# HG changeset patch # User lana # Date 1281668148 25200 # Node ID 67584b95a0f0e5c9d51a8676bb7de8a69907d3ac # Parent 96a57de47def64a59c54b0191efe50878f7cd1aa# Parent 1ce7938efb03224ccc8b3cdd7803eb39e889539c Merge diff -r 96a57de47def -r 67584b95a0f0 .hgtags --- a/.hgtags Wed Aug 11 10:05:56 2010 -0400 +++ b/.hgtags Thu Aug 12 19:55:48 2010 -0700 @@ -77,3 +77,5 @@ 2d6ba7a221915bdf0311acc5641c7f3875cb793e jdk7-b100 2548ac036b8fca3326d058d758e6df8355a42469 jdk7-b101 88db80c8e49cea352c2900f689600dc410761c1f jdk7-b102 +64770970865839b0443066370e7d476ef47e90cd jdk7-b103 +10bc903a228d3a8efdf46fb8c3fcf82a59b88bc5 jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 .hgtags-top-repo --- a/.hgtags-top-repo Wed Aug 11 10:05:56 2010 -0400 +++ b/.hgtags-top-repo Thu Aug 12 19:55:48 2010 -0700 @@ -77,3 +77,5 @@ b218a53ec7d3d42be61d31d6917a6c5c037b6f56 jdk7-b100 4193eaf5f1b82794c6a0fb1a8d11af43d1b1d611 jdk7-b101 a136a51f5113da4dad3853b74a8536ab583ab112 jdk7-b102 +be2aedc4e3b1751c1310f334242ba69e90867f38 jdk7-b103 +f8be576feefce0c6695f188ef97ec16b73ad9cfd jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 corba/.hgtags --- a/corba/.hgtags Wed Aug 11 10:05:56 2010 -0400 +++ b/corba/.hgtags Thu Aug 12 19:55:48 2010 -0700 @@ -77,3 +77,5 @@ a56d734a1e970e1a21a8f4feb13053e9a33674c7 jdk7-b100 86a239832646a74811695428984b6947c0bd6dc8 jdk7-b101 78561a95779090b5106c8d0f1a75360a027ef087 jdk7-b102 +11e7678c3eb169b77d9a9892fe5e3dfa1d1a0d51 jdk7-b103 +9607213481d400ac477183191cc080e1bef6f475 jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 hotspot/.hgtags --- a/hotspot/.hgtags Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/.hgtags Thu Aug 12 19:55:48 2010 -0700 @@ -107,3 +107,6 @@ 6c3a919105b68c15b7db923ec9a00006e9560910 jdk7-b101 ad1977f08c4d69162a0775fe3f9576b9fd521d10 hs19-b03 c5cadf1a07717955cf60dbaec16e35b529fd2cb0 jdk7-b102 +cb4250ef73b21de6c487ea14e2b0b99eed67b4b6 jdk7-b103 +e55900b5c1b865cac17e18abc639c7dc50de7fd8 hs19-b04 +b4acf10eb134fe930802c97e36db65e7ccb544b5 jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Thu Aug 12 19:55:48 2010 -0700 @@ -297,6 +297,7 @@ case JVM_CONSTANT_NameAndType: return "JVM_CONSTANT_NameAndType"; case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle"; case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType"; + case JVM_CONSTANT_InvokeDynamic: return "JVM_CONSTANT_InvokeDynamic"; case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid"; case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass"; case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError"; @@ -355,6 +356,7 @@ case JVM_CONSTANT_NameAndType: case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodType: + case JVM_CONSTANT_InvokeDynamic: visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); break; } @@ -517,6 +519,18 @@ + ", type = " + signatureIndex); break; } + + case JVM_CONSTANT_InvokeDynamic: { + dos.writeByte(cpConstType); + int value = getIntAt(ci); + short bootstrapMethodIndex = (short) extractLowShortFromInt(value); + short nameAndTypeIndex = (short) extractHighShortFromInt(value); + dos.writeShort(bootstrapMethodIndex); + dos.writeShort(nameAndTypeIndex); + if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bootstrapMethodIndex + + ", N&T = " + nameAndTypeIndex); + break; + } default: throw new InternalError("unknown tag: " + cpConstType); } // switch diff -r 96a57de47def -r 67584b95a0f0 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Thu Aug 12 19:55:48 2010 -0700 @@ -42,6 +42,7 @@ public static final int JVM_CONSTANT_NameAndType = 12; public static final int JVM_CONSTANT_MethodHandle = 15; public static final int JVM_CONSTANT_MethodType = 16; + public static final int JVM_CONSTANT_InvokeDynamic = 17; // JVM_CONSTANT_MethodHandle subtypes public static final int JVM_REF_getField = 1; diff -r 96a57de47def -r 67584b95a0f0 hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Thu Aug 12 19:55:48 2010 -0700 @@ -303,12 +303,12 @@ case JVM_CONSTANT_MethodHandle: { dos.writeByte(cpConstType); int value = cpool.getIntAt(ci); - short refIndex = (short) extractHighShortFromInt(value); - byte refKind = (byte) extractLowShortFromInt(value); - dos.writeByte(refKind); - dos.writeShort(refIndex); - if (DEBUG) debugMessage("CP[" + ci + "] = MH index = " + refIndex - + ", kind = " + refKind); + short bootstrapMethodIndex = (short) extractLowShortFromInt(value); + short nameAndTypeIndex = (short) extractHighShortFromInt(value); + dos.writeShort(bootstrapMethodIndex); + dos.writeShort(nameAndTypeIndex); + if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + + bootstrapMethodIndex + ", N&T = " + nameAndTypeIndex); break; } @@ -321,6 +321,15 @@ break; } + case JVM_CONSTANT_InvokeDynamic: { + dos.writeByte(cpConstType); + int value = cpool.getIntAt(ci); + short refIndex = (short) value; + dos.writeShort(refIndex); + if (DEBUG) debugMessage("CP[" + ci + "] = MT index = " + refIndex); + break; + } + default: throw new InternalError("Unknown tag: " + cpConstType); } // switch diff -r 96a57de47def -r 67584b95a0f0 hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Aug 12 19:55:48 2010 -0700 @@ -582,6 +582,11 @@ buf.cell(Integer.toString(cpool.getIntAt(index))); break; + case JVM_CONSTANT_InvokeDynamic: + buf.cell("JVM_CONSTANT_InvokeDynamic"); + buf.cell(genLowHighShort(cpool.getIntAt(index))); + break; + default: throw new InternalError("unknown tag: " + ctag); } diff -r 96a57de47def -r 67584b95a0f0 hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Thu Aug 12 19:55:48 2010 -0700 @@ -40,6 +40,7 @@ private static int JVM_CONSTANT_NameAndType = 12; private static int JVM_CONSTANT_MethodHandle = 15; // JSR 292 private static int JVM_CONSTANT_MethodType = 16; // JSR 292 + private static int JVM_CONSTANT_InvokeDynamic = 17; // JSR 292 private static int JVM_CONSTANT_Invalid = 0; // For bad value initialization private static int JVM_CONSTANT_UnresolvedClass = 100; // Temporary tag until actual use private static int JVM_CONSTANT_ClassIndex = 101; // Temporary tag while constructing constant pool @@ -78,6 +79,7 @@ public boolean isUtf8() { return tag == JVM_CONSTANT_Utf8; } public boolean isMethodHandle() { return tag == JVM_CONSTANT_MethodHandle; } public boolean isMethodType() { return tag == JVM_CONSTANT_MethodType; } + public boolean isInvokeDynamic() { return tag == JVM_CONSTANT_InvokeDynamic; } public boolean isInvalid() { return tag == JVM_CONSTANT_Invalid; } diff -r 96a57de47def -r 67584b95a0f0 hotspot/make/hotspot_version --- a/hotspot/make/hotspot_version Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/make/hotspot_version Thu Aug 12 19:55:48 2010 -0700 @@ -35,7 +35,7 @@ HS_MAJOR_VER=19 HS_MINOR_VER=0 -HS_BUILD_NUMBER=04 +HS_BUILD_NUMBER=05 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -1007,9 +1007,9 @@ __ brx(Assembler::lessEqualUnsigned, false, Assembler::pt, (*NOLp)); __ delayed()->cmp(to_from, byte_count); if (NOLp == NULL) - __ brx(Assembler::greaterEqual, false, Assembler::pt, no_overlap_target); + __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, no_overlap_target); else - __ brx(Assembler::greaterEqual, false, Assembler::pt, (*NOLp)); + __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, (*NOLp)); __ delayed()->nop(); } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/ci/ciEnv.cpp --- a/hotspot/src/share/vm/ci/ciEnv.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/ci/ciEnv.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -728,8 +728,8 @@ } // Get the invoker methodOop from the constant pool. - intptr_t f2_value = cpool->cache()->main_entry_at(index)->f2(); - methodOop signature_invoker = methodOop(f2_value); + oop f1_value = cpool->cache()->main_entry_at(index)->f1(); + methodOop signature_invoker = methodOop(f1_value); assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), "correct result from LinkResolver::resolve_invokedynamic"); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/ci/ciMethod.cpp --- a/hotspot/src/share/vm/ci/ciMethod.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -694,30 +694,21 @@ // ------------------------------------------------------------------ // ciMethod::is_method_handle_invoke // -// Return true if the method is a MethodHandle target. +// Return true if the method is an instance of one of the two +// signature-polymorphic MethodHandle methods, invokeExact or invokeGeneric. bool ciMethod::is_method_handle_invoke() const { - bool flag = (holder()->name() == ciSymbol::java_dyn_MethodHandle() && - methodOopDesc::is_method_handle_invoke_name(name()->sid())); -#ifdef ASSERT - if (is_loaded()) { - bool flag2 = ((flags().as_int() & JVM_MH_INVOKE_BITS) == JVM_MH_INVOKE_BITS); - { - VM_ENTRY_MARK; - bool flag3 = get_methodOop()->is_method_handle_invoke(); - assert(flag2 == flag3, "consistent"); - assert(flag == flag3, "consistent"); - } - } -#endif //ASSERT - return flag; + if (!is_loaded()) return false; + VM_ENTRY_MARK; + return get_methodOop()->is_method_handle_invoke(); } // ------------------------------------------------------------------ // ciMethod::is_method_handle_adapter // // Return true if the method is a generated MethodHandle adapter. +// These are built by MethodHandleCompiler. bool ciMethod::is_method_handle_adapter() const { - check_is_loaded(); + if (!is_loaded()) return false; VM_ENTRY_MARK; return get_methodOop()->is_method_handle_adapter(); } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -122,7 +122,7 @@ if (!EnableMethodHandles || _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { classfile_parse_error( - (!EnableInvokeDynamic ? + (!EnableMethodHandles ? "This JVM does not support constant tag %u in class file %s" : "Class file version does not support constant tag %u in class file %s"), tag, CHECK); @@ -140,6 +140,22 @@ ShouldNotReachHere(); } break; + case JVM_CONSTANT_InvokeDynamic : + { + if (!EnableInvokeDynamic || + _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { + classfile_parse_error( + (!EnableInvokeDynamic ? + "This JVM does not support constant tag %u in class file %s" : + "Class file version does not support constant tag %u in class file %s"), + tag, CHECK); + } + cfs->guarantee_more(5, CHECK); // bsm_index, name_and_type_index, tag/access_flags + u2 bootstrap_method_index = cfs->get_u2_fast(); + u2 name_and_type_index = cfs->get_u2_fast(); + cp->invoke_dynamic_at_put(index, bootstrap_method_index, name_and_type_index); + } + break; case JVM_CONSTANT_Integer : { cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags @@ -414,6 +430,24 @@ ref_index, CHECK_(nullHandle)); } break; + case JVM_CONSTANT_InvokeDynamic : + { + int bootstrap_method_ref_index = cp->invoke_dynamic_bootstrap_method_ref_index_at(index); + int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index); + check_property((bootstrap_method_ref_index == 0 && AllowTransitionalJSR292) + || + (valid_cp_range(bootstrap_method_ref_index, length) && + cp->tag_at(bootstrap_method_ref_index).is_method_handle()), + "Invalid constant pool index %u in class file %s", + bootstrap_method_ref_index, + CHECK_(nullHandle)); + check_property(valid_cp_range(name_and_type_ref_index, length) && + cp->tag_at(name_and_type_ref_index).is_name_and_type(), + "Invalid constant pool index %u in class file %s", + name_and_type_ref_index, + CHECK_(nullHandle)); + break; + } default: fatal(err_msg("bad constant pool tag value %u", cp->tag_at(index).value())); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -2507,6 +2507,10 @@ int caller_bci, TRAPS) { Handle empty; + guarantee(bootstrap_method.not_null() && + java_dyn_MethodHandle::is_instance(bootstrap_method()), + "caller must supply a valid BSM"); + Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty)); MethodHandles::init_MemberName(caller_mname(), caller_method()); @@ -2537,20 +2541,61 @@ return call_site_oop; } -Handle SystemDictionary::find_bootstrap_method(KlassHandle caller, TRAPS) { +Handle SystemDictionary::find_bootstrap_method(methodHandle caller_method, int caller_bci, + int cache_index, TRAPS) { Handle empty; - if (!caller->oop_is_instance()) return empty; - - instanceKlassHandle ik(THREAD, caller()); - - oop boot_method_oop = ik->bootstrap_method(); - if (boot_method_oop != NULL) { + + constantPoolHandle pool; + { + klassOop caller = caller_method->method_holder(); + if (!Klass::cast(caller)->oop_is_instance()) return empty; + pool = constantPoolHandle(THREAD, instanceKlass::cast(caller)->constants()); + } + + int constant_pool_index = pool->cache()->entry_at(cache_index)->constant_pool_index(); + constantTag tag = pool->tag_at(constant_pool_index); + + if (tag.is_invoke_dynamic()) { + // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type] + // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry. + int bsm_index = pool->invoke_dynamic_bootstrap_method_ref_index_at(constant_pool_index); + if (bsm_index != 0) { + int bsm_index_in_cache = pool->cache()->entry_at(cache_index)->bootstrap_method_index_in_cache(); + DEBUG_ONLY(int bsm_index_2 = pool->cache()->entry_at(bsm_index_in_cache)->constant_pool_index()); + assert(bsm_index == bsm_index_2, "BSM constant lifted to cache"); + if (TraceMethodHandles) { + tty->print_cr("resolving bootstrap method for "PTR_FORMAT" at %d at cache[%d]CP[%d]...", + (intptr_t) caller_method(), caller_bci, cache_index, constant_pool_index); + } + oop bsm_oop = pool->resolve_cached_constant_at(bsm_index_in_cache, CHECK_(empty)); + if (TraceMethodHandles) { + tty->print_cr("bootstrap method for "PTR_FORMAT" at %d retrieved as "PTR_FORMAT":", + (intptr_t) caller_method(), caller_bci, (intptr_t) bsm_oop); + } + assert(bsm_oop->is_oop() + && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane"); + return Handle(THREAD, bsm_oop); + } + // else null BSM; fall through + } else if (tag.is_name_and_type()) { + // JSR 292 EDR does not have JVM_CONSTANT_InvokeDynamic + // a bare name&type defaults its BSM to null, so fall through... + } else { + ShouldNotReachHere(); // verifier does not allow this + } + + // Fall through to pick up the per-class bootstrap method. + // This mechanism may go away in the PFD. + assert(AllowTransitionalJSR292, "else the verifier should have stopped us already"); + oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method(); + if (bsm_oop != NULL) { if (TraceMethodHandles) { - tty->print_cr("bootstrap method for "PTR_FORMAT" cached as "PTR_FORMAT":", ik(), boot_method_oop); + tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":", + (intptr_t) caller_method(), (intptr_t) bsm_oop); } - assert(boot_method_oop->is_oop() - && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane"); - return Handle(THREAD, boot_method_oop); + assert(bsm_oop->is_oop() + && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane"); + return Handle(THREAD, bsm_oop); } return empty; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/classfile/systemDictionary.hpp --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -492,7 +492,10 @@ TRAPS); // coordinate with Java about bootstrap methods - static Handle find_bootstrap_method(KlassHandle caller, TRAPS); + static Handle find_bootstrap_method(methodHandle caller_method, + int caller_bci, // N.B. must be an invokedynamic + int cache_index, // must be corresponding main_entry + TRAPS); // Utility for printing loader "name" as part of tracing constraints static const char* loader_name(oop loader) { diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -1913,7 +1913,8 @@ unsigned int types = (opcode == Bytecodes::_invokeinterface ? 1 << JVM_CONSTANT_InterfaceMethodref : opcode == Bytecodes::_invokedynamic - ? 1 << JVM_CONSTANT_NameAndType + ? (1 << JVM_CONSTANT_NameAndType + |1 << JVM_CONSTANT_InvokeDynamic) : 1 << JVM_CONSTANT_Methodref); verify_cp_type(index, cp, types, CHECK_VERIFY(this)); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/code/codeBlob.cpp --- a/hotspot/src/share/vm/code/codeBlob.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/code/codeBlob.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -202,6 +202,11 @@ //---------------------------------------------------------------------------------------------------- // Implementation of AdapterBlob +AdapterBlob::AdapterBlob(int size, CodeBuffer* cb) : + BufferBlob("I2C/C2I adapters", size, cb) { + CodeCache::commit(this); +} + AdapterBlob* AdapterBlob::create(CodeBuffer* cb) { ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock @@ -210,7 +215,6 @@ { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); blob = new (size) AdapterBlob(size, cb); - CodeCache::commit(blob); } // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/code/codeBlob.hpp --- a/hotspot/src/share/vm/code/codeBlob.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/code/codeBlob.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -219,8 +219,7 @@ class AdapterBlob: public BufferBlob { private: - AdapterBlob(int size) : BufferBlob("I2C/C2I adapters", size) {} - AdapterBlob(int size, CodeBuffer* cb) : BufferBlob("I2C/C2I adapters", size, cb) {} + AdapterBlob(int size, CodeBuffer* cb); public: // Creation diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -664,19 +664,14 @@ return; } - // XXX use a global constant instead of 64! - typedef struct OopTaskQueuePadded { - OopTaskQueue work_queue; - char pad[64 - sizeof(OopTaskQueue)]; // prevent false sharing - } OopTaskQueuePadded; - + typedef Padded PaddedOopTaskQueue; for (i = 0; i < num_queues; i++) { - OopTaskQueuePadded *q_padded = new OopTaskQueuePadded(); - if (q_padded == NULL) { + PaddedOopTaskQueue *q = new PaddedOopTaskQueue(); + if (q == NULL) { warning("work_queue allocation failure."); return; } - _task_queues->register_queue(i, &q_padded->work_queue); + _task_queues->register_queue(i, q); } for (i = 0; i < num_queues; i++) { _task_queues->queue(i)->initialize(); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -234,6 +234,11 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); if (_gc_cause != GCCause::_gc_locker && gch->total_full_collections_completed() <= _full_gc_count_before) { + // maybe we should change the condition to test _gc_cause == + // GCCause::_java_lang_system_gc, instead of + // _gc_cause != GCCause::_gc_locker + assert(_gc_cause == GCCause::_java_lang_system_gc, + "the only way to get here if this was a System.gc()-induced GC"); assert(ExplicitGCInvokesConcurrent, "Error"); // Now, wait for witnessing concurrent gc cycle to complete, // but do so in native mode, because we want to lock the diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2010, 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 @@ -271,21 +271,16 @@ if (cas_res == prev_epoch_entry) { // We successfully updated the card num value in the epoch entry count_ptr->_count = 0; // initialize counter for new card num + jbyte* old_card_ptr = card_num_2_ptr(old_card_num); // Even though the region containg the card at old_card_num was not // in the young list when old_card_num was recorded in the epoch // cache it could have been added to the free list and subsequently - // added to the young list in the intervening time. If the evicted - // card is in a young region just return the card_ptr and the evicted - // card will not be cleaned. See CR 6817995. - - jbyte* old_card_ptr = card_num_2_ptr(old_card_num); - if (is_young_card(old_card_ptr)) { - *count = 0; - // We can defer the processing of card_ptr - *defer = true; - return card_ptr; - } + // added to the young list in the intervening time. See CR 6817995. + // We do not deal with this case here - it will be handled in + // HeapRegion::oops_on_card_seq_iterate_careful after it has been + // determined that the region containing the card has been allocated + // to, and it's safe to check the young type of the region. // We do not want to defer processing of card_ptr in this case // (we need to refine old_card_ptr and card_ptr) @@ -301,22 +296,22 @@ jbyte* cached_ptr = add_card_count(card_ptr, &count, defer); assert(cached_ptr != NULL, "bad cached card ptr"); - if (is_young_card(cached_ptr)) { - // The region containing cached_ptr has been freed during a clean up - // pause, reallocated, and tagged as young. - assert(cached_ptr != card_ptr, "shouldn't be"); + // We've just inserted a card pointer into the card count cache + // and got back the card that we just inserted or (evicted) the + // previous contents of that count slot. - // We've just inserted a new old-gen card pointer into the card count - // cache and evicted the previous contents of that count slot. - // The evicted card pointer has been determined to be in a young region - // and so cannot be the newly inserted card pointer (that will be - // in an old region). - // The count for newly inserted card will be set to zero during the - // insertion, so we don't want to defer the cleaning of the newly - // inserted card pointer. - assert(*defer == false, "deferring non-hot card"); - return NULL; - } + // The card we got back could be in a young region. When the + // returned card (if evicted) was originally inserted, we had + // determined that its containing region was not young. However + // it is possible for the region to be freed during a cleanup + // pause, then reallocated and tagged as young which will result + // in the returned card residing in a young region. + // + // We do not deal with this case here - the change from non-young + // to young could be observed at any time - it will be handled in + // HeapRegion::oops_on_card_seq_iterate_careful after it has been + // determined that the region containing the card has been allocated + // to. // The card pointer we obtained from card count cache is not hot // so do not store it in the cache; return it for immediate @@ -325,7 +320,7 @@ return cached_ptr; } - // Otherwise, the pointer we got from the _card_counts is hot. + // Otherwise, the pointer we got from the _card_counts cache is hot. jbyte* res = NULL; MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag); if (_n_hot == _hot_cache_size) { @@ -338,17 +333,8 @@ if (_hot_cache_idx == _hot_cache_size) _hot_cache_idx = 0; _n_hot++; - if (res != NULL) { - // Even though the region containg res was not in the young list - // when it was recorded in the hot cache it could have been added - // to the free list and subsequently added to the young list in - // the intervening time. If res is in a young region, return NULL - // so that res is not cleaned. See CR 6817995. - - if (is_young_card(res)) { - res = NULL; - } - } + // The card obtained from the hot card cache could be in a young + // region. See above on how this can happen. return res; } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -266,6 +266,12 @@ _cm->clearNextBitmap(); _sts.leave(); } + + // Update the number of full collections that have been + // completed. This will also notify the FullGCCount_lock in case a + // Java thread is waiting for a full GC to happen (e.g., it + // called System.gc() with +ExplicitGCInvokesConcurrent). + g1->increment_full_collections_completed(true /* outer */); } assert(_should_terminate, "just checking"); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -638,6 +638,11 @@ // Now retry the allocation. if (_cur_alloc_region != NULL) { + if (allocated_young_region != NULL) { + // We need to ensure that the store to top does not + // float above the setting of the young type. + OrderAccess::storestore(); + } res = _cur_alloc_region->allocate(word_size); } } @@ -809,7 +814,8 @@ } }; -void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs, +void G1CollectedHeap::do_collection(bool explicit_gc, + bool clear_all_soft_refs, size_t word_size) { if (GC_locker::check_active_before_gc()) { return; // GC is disabled (e.g. JNI GetXXXCritical operation) @@ -821,10 +827,6 @@ Universe::print_heap_before_gc(); } - if (full && DisableExplicitGC) { - return; - } - assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread"); @@ -837,9 +839,11 @@ IsGCActiveMark x; // Timing + bool system_gc = (gc_cause() == GCCause::_java_lang_system_gc); + assert(!system_gc || explicit_gc, "invariant"); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); - TraceTime t(full ? "Full GC (System.gc())" : "Full GC", + TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty); TraceMemoryManagerStats tms(true /* fullGC */); @@ -944,7 +948,7 @@ heap_region_iterate(&rs_clear); // Resize the heap if necessary. - resize_if_necessary_after_full_collection(full ? 0 : word_size); + resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); if (_cg1r->use_cache()) { _cg1r->clear_and_record_card_counts(); @@ -1009,13 +1013,18 @@ "young list should be empty at this point"); } + // Update the number of full collections that have been completed. + increment_full_collections_completed(false /* outer */); + if (PrintHeapAtGC) { Universe::print_heap_after_gc(); } } void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { - do_collection(true, clear_all_soft_refs, 0); + do_collection(true, /* explicit_gc */ + clear_all_soft_refs, + 0 /* word_size */); } // This code is mostly copied from TenuredGeneration. @@ -1331,6 +1340,7 @@ _young_list(new YoungList(this)), _gc_time_stamp(0), _surviving_young_words(NULL), + _full_collections_completed(0), _in_cset_fast_test(NULL), _in_cset_fast_test_base(NULL), _dirty_cards_region_list(NULL) { @@ -1689,6 +1699,51 @@ return car->free(); } +bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { + return + ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || + (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); +} + +void G1CollectedHeap::increment_full_collections_completed(bool outer) { + MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); + + // We have already incremented _total_full_collections at the start + // of the GC, so total_full_collections() represents how many full + // collections have been started. + unsigned int full_collections_started = total_full_collections(); + + // Given that this method is called at the end of a Full GC or of a + // concurrent cycle, and those can be nested (i.e., a Full GC can + // interrupt a concurrent cycle), the number of full collections + // completed should be either one (in the case where there was no + // nesting) or two (when a Full GC interrupted a concurrent cycle) + // behind the number of full collections started. + + // This is the case for the inner caller, i.e. a Full GC. + assert(outer || + (full_collections_started == _full_collections_completed + 1) || + (full_collections_started == _full_collections_completed + 2), + err_msg("for inner caller: full_collections_started = %u " + "is inconsistent with _full_collections_completed = %u", + full_collections_started, _full_collections_completed)); + + // This is the case for the outer caller, i.e. the concurrent cycle. + assert(!outer || + (full_collections_started == _full_collections_completed + 1), + err_msg("for outer caller: full_collections_started = %u " + "is inconsistent with _full_collections_completed = %u", + full_collections_started, _full_collections_completed)); + + _full_collections_completed += 1; + + // This notify_all() will ensure that a thread that called + // System.gc() with (with ExplicitGCInvokesConcurrent set or not) + // and it's waiting for a full GC to finish will be woken up. It is + // waiting in VM_G1IncCollectionPause::doit_epilogue(). + FullGCCount_lock->notify_all(); +} + void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { assert(Thread::current()->is_VM_thread(), "Precondition#1"); assert(Heap_lock->is_locked(), "Precondition#2"); @@ -1709,25 +1764,41 @@ // The caller doesn't have the Heap_lock assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); - int gc_count_before; + unsigned int gc_count_before; + unsigned int full_gc_count_before; { MutexLocker ml(Heap_lock); // Read the GC count while holding the Heap_lock gc_count_before = SharedHeap::heap()->total_collections(); + full_gc_count_before = SharedHeap::heap()->total_full_collections(); // Don't want to do a GC until cleanup is completed. wait_for_cleanup_complete(); - } // We give up heap lock; VMThread::execute gets it back below - switch (cause) { - case GCCause::_scavenge_alot: { - // Do an incremental pause, which might sometimes be abandoned. - VM_G1IncCollectionPause op(gc_count_before, cause); + + // We give up heap lock; VMThread::execute gets it back below + } + + if (should_do_concurrent_full_gc(cause)) { + // Schedule an initial-mark evacuation pause that will start a + // concurrent cycle. + VM_G1IncCollectionPause op(gc_count_before, + true, /* should_initiate_conc_mark */ + g1_policy()->max_pause_time_ms(), + cause); + VMThread::execute(&op); + } else { + if (cause == GCCause::_gc_locker + DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { + + // Schedule a standard evacuation pause. + VM_G1IncCollectionPause op(gc_count_before, + false, /* should_initiate_conc_mark */ + g1_policy()->max_pause_time_ms(), + cause); VMThread::execute(&op); - break; - } - default: { - // In all other cases, we currently do a full gc. - VM_G1CollectFull op(gc_count_before, cause); + } else { + // Schedule a Full GC. + VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause); VMThread::execute(&op); } } @@ -1989,6 +2060,11 @@ void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, HeapRegionClosure *cl) { + if (r == NULL) { + // The CSet is empty so there's nothing to do. + return; + } + assert(r->in_collection_set(), "Start region must be a member of the collection set."); HeapRegion* cur = r; @@ -2481,11 +2557,13 @@ } void G1CollectedHeap::do_collection_pause() { + assert(Heap_lock->owned_by_self(), "we assume we'reholding the Heap_lock"); + // Read the GC count while holding the Heap_lock // we need to do this _before_ wait_for_cleanup_complete(), to // ensure that we do not give up the heap lock and potentially // pick up the wrong count - int gc_count_before = SharedHeap::heap()->total_collections(); + unsigned int gc_count_before = SharedHeap::heap()->total_collections(); // Don't want to do a GC pause while cleanup is being completed! wait_for_cleanup_complete(); @@ -2493,7 +2571,10 @@ g1_policy()->record_stop_world_start(); { MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back - VM_G1IncCollectionPause op(gc_count_before); + VM_G1IncCollectionPause op(gc_count_before, + false, /* should_initiate_conc_mark */ + g1_policy()->max_pause_time_ms(), + GCCause::_g1_inc_collection_pause); VMThread::execute(&op); } } @@ -2612,7 +2693,7 @@ }; void -G1CollectedHeap::do_collection_pause_at_safepoint() { +G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { if (GC_locker::check_active_before_gc()) { return; // GC is disabled (e.g. JNI GetXXXCritical operation) } @@ -2637,8 +2718,12 @@ else strcat(verbose_str, "(partial)"); } - if (g1_policy()->during_initial_mark_pause()) + if (g1_policy()->during_initial_mark_pause()) { strcat(verbose_str, " (initial-mark)"); + // We are about to start a marking cycle, so we increment the + // full collection counter. + increment_total_full_collections(); + } // if PrintGCDetails is on, we'll print long statistics information // in the collector policy code, so let's not print this as the output @@ -2661,7 +2746,6 @@ "young list should be well formed"); } - bool abandoned = false; { // Call to jvmpi::post_class_unload_events must occur outside of active GC IsGCActiveMark x; @@ -2743,7 +2827,7 @@ // Now choose the CS. We may abandon a pause if we find no // region that will fit in the MMU pause. - bool abandoned = g1_policy()->choose_collection_set(); + bool abandoned = g1_policy()->choose_collection_set(target_pause_time_ms); // Nothing to do if we were unable to choose a collection set. if (!abandoned) { diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -277,6 +277,18 @@ void update_surviving_young_words(size_t* surv_young_words); void cleanup_surviving_young_words(); + // It decides whether an explicit GC should start a concurrent cycle + // instead of doing a STW GC. Currently, a concurrent cycle is + // explicitly started if: + // (a) cause == _gc_locker and +GCLockerInvokesConcurrent, or + // (b) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent. + bool should_do_concurrent_full_gc(GCCause::Cause cause); + + // Keeps track of how many "full collections" (i.e., Full GCs or + // concurrent cycles) we have completed. The number of them we have + // started is maintained in _total_full_collections in CollectedHeap. + volatile unsigned int _full_collections_completed; + protected: // Returns "true" iff none of the gc alloc regions have any allocations @@ -356,13 +368,14 @@ // GC pause. void retire_alloc_region(HeapRegion* alloc_region, bool par); - // Helper function for two callbacks below. - // "full", if true, indicates that the GC is for a System.gc() request, - // and should collect the entire heap. If "clear_all_soft_refs" is true, - // all soft references are cleared during the GC. If "full" is false, - // "word_size" describes the allocation that the GC should - // attempt (at least) to satisfy. - void do_collection(bool full, bool clear_all_soft_refs, + // - if explicit_gc is true, the GC is for a System.gc() or a heap + // inspection request and should collect the entire heap + // - if clear_all_soft_refs is true, all soft references are cleared + // during the GC + // - if explicit_gc is false, word_size describes the allocation that + // the GC should attempt (at least) to satisfy + void do_collection(bool explicit_gc, + bool clear_all_soft_refs, size_t word_size); // Callback from VM_G1CollectFull operation. @@ -431,6 +444,26 @@ _in_cset_fast_test_length * sizeof(bool)); } + // This is called at the end of either a concurrent cycle or a Full + // GC to update the number of full collections completed. Those two + // can happen in a nested fashion, i.e., we start a concurrent + // cycle, a Full GC happens half-way through it which ends first, + // and then the cycle notices that a Full GC happened and ends + // too. The outer parameter is a boolean to help us do a bit tighter + // consistency checking in the method. If outer is false, the caller + // is the inner caller in the nesting (i.e., the Full GC). If outer + // is true, the caller is the outer caller in this nesting (i.e., + // the concurrent cycle). Further nesting is not currently + // supported. The end of the this call also notifies the + // FullGCCount_lock in case a Java thread is waiting for a full GC + // to happen (e.g., it called System.gc() with + // +ExplicitGCInvokesConcurrent). + void increment_full_collections_completed(bool outer); + + unsigned int full_collections_completed() { + return _full_collections_completed; + } + protected: // Shrink the garbage-first heap by at most the given size (in bytes!). @@ -444,7 +477,7 @@ // The guts of the incremental collection pause, executed by the vm // thread. - virtual void do_collection_pause_at_safepoint(); + virtual void do_collection_pause_at_safepoint(double target_pause_time_ms); // Actually do the work of evacuating the collection set. virtual void evacuate_collection_set(); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -154,7 +154,6 @@ _known_garbage_bytes(0), _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)), - _target_pause_time_ms(-1.0), _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)), @@ -1635,8 +1634,6 @@ double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); // - - _target_pause_time_ms = -1.0; } // @@ -2366,7 +2363,6 @@ if (reached_target_length) { assert( young_list_length > 0 && _g1->young_list()->length() > 0, "invariant" ); - _target_pause_time_ms = max_pause_time_ms; return true; } } else { @@ -2398,6 +2394,17 @@ } #endif +bool +G1CollectorPolicy::force_initial_mark_if_outside_cycle() { + bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle(); + if (!during_cycle) { + set_initiate_conc_mark_if_possible(); + return true; + } else { + return false; + } +} + void G1CollectorPolicy::decide_on_conc_mark_initiation() { // We are about to decide on whether this pause will be an @@ -2864,7 +2871,8 @@ #endif // !PRODUCT bool -G1CollectorPolicy_BestRegionsFirst::choose_collection_set() { +G1CollectorPolicy_BestRegionsFirst::choose_collection_set( + double target_pause_time_ms) { // Set this here - in case we're not doing young collections. double non_young_start_time_sec = os::elapsedTime(); @@ -2877,26 +2885,19 @@ start_recording_regions(); - guarantee(_target_pause_time_ms > -1.0 - NOT_PRODUCT(|| Universe::heap()->gc_cause() == GCCause::_scavenge_alot), - "_target_pause_time_ms should have been set!"); -#ifndef PRODUCT - if (_target_pause_time_ms <= -1.0) { - assert(ScavengeALot && Universe::heap()->gc_cause() == GCCause::_scavenge_alot, "Error"); - _target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; - } -#endif - assert(_collection_set == NULL, "Precondition"); + guarantee(target_pause_time_ms > 0.0, + err_msg("target_pause_time_ms = %1.6lf should be positive", + target_pause_time_ms)); + guarantee(_collection_set == NULL, "Precondition"); double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); double predicted_pause_time_ms = base_time_ms; - double target_time_ms = _target_pause_time_ms; - double time_remaining_ms = target_time_ms - base_time_ms; + double time_remaining_ms = target_pause_time_ms - base_time_ms; // the 10% and 50% values are arbitrary... - if (time_remaining_ms < 0.10*target_time_ms) { - time_remaining_ms = 0.50 * target_time_ms; + if (time_remaining_ms < 0.10 * target_pause_time_ms) { + time_remaining_ms = 0.50 * target_pause_time_ms; _within_target = false; } else { _within_target = true; @@ -3059,7 +3060,18 @@ _recorded_non_young_cset_choice_time_ms = (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; - return abandon_collection; + // Here we are supposed to return whether the pause should be + // abandoned or not (i.e., whether the collection set is empty or + // not). However, this introduces a subtle issue when a pause is + // initiated explicitly with System.gc() and + // +ExplicitGCInvokesConcurrent (see Comment #2 in CR 6944166), it's + // supposed to start a marking cycle, and it's abandoned. So, by + // returning false here we are telling the caller never to consider + // a pause to be abandoned. We'll actually remove all the code + // associated with abandoned pauses as part of CR 6963209, but we are + // just disabling them this way for the moment to avoid increasing + // further the amount of changes for CR 6944166. + return false; } void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() { diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -199,8 +199,6 @@ size_t _young_cset_length; bool _last_young_gc_full; - double _target_pause_time_ms; - unsigned _full_young_pause_num; unsigned _partial_young_pause_num; @@ -526,6 +524,10 @@ return _mmu_tracker; } + double max_pause_time_ms() { + return _mmu_tracker->max_gc_time() * 1000.0; + } + double predict_init_time_ms() { return get_new_prediction(_concurrent_mark_init_times_ms); } @@ -1008,7 +1010,7 @@ // Choose a new collection set. Marks the chosen regions as being // "in_collection_set", and links them together. The head and number of // the collection set are available via access methods. - virtual bool choose_collection_set() = 0; + virtual bool choose_collection_set(double target_pause_time_ms) = 0; // The head of the list (via "next_in_collection_set()") representing the // current collection set. @@ -1077,6 +1079,12 @@ void set_during_initial_mark_pause() { _during_initial_mark_pause = true; } void clear_during_initial_mark_pause(){ _during_initial_mark_pause = false; } + // This sets the initiate_conc_mark_if_possible() flag to start a + // new cycle, as long as we are not already in one. It's best if it + // is called during a safepoint when the test whether a cycle is in + // progress or not is stable. + bool force_initial_mark_if_outside_cycle(); + // This is called at the very beginning of an evacuation pause (it // has to be the first thing that the pause does). If // initiate_conc_mark_if_possible() is true, and the concurrent @@ -1259,7 +1267,7 @@ // If the estimated is less then desirable, resize if possible. void expand_if_possible(size_t numRegions); - virtual bool choose_collection_set(); + virtual bool choose_collection_set(double target_pause_time_ms); virtual void record_collection_pause_start(double start_time_sec, size_t start_used); virtual void record_concurrent_mark_cleanup_end(size_t freed_bytes, diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2010, 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 @@ -676,9 +676,27 @@ // We must complete this write before we do any of the reads below. OrderAccess::storeload(); // And process it, being careful of unallocated portions of TLAB's. + + // The region for the current card may be a young region. The + // current card may have been a card that was evicted from the + // card cache. When the card was inserted into the cache, we had + // determined that its region was non-young. While in the cache, + // the region may have been freed during a cleanup pause, reallocated + // and tagged as young. + // + // We wish to filter out cards for such a region but the current + // thread, if we're running conucrrently, may "see" the young type + // change at any time (so an earlier "is_young" check may pass or + // fail arbitrarily). We tell the iteration code to perform this + // filtering when it has been determined that there has been an actual + // allocation in this region and making it safe to check the young type. + bool filter_young = true; + HeapWord* stop_point = r->oops_on_card_seq_iterate_careful(dirtyRegion, - &filter_then_update_rs_oop_cl); + &filter_then_update_rs_oop_cl, + filter_young); + // If stop_point is non-null, then we encountered an unallocated region // (perhaps the unfilled portion of a TLAB.) For now, we'll dirty the // card and re-enqueue: if we put off the card until a GC pause, then the @@ -789,8 +807,14 @@ if (r == NULL) { assert(_g1->is_in_permanent(start), "Or else where?"); } else { - guarantee(!r->is_young(), "It was evicted in the current minor cycle."); - // Process card pointer we get back from the hot card cache + // Checking whether the region we got back from the cache + // is young here is inappropriate. The region could have been + // freed, reallocated and tagged as young while in the cache. + // Hence we could see its young type change at any time. + // + // Process card pointer we get back from the hot card cache. This + // will check whether the region containing the card is young + // _after_ checking that the region has been allocated from. concurrentRefineOneCard_impl(res, worker_i); } } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -658,7 +658,8 @@ HeapWord* HeapRegion:: oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl) { + FilterOutOfRegionClosure* cl, + bool filter_young) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); // If we're within a stop-world GC, then we might look at a card in a @@ -672,6 +673,16 @@ if (mr.is_empty()) return NULL; // Otherwise, find the obj that extends onto mr.start(). + // The intersection of the incoming mr (for the card) and the + // allocated part of the region is non-empty. This implies that + // we have actually allocated into this region. The code in + // G1CollectedHeap.cpp that allocates a new region sets the + // is_young tag on the region before allocating. Thus we + // safely know if this region is young. + if (is_young() && filter_young) { + return NULL; + } + // We used to use "block_start_careful" here. But we're actually happy // to update the BOT while we do this... HeapWord* cur = block_start(mr.start()); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -252,7 +252,7 @@ // survivor }; - YoungType _young_type; + volatile YoungType _young_type; int _young_index_in_cset; SurvRateGroup* _surv_rate_group; int _age_index; @@ -726,9 +726,12 @@ HeapWord* object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl); + // In this version - if filter_young is true and the region + // is a young region then we skip the iteration. HeapWord* oops_on_card_seq_iterate_careful(MemRegion mr, - FilterOutOfRegionClosure* cl); + FilterOutOfRegionClosure* cl, + bool filter_young); // The region "mr" is entirely in "this", and starts and ends at block // boundaries. The caller declares that all the contained blocks are diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -42,8 +42,65 @@ void VM_G1IncCollectionPause::doit() { JvmtiGCForAllocationMarker jgcm; G1CollectedHeap* g1h = G1CollectedHeap::heap(); + assert(!_should_initiate_conc_mark || + ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || + (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)), + "only a GC locker or a System.gc() induced GC should start a cycle"); + GCCauseSetter x(g1h, _gc_cause); - g1h->do_collection_pause_at_safepoint(); + if (_should_initiate_conc_mark) { + // It's safer to read full_collections_completed() here, given + // that noone else will be updating it concurrently. Since we'll + // only need it if we're initiating a marking cycle, no point in + // setting it earlier. + _full_collections_completed_before = g1h->full_collections_completed(); + + // At this point we are supposed to start a concurrent cycle. We + // will do so if one is not already in progress. + bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle(); + } + g1h->do_collection_pause_at_safepoint(_target_pause_time_ms); +} + +void VM_G1IncCollectionPause::doit_epilogue() { + VM_GC_Operation::doit_epilogue(); + + // If the pause was initiated by a System.gc() and + // +ExplicitGCInvokesConcurrent, we have to wait here for the cycle + // that just started (or maybe one that was already in progress) to + // finish. + if (_gc_cause == GCCause::_java_lang_system_gc && + _should_initiate_conc_mark) { + assert(ExplicitGCInvokesConcurrent, + "the only way to be here is if ExplicitGCInvokesConcurrent is set"); + + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + + // In the doit() method we saved g1h->full_collections_completed() + // in the _full_collections_completed_before field. We have to + // wait until we observe that g1h->full_collections_completed() + // has increased by at least one. This can happen if a) we started + // a cycle and it completes, b) a cycle already in progress + // completes, or c) a Full GC happens. + + // If the condition has already been reached, there's no point in + // actually taking the lock and doing the wait. + if (g1h->full_collections_completed() <= + _full_collections_completed_before) { + // The following is largely copied from CMS + + Thread* thr = Thread::current(); + assert(thr->is_Java_thread(), "invariant"); + JavaThread* jt = (JavaThread*)thr; + ThreadToNativeFromVM native(jt); + + MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); + while (g1h->full_collections_completed() <= + _full_collections_completed_before) { + FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag); + } + } + } } void VM_CGC_Operation::doit() { diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -31,13 +31,12 @@ // - VM_G1PopRegionCollectionPause class VM_G1CollectFull: public VM_GC_Operation { - private: public: - VM_G1CollectFull(int gc_count_before, - GCCause::Cause gc_cause) - : VM_GC_Operation(gc_count_before) - { - _gc_cause = gc_cause; + VM_G1CollectFull(unsigned int gc_count_before, + unsigned int full_gc_count_before, + GCCause::Cause cause) + : VM_GC_Operation(gc_count_before, full_gc_count_before) { + _gc_cause = cause; } ~VM_G1CollectFull() {} virtual VMOp_Type type() const { return VMOp_G1CollectFull; } @@ -67,12 +66,28 @@ }; class VM_G1IncCollectionPause: public VM_GC_Operation { - public: - VM_G1IncCollectionPause(int gc_count_before, - GCCause::Cause gc_cause = GCCause::_g1_inc_collection_pause) : - VM_GC_Operation(gc_count_before) { _gc_cause = gc_cause; } +private: + bool _should_initiate_conc_mark; + double _target_pause_time_ms; + unsigned int _full_collections_completed_before; +public: + VM_G1IncCollectionPause(unsigned int gc_count_before, + bool should_initiate_conc_mark, + double target_pause_time_ms, + GCCause::Cause cause) + : VM_GC_Operation(gc_count_before), + _full_collections_completed_before(0), + _should_initiate_conc_mark(should_initiate_conc_mark), + _target_pause_time_ms(target_pause_time_ms) { + guarantee(target_pause_time_ms > 0.0, + err_msg("target_pause_time_ms = %1.6lf should be positive", + target_pause_time_ms)); + + _gc_cause = cause; + } virtual VMOp_Type type() const { return VMOp_G1IncCollectionPause; } virtual void doit(); + virtual void doit_epilogue(); virtual const char* name() const { return "garbage-first incremental collection pause"; } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/includeDB_gc_g1 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1 Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_g1 Thu Aug 12 19:55:48 2010 -0700 @@ -367,4 +367,6 @@ vm_operations_g1.cpp vm_operations_g1.hpp vm_operations_g1.cpp g1CollectedHeap.inline.hpp +vm_operations_g1.cpp g1CollectorPolicy.hpp +vm_operations_g1.cpp interfaceSupport.hpp vm_operations_g1.cpp isGCActiveMark.hpp diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -539,10 +539,9 @@ guarantee(_task_queues != NULL, "task_queues allocation failure."); for (uint i1 = 0; i1 < ParallelGCThreads; i1++) { - ObjToScanQueuePadded *q_padded = new ObjToScanQueuePadded(); - guarantee(q_padded != NULL, "work_queue Allocation failure."); - - _task_queues->register_queue(i1, &q_padded->work_queue); + ObjToScanQueue *q = new ObjToScanQueue(); + guarantee(q != NULL, "work_queue Allocation failure."); + _task_queues->register_queue(i1, q); } for (uint i2 = 0; i2 < ParallelGCThreads; i2++) diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2010, 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 @@ -33,8 +33,8 @@ // but they must be here to allow ParScanClosure::do_oop_work to be defined // in genOopClosures.inline.hpp. -typedef OopTaskQueue ObjToScanQueue; -typedef OopTaskQueueSet ObjToScanQueueSet; +typedef Padded ObjToScanQueue; +typedef GenericTaskQueueSet ObjToScanQueueSet; // Enable this to get push/pop/steal stats. const int PAR_STATS_ENABLED = 0; @@ -304,12 +304,6 @@ friend class ParEvacuateFollowersClosure; private: - // XXX use a global constant instead of 64! - struct ObjToScanQueuePadded { - ObjToScanQueue work_queue; - char pad[64 - sizeof(ObjToScanQueue)]; // prevent false sharing - }; - // The per-worker-thread work queues ObjToScanQueueSet* _task_queues; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp --- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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 @@ -26,7 +26,8 @@ class ParScanThreadState; class ParNewGeneration; -typedef OopTaskQueueSet ObjToScanQueueSet; +typedef Padded ObjToScanQueue; +typedef GenericTaskQueueSet ObjToScanQueueSet; class ParallelTaskTerminator; class ParScanClosure: public OopsInGenClosure { diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -90,10 +90,7 @@ } void PSPromotionManager::post_scavenge() { -#if PS_PM_STATS - print_stats(); -#endif // PS_PM_STATS - + TASKQUEUE_STATS_ONLY(if (PrintGCDetails && ParallelGCVerbose) print_stats()); for (uint i = 0; i < ParallelGCThreads + 1; i++) { PSPromotionManager* manager = manager_array(i); if (UseDepthFirstScavengeOrder) { @@ -105,37 +102,58 @@ } } -#if PS_PM_STATS - +#if TASKQUEUE_STATS void -PSPromotionManager::print_stats(uint i) { - tty->print_cr("---- GC Worker %2d Stats", i); - tty->print_cr(" total pushes %8d", _total_pushes); - tty->print_cr(" masked pushes %8d", _masked_pushes); - tty->print_cr(" overflow pushes %8d", _overflow_pushes); - tty->print_cr(" max overflow length %8d", _max_overflow_length); - tty->print_cr(""); - tty->print_cr(" arrays chunked %8d", _arrays_chunked); - tty->print_cr(" array chunks processed %8d", _array_chunks_processed); - tty->print_cr(""); - tty->print_cr(" total steals %8d", _total_steals); - tty->print_cr(" masked steals %8d", _masked_steals); - tty->print_cr(""); +PSPromotionManager::print_taskqueue_stats(uint i) const { + const TaskQueueStats& stats = depth_first() ? + _claimed_stack_depth.stats : _claimed_stack_breadth.stats; + tty->print("%3u ", i); + stats.print(); + tty->cr(); } void +PSPromotionManager::print_local_stats(uint i) const { + #define FMT " " SIZE_FORMAT_W(10) + tty->print_cr("%3u" FMT FMT FMT FMT, i, _masked_pushes, _masked_steals, + _arrays_chunked, _array_chunks_processed); + #undef FMT +} + +static const char* const pm_stats_hdr[] = { + " --------masked------- arrays array", + "thr push steal chunked chunks", + "--- ---------- ---------- ---------- ----------" +}; + +void PSPromotionManager::print_stats() { - tty->print_cr("== GC Tasks Stats (%s), GC %3d", - (UseDepthFirstScavengeOrder) ? "Depth-First" : "Breadth-First", + const bool df = UseDepthFirstScavengeOrder; + tty->print_cr("== GC Task Stats (%s-First), GC %3d", df ? "Depth" : "Breadth", Universe::heap()->total_collections()); - for (uint i = 0; i < ParallelGCThreads+1; ++i) { - PSPromotionManager* manager = manager_array(i); - manager->print_stats(i); + tty->print("thr "); TaskQueueStats::print_header(1); tty->cr(); + tty->print("--- "); TaskQueueStats::print_header(2); tty->cr(); + for (uint i = 0; i < ParallelGCThreads + 1; ++i) { + manager_array(i)->print_taskqueue_stats(i); + } + + const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); + for (uint i = 0; i < hlines; ++i) tty->print_cr(pm_stats_hdr[i]); + for (uint i = 0; i < ParallelGCThreads + 1; ++i) { + manager_array(i)->print_local_stats(i); } } -#endif // PS_PM_STATS +void +PSPromotionManager::reset_stats() { + TaskQueueStats& stats = depth_first() ? + claimed_stack_depth()->stats : claimed_stack_breadth()->stats; + stats.reset(); + _masked_pushes = _masked_steals = 0; + _arrays_chunked = _array_chunks_processed = 0; +} +#endif // TASKQUEUE_STATS PSPromotionManager::PSPromotionManager() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); @@ -189,16 +207,7 @@ _prefetch_queue.clear(); -#if PS_PM_STATS - _total_pushes = 0; - _masked_pushes = 0; - _overflow_pushes = 0; - _max_overflow_length = 0; - _arrays_chunked = 0; - _array_chunks_processed = 0; - _total_steals = 0; - _masked_steals = 0; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(reset_stats()); } @@ -423,14 +432,9 @@ new_obj->is_objArray() && PSChunkLargeArrays) { // we'll chunk it -#if PS_PM_STATS - ++_arrays_chunked; -#endif // PS_PM_STATS oop* const masked_o = mask_chunked_array_oop(o); push_depth(masked_o); -#if PS_PM_STATS - ++_masked_pushes; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(++_arrays_chunked; ++_masked_pushes); } else { // we'll just push its contents new_obj->push_contents(this); @@ -494,9 +498,7 @@ assert(old->is_objArray(), "invariant"); assert(old->is_forwarded(), "invariant"); -#if PS_PM_STATS - ++_array_chunks_processed; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(++_array_chunks_processed); oop const obj = old->forwardee(); @@ -508,9 +510,7 @@ assert(start > 0, "invariant"); arrayOop(old)->set_length(start); push_depth(mask_chunked_array_oop(old)); -#if PS_PM_STATS - ++_masked_pushes; -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(++_masked_pushes); } else { // this is the final chunk for this array start = 0; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -42,8 +42,6 @@ class PSOldGen; class ParCompactionManager; -#define PS_PM_STATS 0 - class PSPromotionManager : public CHeapObj { friend class PSScavenge; friend class PSRefProcTaskExecutor; @@ -54,22 +52,18 @@ static PSOldGen* _old_gen; static MutableSpace* _young_space; -#if PS_PM_STATS - uint _total_pushes; - uint _masked_pushes; - - uint _overflow_pushes; - uint _max_overflow_length; +#if TASKQUEUE_STATS + size_t _masked_pushes; + size_t _masked_steals; + size_t _arrays_chunked; + size_t _array_chunks_processed; - uint _arrays_chunked; - uint _array_chunks_processed; + void print_taskqueue_stats(uint i) const; + void print_local_stats(uint i) const; + static void print_stats(); - uint _total_steals; - uint _masked_steals; - - void print_stats(uint i); - static void print_stats(); -#endif // PS_PM_STATS + void reset_stats(); +#endif // TASKQUEUE_STATS PSYoungPromotionLAB _young_lab; PSOldPromotionLAB _old_lab; @@ -143,42 +137,12 @@ template void push_depth(T* p) { assert(depth_first(), "pre-condition"); - -#if PS_PM_STATS - ++_total_pushes; - int stack_length = claimed_stack_depth()->overflow_stack()->length(); -#endif // PS_PM_STATS - claimed_stack_depth()->push(p); - -#if PS_PM_STATS - if (claimed_stack_depth()->overflow_stack()->length() != stack_length) { - ++_overflow_pushes; - if ((uint)stack_length + 1 > _max_overflow_length) { - _max_overflow_length = (uint)stack_length + 1; - } - } -#endif // PS_PM_STATS } void push_breadth(oop o) { assert(!depth_first(), "pre-condition"); - -#if PS_PM_STATS - ++_total_pushes; - int stack_length = claimed_stack_breadth()->overflow_stack()->length(); -#endif // PS_PM_STATS - claimed_stack_breadth()->push(o); - -#if PS_PM_STATS - if (claimed_stack_breadth()->overflow_stack()->length() != stack_length) { - ++_overflow_pushes; - if ((uint)stack_length + 1 > _max_overflow_length) { - _max_overflow_length = (uint)stack_length + 1; - } - } -#endif // PS_PM_STATS } protected: @@ -256,12 +220,5 @@ template inline void claim_or_forward_depth(T* p); template inline void claim_or_forward_breadth(T* p); -#if PS_PM_STATS - void increment_steals(oop* p = NULL) { - _total_steals += 1; - if (p != NULL && is_oop_masked(p)) { - _masked_steals += 1; - } - } -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(inline void record_steal(StarTask& p);) }; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, 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 @@ -124,3 +124,11 @@ } } } + +#if TASKQUEUE_STATS +void PSPromotionManager::record_steal(StarTask& p) { + if (is_oop_masked(p)) { + ++_masked_steals; + } +} +#endif // TASKQUEUE_STATS diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, 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 @@ -148,9 +148,7 @@ while(true) { StarTask p; if (PSPromotionManager::steal_depth(which, &random_seed, p)) { -#if PS_PM_STATS - pm->increment_steals(p); -#endif // PS_PM_STATS + TASKQUEUE_STATS_ONLY(pm->record_steal(p)); pm->process_popped_location_depth(p); pm->drain_stacks_depth(true); } else { @@ -163,9 +161,6 @@ while(true) { oop obj; if (PSPromotionManager::steal_breadth(which, &random_seed, obj)) { -#if PS_PM_STATS - pm->increment_steals(); -#endif // PS_PM_STATS obj->copy_contents(pm); pm->drain_stacks_breadth(true); } else { diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp --- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -86,9 +86,7 @@ _gc_locked = false; - if (full) { - _full_gc_count_before = full_gc_count_before; - } + _full_gc_count_before = full_gc_count_before; // In ParallelScavengeHeap::mem_allocate() collections can be // executed within a loop and _all_soft_refs_clear can be set // true after they have been cleared by a collection and another diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/gc_interface/gcCause.cpp --- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -78,6 +78,9 @@ case _old_generation_too_full_to_scavenge: return "Old Generation Too Full To Scavenge"; + case _g1_inc_collection_pause: + return "G1 Evacuation Pause"; + case _last_ditch_collection: return "Last ditch collection"; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/interpreter/bytecodeTracer.cpp --- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -328,24 +328,35 @@ constantPoolOop constants = method()->constants(); constantTag tag = constants->tag_at(i); - int nt_index = -1; + bool has_klass = true; switch (tag.value()) { case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Methodref: case JVM_CONSTANT_Fieldref: + break; case JVM_CONSTANT_NameAndType: + case JVM_CONSTANT_InvokeDynamic: + has_klass = false; break; default: st->print_cr(" bad tag=%d at %d", tag.value(), i); return; } - symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i)); symbolOop name = constants->uncached_name_ref_at(i); symbolOop signature = constants->uncached_signature_ref_at(i); const char* sep = (tag.is_field() ? "/" : ""); - st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string()); + if (has_klass) { + symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i)); + st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string()); + } else { + if (tag.is_invoke_dynamic()) { + int bsm = constants->invoke_dynamic_bootstrap_method_ref_index_at(i); + st->print(" bsm=%d", bsm); + } + st->print_cr(" %d <%s%s%s>", i, name->as_C_string(), sep, signature->as_C_string()); + } } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/interpreter/interpreterRuntime.cpp --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -702,10 +702,6 @@ methodHandle caller_method(thread, method(thread)); - // first find the bootstrap method - KlassHandle caller_klass(thread, caller_method->method_holder()); - Handle bootm = SystemDictionary::find_bootstrap_method(caller_klass, CHECK); - constantPoolHandle pool(thread, caller_method->constants()); pool->set_invokedynamic(); // mark header to flag active call sites @@ -726,7 +722,7 @@ CallInfo info; LinkResolver::resolve_invoke(info, Handle(), pool, site_index, bytecode, CHECK); - // The main entry corresponds to a JVM_CONSTANT_NameAndType, and serves + // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves // as a common reference point for all invokedynamic call sites with // that exact call descriptor. We will link it in the CP cache exactly // as if it were an invokevirtual of MethodHandle.invoke. @@ -734,23 +730,30 @@ bytecode, info.resolved_method(), info.vtable_index()); - assert(pool->cache()->entry_at(main_index)->is_vfinal(), "f2 must be a methodOop"); } // The method (f2 entry) of the main entry is the MH.invoke for the // invokedynamic target call signature. - intptr_t f2_value = pool->cache()->entry_at(main_index)->f2(); - methodHandle signature_invoker(THREAD, (methodOop) f2_value); + oop f1_value = pool->cache()->entry_at(main_index)->f1(); + methodHandle signature_invoker(THREAD, (methodOop) f1_value); assert(signature_invoker.not_null() && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), "correct result from LinkResolver::resolve_invokedynamic"); + Handle bootm = SystemDictionary::find_bootstrap_method(caller_method, caller_bci, + main_index, CHECK); + if (bootm.is_null()) { + THROW_MSG(vmSymbols::java_lang_IllegalStateException(), + "no bootstrap method found for invokedynamic"); + } + + // Short circuit if CallSite has been bound already: + if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null()) + return; + symbolHandle call_site_name(THREAD, pool->name_ref_at(site_index)); Handle info; // NYI: Other metadata from a new kind of CP entry. (Annotations?) - // this is the index which gets stored on the CallSite object (as "callerPosition"): - int call_site_position = constantPoolCacheOopDesc::decode_secondary_index(site_index); - Handle call_site = SystemDictionary::make_dynamic_call_site(bootm, // Callee information: diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -67,6 +67,15 @@ set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); } +void CallInfo::set_dynamic(methodHandle resolved_method, TRAPS) { + assert(resolved_method->is_method_handle_invoke(), ""); + KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); + assert(resolved_klass == resolved_method->method_holder(), ""); + int vtable_index = methodOopDesc::nonvirtual_vtable_index; + assert(resolved_method->vtable_index() == vtable_index, ""); + set_common(resolved_klass, KlassHandle(), resolved_method, resolved_method, vtable_index, CHECK); +} + void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond"); _resolved_klass = resolved_klass; @@ -176,9 +185,20 @@ KlassHandle klass, symbolHandle name, symbolHandle signature, KlassHandle current_klass, TRAPS) { - if (EnableMethodHandles && MethodHandles::enabled() && + if (EnableMethodHandles && klass() == SystemDictionary::MethodHandle_klass() && methodOopDesc::is_method_handle_invoke_name(name())) { + if (!MethodHandles::enabled()) { + // Make sure the Java part of the runtime has been booted up. + klassOop natives = SystemDictionary::MethodHandleNatives_klass(); + if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) { + SystemDictionary::resolve_or_fail(vmSymbolHandles::sun_dyn_MethodHandleNatives(), + Handle(), + Handle(), + true, + CHECK); + } + } methodOop result_oop = SystemDictionary::find_method_handle_invoke(name, signature, current_klass, @@ -1065,7 +1085,7 @@ if (resolved_method.is_null()) { THROW(vmSymbols::java_lang_InternalError()); } - result.set_virtual(resolved_klass, KlassHandle(), resolved_method, resolved_method, resolved_method->vtable_index(), CHECK); + result.set_dynamic(resolved_method, CHECK); } //------------------------------------------------------------------------------------------------------------------------ diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/interpreter/linkResolver.hpp --- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -73,6 +73,7 @@ void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS); void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS); void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS); + void set_dynamic( methodHandle resolved_method, TRAPS); void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS); friend class LinkResolver; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/interpreter/rewriter.cpp --- a/hotspot/src/share/vm/interpreter/rewriter.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -32,14 +32,17 @@ void Rewriter::compute_index_maps() { const int length = _pool->length(); init_cp_map(length); + jint tag_mask = 0; for (int i = 0; i < length; i++) { int tag = _pool->tag_at(i).value(); + tag_mask |= (1 << tag); switch (tag) { case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Fieldref : // fall through case JVM_CONSTANT_Methodref : // fall through case JVM_CONSTANT_MethodHandle : // fall through case JVM_CONSTANT_MethodType : // fall through + case JVM_CONSTANT_InvokeDynamic : // fall through add_cp_cache_entry(i); break; } @@ -47,6 +50,8 @@ guarantee((int)_cp_cache_map.length()-1 <= (int)((u2)-1), "all cp cache indexes fit in a u2"); + + _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0); } @@ -59,6 +64,28 @@ constantPoolCacheOop cache = oopFactory::new_constantPoolCache(length, methodOopDesc::IsUnsafeConc, CHECK); cache->initialize(_cp_cache_map); + + // Don't bother to the next pass if there is no JVM_CONSTANT_InvokeDynamic. + if (_have_invoke_dynamic) { + for (int i = 0; i < length; i++) { + int pool_index = cp_cache_entry_pool_index(i); + if (pool_index >= 0 && + _pool->tag_at(pool_index).is_invoke_dynamic()) { + int bsm_index = _pool->invoke_dynamic_bootstrap_method_ref_index_at(pool_index); + if (bsm_index != 0) { + assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant"); + // There is a CP cache entry holding the BSM for these calls. + int bsm_cache_index = cp_entry_to_cp_cache(bsm_index); + cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index); + } else { + // There is no CP cache entry holding the BSM for these calls. + // We will need to look for a class-global BSM, later. + guarantee(AllowTransitionalJSR292, ""); + } + } + } + } + _pool->set_cache(cache); cache->set_constant_pool(_pool()); } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/interpreter/rewriter.hpp --- a/hotspot/src/share/vm/interpreter/rewriter.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/interpreter/rewriter.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -32,6 +32,7 @@ objArrayHandle _methods; intArray _cp_map; intStack _cp_cache_map; + bool _have_invoke_dynamic; void init_cp_map(int length) { _cp_map.initialize(length, -1); @@ -56,6 +57,22 @@ return cache_index; } + // Access the contents of _cp_cache_map to determine CP cache layout. + int cp_cache_entry_pool_index(int cache_index) { + int cp_index = _cp_cache_map[cache_index]; + if ((cp_index & _secondary_entry_tag) != 0) + return -1; + else + return cp_index; + } + int cp_cache_secondary_entry_main_index(int cache_index) { + int cp_index = _cp_cache_map[cache_index]; + if ((cp_index & _secondary_entry_tag) == 0) + return -1; + else + return (cp_index - _secondary_entry_tag); + } + // All the work goes in here: Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, objArrayHandle methods, TRAPS); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/oops/constantPoolKlass.cpp --- a/hotspot/src/share/vm/oops/constantPoolKlass.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/oops/constantPoolKlass.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -379,6 +379,10 @@ case JVM_CONSTANT_MethodType : st->print("signature_index=%d", cp->method_type_index_at(index)); break; + case JVM_CONSTANT_InvokeDynamic : + st->print("bootstrap_method_index=%d", cp->invoke_dynamic_bootstrap_method_ref_index_at(index)); + st->print(" name_and_type_index=%d", cp->invoke_dynamic_name_and_type_ref_index_at(index)); + break; default: ShouldNotReachHere(); break; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/oops/constantPoolOop.cpp --- a/hotspot/src/share/vm/oops/constantPoolOop.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -264,10 +264,15 @@ int constantPoolOopDesc::impl_name_and_type_ref_index_at(int which, bool uncached) { int i = which; if (!uncached && cache() != NULL) { - if (constantPoolCacheOopDesc::is_secondary_index(which)) + if (constantPoolCacheOopDesc::is_secondary_index(which)) { // Invokedynamic indexes are always processed in native order // so there is no question of reading a native u2 in Java order here. - return cache()->main_entry_at(which)->constant_pool_index(); + int pool_index = cache()->main_entry_at(which)->constant_pool_index(); + if (tag_at(pool_index).is_invoke_dynamic()) + pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index); + assert(tag_at(pool_index).is_name_and_type(), ""); + return pool_index; + } // change byte-ordering and go via cache i = remap_instruction_operand_from_cache(which); } else { @@ -830,6 +835,19 @@ } } break; + case JVM_CONSTANT_InvokeDynamic: + { + int k1 = invoke_dynamic_bootstrap_method_ref_index_at(index1); + int k2 = cp2->invoke_dynamic_bootstrap_method_ref_index_at(index2); + if (k1 == k2) { + int i1 = invoke_dynamic_name_and_type_ref_index_at(index1); + int i2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2); + if (i1 == i2) { + return true; + } + } + } break; + case JVM_CONSTANT_UnresolvedString: { symbolOop s1 = unresolved_string_at(index1); @@ -1016,6 +1034,13 @@ to_cp->method_handle_index_at_put(to_i, k1, k2); } break; + case JVM_CONSTANT_InvokeDynamic: + { + int k1 = invoke_dynamic_bootstrap_method_ref_index_at(from_i); + int k2 = invoke_dynamic_name_and_type_ref_index_at(from_i); + to_cp->invoke_dynamic_at_put(to_i, k1, k2); + } break; + // Invalid is used as the tag for the second constant pool entry // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should // not be seen by itself. @@ -1231,6 +1256,7 @@ case JVM_CONSTANT_Methodref: case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_NameAndType: + case JVM_CONSTANT_InvokeDynamic: return 5; case JVM_CONSTANT_Long: @@ -1444,6 +1470,15 @@ DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); break; } + case JVM_CONSTANT_InvokeDynamic: { + *bytes = JVM_CONSTANT_InvokeDynamic; + idx1 = invoke_dynamic_bootstrap_method_ref_index_at(idx); + idx2 = invoke_dynamic_name_and_type_ref_index_at(idx); + Bytes::put_Java_u2((address) (bytes+1), idx1); + Bytes::put_Java_u2((address) (bytes+3), idx2); + DBG(printf("JVM_CONSTANT_InvokeDynamic: %hd %hd", idx1, idx2)); + break; + } } DBG(printf("\n")); bytes += ent_size; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/oops/constantPoolOop.hpp --- a/hotspot/src/share/vm/oops/constantPoolOop.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/oops/constantPoolOop.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -156,6 +156,11 @@ *int_at_addr(which) = ref_index; } + void invoke_dynamic_at_put(int which, int bootstrap_method_index, int name_and_type_index) { + tag_at_put(which, JVM_CONSTANT_InvokeDynamic); + *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index; + } + // Temporary until actual use void unresolved_string_at_put(int which, symbolOop s) { *obj_at_addr(which) = NULL; @@ -396,6 +401,16 @@ int sym = method_type_index_at(which); return symbol_at(sym); } + int invoke_dynamic_bootstrap_method_ref_index_at(int which) { + assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); + jint ref_index = *int_at_addr(which); + return extract_low_short_from_int(ref_index); + } + int invoke_dynamic_name_and_type_ref_index_at(int which) { + assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); + jint ref_index = *int_at_addr(which); + return extract_high_short_from_int(ref_index); + } // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, // name_and_type_ref_index_at) all expect to be passed indices obtained diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/oops/cpCacheOop.cpp --- a/hotspot/src/share/vm/oops/cpCacheOop.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -134,7 +134,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, methodHandle method, int vtable_index) { - + assert(!is_secondary_entry(), ""); assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface); @@ -142,7 +142,6 @@ int byte_no = -1; bool needs_vfinal_flag = false; switch (invoke_code) { - case Bytecodes::_invokedynamic: case Bytecodes::_invokevirtual: case Bytecodes::_invokeinterface: { if (method->can_be_statically_bound()) { @@ -155,6 +154,23 @@ byte_no = 2; break; } + + case Bytecodes::_invokedynamic: // similar to _invokevirtual + if (TraceInvokeDynamic) { + tty->print_cr("InvokeDynamic set_method%s method="PTR_FORMAT" index=%d", + (is_secondary_entry() ? " secondary" : ""), + (intptr_t)method(), vtable_index); + method->print(); + this->print(tty, 0); + } + assert(method->can_be_statically_bound(), "must be a MH invoker method"); + assert(AllowTransitionalJSR292 || _f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized"); + set_f1(method()); + needs_vfinal_flag = false; // _f2 is not an oop + assert(!is_vfinal(), "f2 not an oop"); + byte_no = 1; // coordinate this with bytecode_number & is_resolved + break; + case Bytecodes::_invokespecial: // Preserve the value of the vfinal flag on invokevirtual bytecode // which may be shared with this constant pool cache entry. @@ -209,6 +225,7 @@ void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { + assert(!is_secondary_entry(), ""); klassOop interf = method->method_holder(); assert(instanceKlass::cast(interf)->is_interface(), "must be an interface"); set_f1(interf); @@ -218,8 +235,23 @@ } +void ConstantPoolCacheEntry::initialize_bootstrap_method_index_in_cache(int bsm_cache_index) { + assert(!is_secondary_entry(), "only for JVM_CONSTANT_InvokeDynamic main entry"); + assert(_f2 == 0, "initialize once"); + assert(bsm_cache_index == (int)(u2)bsm_cache_index, "oob"); + set_f2(bsm_cache_index + constantPoolOopDesc::CPCACHE_INDEX_TAG); +} + +int ConstantPoolCacheEntry::bootstrap_method_index_in_cache() { + assert(!is_secondary_entry(), "only for JVM_CONSTANT_InvokeDynamic main entry"); + intptr_t bsm_cache_index = (intptr_t) _f2 - constantPoolOopDesc::CPCACHE_INDEX_TAG; + assert(bsm_cache_index == (intptr_t)(u2)bsm_cache_index, "oob"); + return (int) bsm_cache_index; +} + void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, methodHandle signature_invoker) { + assert(is_secondary_entry(), ""); int param_size = signature_invoker->size_of_parameters(); assert(param_size >= 1, "method argument size must include MH.this"); param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic @@ -227,7 +259,6 @@ // racing threads might be trying to install their own favorites set_f1(call_site()); } - //set_f2(0); bool is_final = true; assert(signature_invoker->is_final_method(), "is_final"); set_flags(as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size); @@ -417,14 +448,14 @@ // print separator if (index == 0) tty->print_cr(" -------------"); // print entry - tty->print_cr("%3d (%08x) ", index, this); + tty->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this); if (is_secondary_entry()) tty->print_cr("[%5d|secondary]", main_entry_index()); else tty->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index()); - tty->print_cr(" [ %08x]", (address)(oop)_f1); - tty->print_cr(" [ %08x]", _f2); - tty->print_cr(" [ %08x]", _flags); + tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)(oop)_f1); + tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2); + tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags); tty->print_cr(" -------------"); } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/oops/cpCacheOop.hpp --- a/hotspot/src/share/vm/oops/cpCacheOop.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/oops/cpCacheOop.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -185,6 +185,10 @@ methodHandle signature_invoker // determines signature information ); + // For JVM_CONSTANT_InvokeDynamic cache entries: + void initialize_bootstrap_method_index_in_cache(int bsm_cache_index); + int bootstrap_method_index_in_cache(); + void set_parameter_size(int value) { assert(parameter_size() == 0 || parameter_size() == value, "size must not change"); @@ -207,6 +211,7 @@ case Bytecodes::_getfield : // fall through case Bytecodes::_invokespecial : // fall through case Bytecodes::_invokestatic : // fall through + case Bytecodes::_invokedynamic : // fall through case Bytecodes::_invokeinterface : return 1; case Bytecodes::_putstatic : // fall through case Bytecodes::_putfield : // fall through @@ -234,6 +239,7 @@ Bytecodes::Code bytecode_1() const { return Bytecodes::cast((_indices >> 16) & 0xFF); } Bytecodes::Code bytecode_2() const { return Bytecodes::cast((_indices >> 24) & 0xFF); } volatile oop f1() const { return _f1; } + bool is_f1_null() const { return (oop)_f1 == NULL; } // classifies a CPC entry as unbound intx f2() const { return _f2; } int field_index() const; int parameter_size() const { return _flags & 0xFF; } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/oops/methodOop.cpp --- a/hotspot/src/share/vm/oops/methodOop.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/oops/methodOop.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -851,9 +851,15 @@ // MethodHandleCompiler. // Must be consistent with MethodHandleCompiler::get_method_oop(). bool methodOopDesc::is_method_handle_adapter() const { - return (is_method_handle_invoke_name(name()) && - is_synthetic() && - MethodHandleCompiler::klass_is_method_handle_adapter_holder(method_holder())); + if (is_synthetic() && + !is_native() && // has code from MethodHandleCompiler + is_method_handle_invoke_name(name()) && + MethodHandleCompiler::klass_is_method_handle_adapter_holder(method_holder())) { + assert(!is_method_handle_invoke(), "disjoint"); + return true; + } else { + return false; + } } methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/prims/jvm.h Thu Aug 12 19:55:48 2010 -0700 @@ -1046,7 +1046,8 @@ JVM_CONSTANT_InterfaceMethodref, JVM_CONSTANT_NameAndType, JVM_CONSTANT_MethodHandle = 15, // JSR 292 - JVM_CONSTANT_MethodType = 16 // JSR 292 + JVM_CONSTANT_MethodType = 16, // JSR 292 + JVM_CONSTANT_InvokeDynamic = 17 // JSR 292 }; /* JVM_CONSTANT_MethodHandle subtypes */ diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/prims/methodHandleWalk.cpp --- a/hotspot/src/share/vm/prims/methodHandleWalk.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/prims/methodHandleWalk.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -738,6 +738,12 @@ // bi case Bytecodes::_ldc: + assert(Bytecodes::format_bits(op, false) == (Bytecodes::_fmt_b|Bytecodes::_fmt_has_k), "wrong bytecode format"); + assert((char) index == index, "index does not fit in 8-bit"); + _bytecode.push(op); + _bytecode.push(index); + break; + case Bytecodes::_iload: case Bytecodes::_lload: case Bytecodes::_fload: @@ -754,7 +760,8 @@ _bytecode.push(index); break; - // bii + // bkk + case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: case Bytecodes::_checkcast: assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bkk, "wrong bytecode format"); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/prims/methodHandles.cpp --- a/hotspot/src/share/vm/prims/methodHandles.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -2475,6 +2475,10 @@ JVM_ENTRY(void, MHI_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) { instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD); + if (!AllowTransitionalJSR292) { + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), + "registerBootstrapMethod is only supported in JSR 292 EDR"); + } ik->link_class(CHECK); if (!java_dyn_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle"); diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -3517,6 +3517,9 @@ experimental(bool, EnableInvokeDynamic, false, \ "recognize the invokedynamic instruction") \ \ + experimental(bool, AllowTransitionalJSR292, true, \ + "recognize pre-PFD formats of invokedynamic") \ + \ develop(bool, TraceInvokeDynamic, false, \ "trace internal invoke dynamic operations") \ \ diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/runtime/mutexLocker.cpp --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -159,6 +159,8 @@ def(STS_init_lock , Mutex, leaf, true ); if (UseConcMarkSweepGC) { def(iCMS_lock , Monitor, special, true ); // CMS incremental mode start/stop notification + } + if (UseConcMarkSweepGC || UseG1GC) { def(FullGCCount_lock , Monitor, leaf, true ); // in support of ExplicitGCInvokesConcurrent } if (UseG1GC) { diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/utilities/constantTag.cpp --- a/hotspot/src/share/vm/utilities/constantTag.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/utilities/constantTag.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -91,6 +91,8 @@ return "MethodHandle"; case JVM_CONSTANT_MethodType : return "MethodType"; + case JVM_CONSTANT_InvokeDynamic : + return "InvokeDynamic"; case JVM_CONSTANT_Object : return "Object"; case JVM_CONSTANT_Utf8 : diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/utilities/constantTag.hpp --- a/hotspot/src/share/vm/utilities/constantTag.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/utilities/constantTag.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -80,13 +80,14 @@ bool is_method_type() const { return _tag == JVM_CONSTANT_MethodType; } bool is_method_handle() const { return _tag == JVM_CONSTANT_MethodHandle; } + bool is_invoke_dynamic() const { return _tag == JVM_CONSTANT_InvokeDynamic; } constantTag() { _tag = JVM_CONSTANT_Invalid; } constantTag(jbyte tag) { assert((tag >= 0 && tag <= JVM_CONSTANT_NameAndType) || - (tag >= JVM_CONSTANT_MethodHandle && tag <= JVM_CONSTANT_MethodType) || + (tag >= JVM_CONSTANT_MethodHandle && tag <= JVM_CONSTANT_InvokeDynamic) || (tag >= JVM_CONSTANT_InternalMin && tag <= JVM_CONSTANT_InternalMax), "Invalid constant tag"); _tag = tag; } diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/utilities/globalDefinitions.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -345,6 +345,35 @@ return align_size_up(offset, HeapWordsPerLong); } +// The expected size in bytes of a cache line, used to pad data structures. +#define DEFAULT_CACHE_LINE_SIZE 64 + +// Bytes needed to pad type to avoid cache-line sharing; alignment should be the +// expected cache line size (a power of two). The first addend avoids sharing +// when the start address is not a multiple of alignment; the second maintains +// alignment of starting addresses that happen to be a multiple. +#define PADDING_SIZE(type, alignment) \ + ((alignment) + align_size_up_(sizeof(type), alignment)) + +// Templates to create a subclass padded to avoid cache line sharing. These are +// effective only when applied to derived-most (leaf) classes. + +// When no args are passed to the base ctor. +template +class Padded: public T { +private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; + +// When either 0 or 1 args may be passed to the base ctor. +template +class Padded01: public T { +public: + Padded01(): T() { } + Padded01(Arg1T arg1): T(arg1) { } +private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; //---------------------------------------------------------------------------------------------------- // Utility macros for compilers diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/utilities/taskqueue.cpp --- a/hotspot/src/share/vm/utilities/taskqueue.cpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/utilities/taskqueue.cpp Thu Aug 12 19:55:48 2010 -0700 @@ -31,6 +31,48 @@ uint ParallelTaskTerminator::_total_peeks = 0; #endif +#if TASKQUEUE_STATS +const char * const TaskQueueStats::_names[last_stat_id] = { + "qpush", "qpop", "qpop-s", "qattempt", "qsteal", "opush", "omax" +}; + +void TaskQueueStats::print_header(unsigned int line, outputStream* const stream, + unsigned int width) +{ + // Use a width w: 1 <= w <= max_width + const unsigned int max_width = 40; + const unsigned int w = MAX2(MIN2(width, max_width), 1U); + + if (line == 0) { // spaces equal in width to the header + const unsigned int hdr_width = w * last_stat_id + last_stat_id - 1; + stream->print("%*s", hdr_width, " "); + } else if (line == 1) { // labels + stream->print("%*s", w, _names[0]); + for (unsigned int i = 1; i < last_stat_id; ++i) { + stream->print(" %*s", w, _names[i]); + } + } else if (line == 2) { // dashed lines + char dashes[max_width + 1]; + memset(dashes, '-', w); + dashes[w] = '\0'; + stream->print("%s", dashes); + for (unsigned int i = 1; i < last_stat_id; ++i) { + stream->print(" %s", dashes); + } + } +} + +void TaskQueueStats::print(outputStream* stream, unsigned int width) const +{ + #define FMT SIZE_FORMAT_W(*) + stream->print(FMT, width, _stats[0]); + for (unsigned int i = 1; i < last_stat_id; ++i) { + stream->print(" " FMT, width, _stats[i]); + } + #undef FMT +} +#endif // TASKQUEUE_STATS + int TaskQueueSetSuper::randomParkAndMiller(int *seed0) { const int a = 16807; const int m = 2147483647; diff -r 96a57de47def -r 67584b95a0f0 hotspot/src/share/vm/utilities/taskqueue.hpp --- a/hotspot/src/share/vm/utilities/taskqueue.hpp Wed Aug 11 10:05:56 2010 -0400 +++ b/hotspot/src/share/vm/utilities/taskqueue.hpp Thu Aug 12 19:55:48 2010 -0700 @@ -22,6 +22,72 @@ * */ +// Simple TaskQueue stats that are collected by default in debug builds. + +#if !defined(TASKQUEUE_STATS) && defined(ASSERT) +#define TASKQUEUE_STATS 1 +#elif !defined(TASKQUEUE_STATS) +#define TASKQUEUE_STATS 0 +#endif + +#if TASKQUEUE_STATS +#define TASKQUEUE_STATS_ONLY(code) code +#else +#define TASKQUEUE_STATS_ONLY(code) +#endif // TASKQUEUE_STATS + +#if TASKQUEUE_STATS +class TaskQueueStats { +public: + enum StatId { + push, // number of taskqueue pushes + pop, // number of taskqueue pops + pop_slow, // subset of taskqueue pops that were done slow-path + steal_attempt, // number of taskqueue steal attempts + steal, // number of taskqueue steals + overflow, // number of overflow pushes + overflow_max_len, // max length of overflow stack + last_stat_id + }; + +public: + inline TaskQueueStats() { reset(); } + + inline void record_push() { ++_stats[push]; } + inline void record_pop() { ++_stats[pop]; } + inline void record_pop_slow() { record_pop(); ++_stats[pop_slow]; } + inline void record_steal(bool success); + inline void record_overflow(size_t new_length); + + inline size_t get(StatId id) const { return _stats[id]; } + inline const size_t* get() const { return _stats; } + + inline void reset(); + + static void print_header(unsigned int line, outputStream* const stream = tty, + unsigned int width = 10); + void print(outputStream* const stream = tty, unsigned int width = 10) const; + +private: + size_t _stats[last_stat_id]; + static const char * const _names[last_stat_id]; +}; + +void TaskQueueStats::record_steal(bool success) { + ++_stats[steal_attempt]; + if (success) ++_stats[steal]; +} + +void TaskQueueStats::record_overflow(size_t new_len) { + ++_stats[overflow]; + if (new_len > _stats[overflow_max_len]) _stats[overflow_max_len] = new_len; +} + +void TaskQueueStats::reset() { + memset(_stats, 0, sizeof(_stats)); +} +#endif // TASKQUEUE_STATS + template class TaskQueueSuper: public CHeapObj { protected: @@ -135,6 +201,8 @@ // Total size of queue. static const uint total_size() { return N; } + + TASKQUEUE_STATS_ONLY(TaskQueueStats stats;) }; template @@ -152,6 +220,7 @@ public: using TaskQueueSuper::max_elems; using TaskQueueSuper::size; + TASKQUEUE_STATS_ONLY(using TaskQueueSuper::stats;) private: // Slow paths for push, pop_local. (pop_global has no fast path.) @@ -224,14 +293,14 @@ // g++ complains if the volatile result of the assignment is unused. const_cast(_elems[localBot] = t); OrderAccess::release_store(&_bottom, increment_index(localBot)); + TASKQUEUE_STATS_ONLY(stats.record_push()); return true; } return false; } template -bool GenericTaskQueue:: -pop_local_slow(uint localBot, Age oldAge) { +bool GenericTaskQueue::pop_local_slow(uint localBot, Age oldAge) { // This queue was observed to contain exactly one element; either this // thread will claim it, or a competing "pop_global". In either case, // the queue will be logically empty afterwards. Create a new Age value @@ -251,6 +320,7 @@ if (tempAge == oldAge) { // We win. assert(dirty_size(localBot, _age.top()) != N - 1, "sanity"); + TASKQUEUE_STATS_ONLY(stats.record_pop_slow()); return true; } } @@ -306,6 +376,8 @@ typedef GrowableArray overflow_t; typedef GenericTaskQueue taskqueue_t; + TASKQUEUE_STATS_ONLY(using taskqueue_t::stats;) + OverflowTaskQueue(); ~OverflowTaskQueue(); void initialize(); @@ -356,6 +428,7 @@ { if (!taskqueue_t::push(t)) { overflow_stack()->push(t); + TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->length())); } return true; } @@ -424,9 +497,13 @@ template bool GenericTaskQueueSet::steal(uint queue_num, int* seed, E& t) { - for (uint i = 0; i < 2 * _n; i++) - if (steal_best_of_2(queue_num, seed, t)) + for (uint i = 0; i < 2 * _n; i++) { + if (steal_best_of_2(queue_num, seed, t)) { + TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true)); return true; + } + } + TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(false)); return false; } @@ -574,6 +651,7 @@ // g++ complains if the volatile result of the assignment is unused. const_cast(_elems[localBot] = t); OrderAccess::release_store(&_bottom, increment_index(localBot)); + TASKQUEUE_STATS_ONLY(stats.record_push()); return true; } else { return push_slow(t, dirty_n_elems); @@ -603,6 +681,7 @@ idx_t tp = _age.top(); // XXX if (size(localBot, tp) > 0) { assert(dirty_size(localBot, tp) != N - 1, "sanity"); + TASKQUEUE_STATS_ONLY(stats.record_pop()); return true; } else { // Otherwise, the queue contained exactly one element; we take the slow diff -r 96a57de47def -r 67584b95a0f0 jaxp/.hgtags --- a/jaxp/.hgtags Wed Aug 11 10:05:56 2010 -0400 +++ b/jaxp/.hgtags Thu Aug 12 19:55:48 2010 -0700 @@ -77,3 +77,5 @@ d524be5ef62e8b8cb890c59a5d2c19ef0ab50d45 jdk7-b100 17f62a566a2020fd908e77106ed885e0c4e7c14d jdk7-b101 15573625af97d01c4e24549041cba7584da7fe88 jdk7-b102 +b7722e8788644507c10bb69a137de422d0300b24 jdk7-b103 +d42c4acb6424a094bdafe2ad9c8c1c7ca7fb7b7e jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 jaxws/.hgtags --- a/jaxws/.hgtags Wed Aug 11 10:05:56 2010 -0400 +++ b/jaxws/.hgtags Thu Aug 12 19:55:48 2010 -0700 @@ -77,3 +77,5 @@ bd26d0ce0c3cb43e58a8e2770cc03f26d96ffe5c jdk7-b100 b55ce274490082712f5e002b38d2eed505ca863d jdk7-b101 d8580443d1815d68e0035a0560634e50fa899288 jdk7-b102 +267386d6b923f724309cab855a555e2d86a15c8f jdk7-b103 +bbc4cce6c20aeca4862804a6e8315a2350d43633 jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 jdk/.hgtags --- a/jdk/.hgtags Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/.hgtags Thu Aug 12 19:55:48 2010 -0700 @@ -77,3 +77,5 @@ 820b4e843d5168370a3bf166d19751a3271d8575 jdk7-b100 d58354a69011f3d3354765fa3167567c4c4a9612 jdk7-b101 13029a61b16bec06535d4f0aa98229b358684128 jdk7-b102 +6488b70a23cc6dc4b7e00809bc503c2884bafb28 jdk7-b103 +1a92820132a0221c5bdedd42d0888c57ce4cbb34 jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 jdk/make/common/Release.gmk --- a/jdk/make/common/Release.gmk Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/make/common/Release.gmk Thu Aug 12 19:55:48 2010 -0700 @@ -571,6 +571,16 @@ $(ECHO) "META-INF/services/com.sun.tools.xjc.Plugin" >> $@ $(ECHO) "com/sun/tools/" >> $@ $(ECHO) "sun/jvmstat/" >> $@ + $(ECHO) "sun/nio/cs/ext/" >> $@ + $(ECHO) "sun/awt/HKSCS.class" >> $@ + $(ECHO) "sun/awt/motif/X11GB2312$Decoder.class" >> $@ + $(ECHO) "sun/awt/motif/X11GB2312$Encoder.class" >> $@ + $(ECHO) "sun/awt/motif/X11GB2312.class" >> $@ + $(ECHO) "sun/awt/motif/X11GBK$Encoder.class" >> $@ + $(ECHO) "sun/awt/motif/X11GBK.class" >> $@ + $(ECHO) "sun/awt/motif/X11KSC5601$Decoder.class" >> $@ + $(ECHO) "sun/awt/motif/X11KSC5601$Encoder.class" >> $@ + $(ECHO) "sun/awt/motif/X11KSC5601.class" >> $@ $(ECHO) "sun/rmi/rmic/" >> $@ $(ECHO) "sun/tools/asm/" >> $@ $(ECHO) "sun/tools/java/" >> $@ diff -r 96a57de47def -r 67584b95a0f0 jdk/make/common/shared/Defs-versions.gmk --- a/jdk/make/common/shared/Defs-versions.gmk Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/make/common/shared/Defs-versions.gmk Thu Aug 12 19:55:48 2010 -0700 @@ -191,7 +191,7 @@ # Generic REQUIRED_ANT_VER = 1.6.3 -REQUIRED_BOOT_VER = 1.5 +REQUIRED_BOOT_VER = 1.6 REQUIRED_FREETYPE_VERSION = 2.3.0 REQUIRED_MAKE_VER = 3.78 REQUIRED_UNZIP_VER = 5.12 diff -r 96a57de47def -r 67584b95a0f0 jdk/make/docs/Makefile --- a/jdk/make/docs/Makefile Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/make/docs/Makefile Thu Aug 12 19:55:48 2010 -0700 @@ -47,9 +47,9 @@ # Url to devdocs page # Was: http://java.sun.com/javase/6/webnotes/devdocs-vs-specs.html -DEV_DOCS_URL-5 = http://java.sun.com/j2se/1.5.0/docs -DEV_DOCS_URL-6 = http://download.oracle.com/docs/cd/E17409_01/javase/6/docs -DEV_DOCS_URL-7 = http://download.oracle.com/docs/cd/E17409_01/javase/7/docs +DEV_DOCS_URL-5 = http://java.sun.com/j2se/1.5.0/docs/index.html +DEV_DOCS_URL-6 = http://download.oracle.com/javase/6/docs/index.html +DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION)) # Url to Java Language Spec @@ -84,6 +84,11 @@ $(SHARE_SRC)/../solaris/classes \ $(SHARE_SRC)/../windows/classes \ $(SHARE_SRC)/doc/stub + +# List of directories that actually exist +ALL_EXISTING_SOURCE_DIRS := $(wildcard $(ALL_SOURCE_DIRS)) + +# List with classpath separator between them EMPTY:= SPACE:= $(EMPTY) $(EMPTY) RELEASEDOCS_SOURCEPATH = \ @@ -240,7 +245,8 @@ # Default target is same as docs target, create core api and all others it can # -all docs: coredocs otherdocs +all: docs +docs: coredocs otherdocs ################################################################# # Production Targets -- USE THESE TARGETS WHEN: @@ -1178,9 +1184,9 @@ # # Get a cache of all the directories -$(DIRECTORY_CACHE): $(ALL_SOURCE_DIRS) +$(DIRECTORY_CACHE): $(ALL_EXISTING_SOURCE_DIRS) $(prep-target) - @for cp in $(ALL_SOURCE_DIRS) ; do \ + @for cp in $(ALL_EXISTING_SOURCE_DIRS) ; do \ $(ECHO) "$(FIND) $${cp} -type f >> $@"; \ $(FIND) $${cp} -type f >> $@; \ done diff -r 96a57de47def -r 67584b95a0f0 jdk/make/java/nio/mapfile-linux --- a/jdk/make/java/nio/mapfile-linux Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/make/java/nio/mapfile-linux Thu Aug 12 19:55:48 2010 -0700 @@ -119,6 +119,7 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0; Java_sun_nio_ch_ServerSocketChannelImpl_initIDs; Java_sun_nio_ch_SocketChannelImpl_checkConnect; + Java_sun_nio_ch_SocketChannelImpl_sendOutOfBandData; Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0; Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs; Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect; diff -r 96a57de47def -r 67584b95a0f0 jdk/make/java/nio/mapfile-solaris --- a/jdk/make/java/nio/mapfile-solaris Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/make/java/nio/mapfile-solaris Thu Aug 12 19:55:48 2010 -0700 @@ -106,6 +106,7 @@ Java_sun_nio_ch_ServerSocketChannelImpl_accept0; Java_sun_nio_ch_ServerSocketChannelImpl_initIDs; Java_sun_nio_ch_SocketChannelImpl_checkConnect; + Java_sun_nio_ch_SocketChannelImpl_sendOutOfBandData; Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0; Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs; Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect; diff -r 96a57de47def -r 67584b95a0f0 jdk/make/sun/nio/cs/Makefile --- a/jdk/make/sun/nio/cs/Makefile Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/make/sun/nio/cs/Makefile Thu Aug 12 19:55:48 2010 -0700 @@ -58,6 +58,25 @@ FILES_genout_extcs = $(FILES_gen_extcs:%.java=$(GENSRCDIR)/%.java) # +# These sun.awt charsets use sun/nio/cs/ext charsets that only exist +# in JDK7 charsets.jar, which causes problem when build the symbol +# table for rt.jar in Release.gmk. They are now removed from the +# rt.jar when building jdk/jre image (in Release.gmk), so add them +# into charsets.jar here +# +ifeq ($(PLATFORM), windows) +FILES_src += \ + sun/awt/HKSCS.java +else +# Solaris/Linux +FILES_src += \ + sun/awt/HKSCS.java \ + sun/awt/motif/X11GB2312.java \ + sun/awt/motif/X11GBK.java \ + sun/awt/motif/X11KSC5601.java +endif # PLATFORM + +# # Rules # include $(BUILDDIR)/common/Classes.gmk diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java --- a/jdk/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/dns/DnsContextFactory.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, 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 @@ -132,7 +132,7 @@ throw new ConfigurationException("DNS pseudo-URL required"); } - List servers = new ArrayList(); + List servers = new ArrayList<>(); for (int i = 0; i < urls.length; i++) { String server = urls[i].getHost(); @@ -142,7 +142,7 @@ // No server or port given, so look to underlying platform. // ResolverConfiguration does some limited caching, so the // following is reasonably efficient even if called rapid-fire. - List platformServers = + List platformServers = ResolverConfiguration.open().nameservers(); if (!platformServers.isEmpty()) { servers.addAll(platformServers); @@ -157,8 +157,7 @@ ? server : server + ":" + port); } - return (String[]) servers.toArray( - new String[servers.size()]); + return servers.toArray(new String[servers.size()]); } /* diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/com/sun/jndi/ldap/Connection.java --- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2010, 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 @@ -658,6 +658,11 @@ } } if (nparent) { + LdapRequest ldr = pendingRequests; + while (ldr != null) { + ldr.notify(); + ldr = ldr.next; + } parent.processConnectionClosure(); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/com/sun/jndi/ldap/Filter.java --- a/jdk/src/share/classes/com/sun/jndi/ldap/Filter.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Filter.java Thu Aug 12 19:55:48 2010 -0700 @@ -803,8 +803,7 @@ // //////////////////////////////////////////////////////////////////////////// - // private static final boolean dbg = false; - private static final boolean dbg = true; + private static final boolean dbg = false; private static int dbgIndent = 0; private static void dprint(String msg) { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java --- a/jdk/src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java Thu Aug 12 19:55:48 2010 -0700 @@ -81,7 +81,7 @@ } RMIClientSocketFactory socketFactory = - (RMIClientSocketFactory) env.get(SOCKET_FACTORY); + (RMIClientSocketFactory) environment.get(SOCKET_FACTORY); registry = getRegistry(host, port, socketFactory); this.host = host; this.port = port; diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/java/lang/AutoCloseable.java --- a/jdk/src/share/classes/java/lang/AutoCloseable.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/java/lang/AutoCloseable.java Thu Aug 12 19:55:48 2010 -0700 @@ -41,6 +41,13 @@ * be declared to throw more specific exceptions (or no exception * at all, if the close cannot fail). * + *

Note that unlike the {@link java.io.Closeable#close close} + * method of {@link java.io.Closeable}, this {@code close} method + * is not required to be idempotent. In other words, + * calling this {@code close} method more than once may have some + * visible side effect, unlike {@code Closeable.close} which is + * required to have no effect if called more than once. + * * @throws Exception if this resource cannot be closed */ void close() throws Exception; diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/java/lang/Throwable.java --- a/jdk/src/share/classes/java/lang/Throwable.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/java/lang/Throwable.java Thu Aug 12 19:55:48 2010 -0700 @@ -28,12 +28,12 @@ import java.util.*; /** - * The Throwable class is the superclass of all errors and + * The {@code Throwable} class is the superclass of all errors and * exceptions in the Java language. Only objects that are instances of this * class (or one of its subclasses) are thrown by the Java Virtual Machine or - * can be thrown by the Java throw statement. Similarly, only + * can be thrown by the Java {@code throw} statement. Similarly, only * this class or one of its subclasses can be the argument type in a - * catch clause. + * {@code catch} clause. * * For the purposes of compile-time checking of exceptions, {@code * Throwable} and any subclass of {@code Throwable} that is not also a @@ -73,11 +73,11 @@ * permit the method to throw the cause directly. For example, suppose * a persistent collection conforms to the {@link java.util.Collection * Collection} interface, and that its persistence is implemented atop - * java.io. Suppose the internals of the add method + * {@code java.io}. Suppose the internals of the {@code add} method * can throw an {@link java.io.IOException IOException}. The implementation - * can communicate the details of the IOException to its caller - * while conforming to the Collection interface by wrapping the - * IOException in an appropriate unchecked exception. (The + * can communicate the details of the {@code IOException} to its caller + * while conforming to the {@code Collection} interface by wrapping the + * {@code IOException} in an appropriate unchecked exception. (The * specification for the persistent collection should indicate that it is * capable of throwing such exceptions.) * @@ -86,7 +86,7 @@ * {@link #initCause(Throwable)} method. New throwable classes that * wish to allow causes to be associated with them should provide constructors * that take a cause and delegate (perhaps indirectly) to one of the - * Throwable constructors that takes a cause. For example: + * {@code Throwable} constructors that takes a cause. For example: *

  *     try {
  *         lowLevelOp();
@@ -94,10 +94,10 @@
  *         throw new HighLevelException(le);  // Chaining-aware constructor
  *     }
  * 
- * Because the initCause method is public, it allows a cause to be + * Because the {@code initCause} method is public, it allows a cause to be * associated with any throwable, even a "legacy throwable" whose * implementation predates the addition of the exception chaining mechanism to - * Throwable. For example: + * {@code Throwable}. For example: *
  *     try {
  *         lowLevelOp();
@@ -121,28 +121,28 @@
  * use the standard exception chaining mechanism, while continuing to
  * implement their "legacy" chaining mechanisms for compatibility.
  *
- * 

Further, as of release 1.4, many general purpose Throwable + *

Further, as of release 1.4, many general purpose {@code Throwable} * classes (for example {@link Exception}, {@link RuntimeException}, * {@link Error}) have been retrofitted with constructors that take * a cause. This was not strictly necessary, due to the existence of the - * initCause method, but it is more convenient and expressive to + * {@code initCause} method, but it is more convenient and expressive to * delegate to a constructor that takes a cause. * - *

By convention, class Throwable and its subclasses have two + *

By convention, class {@code Throwable} and its subclasses have two * constructors, one that takes no arguments and one that takes a - * String argument that can be used to produce a detail message. + * {@code String} argument that can be used to produce a detail message. * Further, those subclasses that might likely have a cause associated with * them should have two more constructors, one that takes a - * Throwable (the cause), and one that takes a - * String (the detail message) and a Throwable (the + * {@code Throwable} (the cause), and one that takes a + * {@code String} (the detail message) and a {@code Throwable} (the * cause). * *

Also introduced in release 1.4 is the {@link #getStackTrace()} method, * which allows programmatic access to the stack trace information that was * previously available only in text form, via the various forms of the * {@link #printStackTrace()} method. This information has been added to the - * serialized representation of this class so getStackTrace - * and printStackTrace will operate properly on a throwable that + * serialized representation of this class so {@code getStackTrace} + * and {@code printStackTrace} will operate properly on a throwable that * was obtained by deserialization. * * @author unascribed @@ -162,7 +162,7 @@ /** * Specific details about the Throwable. For example, for - * FileNotFoundException, this contains the name of + * {@code FileNotFoundException}, this contains the name of * the file that could not be found. * * @serial @@ -212,7 +212,7 @@ private static final String SUPPRESSED_CAPTION = "Suppressed: "; /** - * Constructs a new throwable with null as its detail message. + * Constructs a new throwable with {@code null} as its detail message. * The cause is not initialized, and may subsequently be initialized by a * call to {@link #initCause}. * @@ -242,7 +242,7 @@ /** * Constructs a new throwable with the specified detail message and * cause.

Note that the detail message associated with - * cause is not automatically incorporated in + * {@code cause} is not automatically incorporated in * this throwable's detail message. * *

The {@link #fillInStackTrace()} method is called to initialize @@ -251,7 +251,7 @@ * @param message the detail message (which is saved for later retrieval * by the {@link #getMessage()} method). * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A null value is + * {@link #getCause()} method). (A {@code null} value is * permitted, and indicates that the cause is nonexistent or * unknown.) * @since 1.4 @@ -264,8 +264,8 @@ /** * Constructs a new throwable with the specified cause and a detail - * message of (cause==null ? null : cause.toString()) (which - * typically contains the class and detail message of cause). + * message of {@code (cause==null ? null : cause.toString())} (which + * typically contains the class and detail message of {@code cause}). * This constructor is useful for throwables that are little more than * wrappers for other throwables (for example, {@link * java.security.PrivilegedActionException}). @@ -274,7 +274,7 @@ * the stack trace data in the newly created throwable. * * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A null value is + * {@link #getCause()} method). (A {@code null} value is * permitted, and indicates that the cause is nonexistent or * unknown.) * @since 1.4 @@ -288,8 +288,8 @@ /** * Returns the detail message string of this throwable. * - * @return the detail message string of this Throwable instance - * (which may be null). + * @return the detail message string of this {@code Throwable} instance + * (which may be {@code null}). */ public String getMessage() { return detailMessage; @@ -300,7 +300,7 @@ * Subclasses may override this method in order to produce a * locale-specific message. For subclasses that do not override this * method, the default implementation returns the same result as - * getMessage(). + * {@code getMessage()}. * * @return The localized description of this throwable. * @since JDK1.1 @@ -310,22 +310,22 @@ } /** - * Returns the cause of this throwable or null if the + * Returns the cause of this throwable or {@code null} if the * cause is nonexistent or unknown. (The cause is the throwable that * caused this throwable to get thrown.) * *

This implementation returns the cause that was supplied via one of - * the constructors requiring a Throwable, or that was set after + * the constructors requiring a {@code Throwable}, or that was set after * creation with the {@link #initCause(Throwable)} method. While it is * typically unnecessary to override this method, a subclass can override * it to return a cause set by some other means. This is appropriate for * a "legacy chained throwable" that predates the addition of chained - * exceptions to Throwable. Note that it is not - * necessary to override any of the PrintStackTrace methods, - * all of which invoke the getCause method to determine the + * exceptions to {@code Throwable}. Note that it is not + * necessary to override any of the {@code PrintStackTrace} methods, + * all of which invoke the {@code getCause} method to determine the * cause of a throwable. * - * @return the cause of this throwable or null if the + * @return the cause of this throwable or {@code null} if the * cause is nonexistent or unknown. * @since 1.4 */ @@ -345,11 +345,11 @@ * even once. * * @param cause the cause (which is saved for later retrieval by the - * {@link #getCause()} method). (A null value is + * {@link #getCause()} method). (A {@code null} value is * permitted, and indicates that the cause is nonexistent or * unknown.) - * @return a reference to this Throwable instance. - * @throws IllegalArgumentException if cause is this + * @return a reference to this {@code Throwable} instance. + * @throws IllegalArgumentException if {@code cause} is this * throwable. (A throwable cannot be its own cause.) * @throws IllegalStateException if this throwable was * created with {@link #Throwable(Throwable)} or @@ -375,7 +375,7 @@ *

  • the result of invoking this object's {@link #getLocalizedMessage} * method * - * If getLocalizedMessage returns null, then just + * If {@code getLocalizedMessage} returns {@code null}, then just * the class name is returned. * * @return a string representation of this throwable. @@ -389,8 +389,8 @@ /** * Prints this throwable and its backtrace to the * standard error stream. This method prints a stack trace for this - * Throwable object on the error output stream that is - * the value of the field System.err. The first line of + * {@code Throwable} object on the error output stream that is + * the value of the field {@code System.err}. The first line of * output contains the result of the {@link #toString()} method for * this object. Remaining lines represent data previously recorded by * the method {@link #fillInStackTrace()}. The format of this @@ -435,7 +435,7 @@ * at Junk.c(Junk.java:21) * ... 3 more *
  • - * Note the presence of lines containing the characters "...". + * Note the presence of lines containing the characters {@code "..."}. * These lines indicate that the remainder of the stack trace for this * exception matches the indicated number of frames from the bottom of the * stack trace of the exception that was caused by this exception (the @@ -542,14 +542,17 @@ /** * Prints this throwable and its backtrace to the specified print stream. * - * @param s PrintStream to use for output + * @param s {@code PrintStream} to use for output */ public void printStackTrace(PrintStream s) { printStackTrace(new WrappedPrintStream(s)); } private void printStackTrace(PrintStreamOrWriter s) { - Set dejaVu = new HashSet(); + // Guard against malicious overrides of Throwable.equals by + // using a Set with identity equality semantics. + Set dejaVu = + Collections.newSetFromMap(new IdentityHashMap()); dejaVu.add(this); synchronized (s.lock()) { @@ -616,7 +619,7 @@ * Prints this throwable and its backtrace to the specified * print writer. * - * @param s PrintWriter to use for output + * @param s {@code PrintWriter} to use for output * @since JDK1.1 */ public void printStackTrace(PrintWriter s) { @@ -669,10 +672,10 @@ /** * Fills in the execution stack trace. This method records within this - * Throwable object information about the current state of + * {@code Throwable} object information about the current state of * the stack frames for the current thread. * - * @return a reference to this Throwable instance. + * @return a reference to this {@code Throwable} instance. * @see java.lang.Throwable#printStackTrace() */ public synchronized native Throwable fillInStackTrace(); @@ -694,7 +697,7 @@ * this throwable is permitted to return a zero-length array from this * method. Generally speaking, the array returned by this method will * contain one element for every frame that would be printed by - * printStackTrace. + * {@code printStackTrace}. * * @return an array of stack trace elements representing the stack trace * pertaining to this throwable. @@ -727,14 +730,14 @@ * read from a serialization stream. * * @param stackTrace the stack trace elements to be associated with - * this Throwable. The specified array is copied by this + * this {@code Throwable}. The specified array is copied by this * call; changes in the specified array after the method invocation - * returns will have no affect on this Throwable's stack + * returns will have no affect on this {@code Throwable}'s stack * trace. * - * @throws NullPointerException if stackTrace is - * null, or if any of the elements of - * stackTrace are null + * @throws NullPointerException if {@code stackTrace} is + * {@code null}, or if any of the elements of + * {@code stackTrace} are {@code null} * * @since 1.4 */ @@ -761,8 +764,8 @@ * package-protection for use by SharedSecrets. * * @param index index of the element to return. - * @throws IndexOutOfBoundsException if index < 0 || - * index >= getStackTraceDepth() + * @throws IndexOutOfBoundsException if {@code index < 0 || + * index >= getStackTraceDepth() } */ native StackTraceElement getStackTraceElement(int index); @@ -794,14 +797,27 @@ * were suppressed, typically by the automatic resource management * statement, in order to deliver this exception. * + *

    Note that when one exception {@linkplain + * #initCause(Throwable) causes} another exception, the first + * exception is usually caught and then the second exception is + * thrown in response. In contrast, when one exception suppresses + * another, two exceptions are thrown in sibling code blocks, such + * as in a {@code try} block and in its {@code finally} block, and + * control flow can only continue with one exception so the second + * is recorded as a suppressed exception of the first. + * * @param exception the exception to be added to the list of * suppressed exceptions * @throws NullPointerException if {@code exception} is null + * @throws IllegalArgumentException if {@code exception} is this + * throwable; a throwable cannot suppress itself. * @since 1.7 */ public synchronized void addSuppressedException(Throwable exception) { if (exception == null) throw new NullPointerException(NULL_CAUSE_MESSAGE); + if (exception == this) + throw new IllegalArgumentException("Self-suppression not permitted"); if (suppressedExceptions.size() == 0) suppressedExceptions = new ArrayList(); diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/java/nio/Bits.java --- a/jdk/src/share/classes/java/nio/Bits.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/java/nio/Bits.java Thu Aug 12 19:55:48 2010 -0700 @@ -596,6 +596,9 @@ return pageSize; } + static int pageCount(long size) { + return (int)(size + (long)pageSize() - 1L) / pageSize(); + } private static boolean unaligned; private static boolean unalignedKnown = false; diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/java/nio/MappedByteBuffer.java --- a/jdk/src/share/classes/java/nio/MappedByteBuffer.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/java/nio/MappedByteBuffer.java Thu Aug 12 19:55:48 2010 -0700 @@ -25,6 +25,8 @@ package java.nio; +import sun.misc.Unsafe; + /** * A direct byte buffer whose content is a memory-mapped region of a file. @@ -93,6 +95,22 @@ throw new UnsupportedOperationException(); } + // Returns the distance (in bytes) of the buffer from the page aligned address + // of the mapping. Computed each time to avoid storing in every direct buffer. + private long mappingOffset() { + int ps = Bits.pageSize(); + long offset = address % ps; + return (offset >= 0) ? offset : (ps + offset); + } + + private long mappingAddress(long mappingOffset) { + return address - mappingOffset; + } + + private long mappingLength(long mappingOffset) { + return (long)capacity() + mappingOffset; + } + /** * Tells whether or not this buffer's content is resident in physical * memory. @@ -115,7 +133,9 @@ checkMapped(); if ((address == 0) || (capacity() == 0)) return true; - return isLoaded0(((DirectByteBuffer)this).address(), capacity()); + long offset = mappingOffset(); + long length = mappingLength(offset); + return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length)); } /** @@ -132,7 +152,20 @@ checkMapped(); if ((address == 0) || (capacity() == 0)) return this; - load0(((DirectByteBuffer)this).address(), capacity(), Bits.pageSize()); + long offset = mappingOffset(); + long length = mappingLength(offset); + load0(mappingAddress(offset), length); + + // touch each page + Unsafe unsafe = Unsafe.getUnsafe(); + int ps = Bits.pageSize(); + int count = Bits.pageCount(length); + long a = mappingAddress(offset); + for (int i=0; i * signatureAlgorithm AlgorithmIdentifier

    diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/java/security/cert/X509Certificate.java --- a/jdk/src/share/classes/java/security/cert/X509Certificate.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/java/security/cert/X509Certificate.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -352,7 +352,7 @@ /** * Gets the signature algorithm name for the certificate - * signature algorithm. An example is the string "SHA-1/DSA". + * signature algorithm. An example is the string "SHA256withRSA". * The ASN.1 definition for this is: *

          * signatureAlgorithm   AlgorithmIdentifier

    diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/java/util/LinkedList.java --- a/jdk/src/share/classes/java/util/LinkedList.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/java/util/LinkedList.java Thu Aug 12 19:55:48 2010 -0700 @@ -26,18 +26,9 @@ package java.util; /** - * Linked list implementation of the {@code List} interface. Implements all - * optional list operations, and permits all elements (including - * {@code null}). In addition to implementing the {@code List} interface, - * the {@code LinkedList} class provides uniformly named methods to - * {@code get}, {@code remove} and {@code insert} an element at the - * beginning and end of the list. These operations allow linked lists to be - * used as a stack, {@linkplain Queue queue}, or {@linkplain Deque - * double-ended queue}. - * - *

    The class implements the {@code Deque} interface, providing - * first-in-first-out queue operations for {@code add}, - * {@code poll}, along with other stack and deque operations. + * Linked list implementation of the {@link List} and {@link Deque} interfaces. + * Implements all optional operations, and permits all elements (including + * {@code null}). * *

    All of the operations perform as could be expected for a doubly-linked * list. Operations that index into the list will traverse the list from diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -113,7 +113,6 @@ previewPanelHolder.setBorder(new TitledBorder(previewString)); } previewPanelHolder.setInheritsPopupMenu(true); - chooser.add(previewPanelHolder, BorderLayout.SOUTH); installPreviewPanel(); chooser.applyComponentOrientation(c.getComponentOrientation()); @@ -126,13 +125,9 @@ uninstallDefaultChoosers(); uninstallListeners(); + uninstallPreviewPanel(); uninstallDefaults(); - previewPanelHolder.remove(previewPanel); - if (previewPanel instanceof UIResource) { - chooser.setPreviewPanel(null); - } - previewPanelHolder = null; previewPanel = null; defaultChoosers = null; @@ -143,29 +138,37 @@ } protected void installPreviewPanel() { - if (previewPanel != null) { - previewPanelHolder.remove(previewPanel); - previewPanel.removeMouseListener(getHandler()); + JComponent previewPanel = this.chooser.getPreviewPanel(); + if (previewPanel == null) { + previewPanel = ColorChooserComponentFactory.getPreviewPanel(); } - - previewPanel = chooser.getPreviewPanel(); - Dimension layoutSize = new Dimension(); // fix for bug 4759306 - if (previewPanel != null) { - layoutSize = new BorderLayout().minimumLayoutSize(previewPanel); - if ((previewPanelHolder != null) && (chooser != null) && - (layoutSize.getWidth() + layoutSize.getHeight() == 0)) { - chooser.remove(previewPanelHolder); - return; + else { + Dimension size = new BorderLayout().minimumLayoutSize(previewPanel); + if ((size.width == 0) && (size.height == 0)) { + previewPanel = null; } } - if (previewPanel == null || previewPanel instanceof UIResource) { - previewPanel = ColorChooserComponentFactory.getPreviewPanel(); // get from table? - chooser.setPreviewPanel(previewPanel); + this.previewPanel = previewPanel; + if (previewPanel != null) { + chooser.add(previewPanelHolder, BorderLayout.SOUTH); + previewPanel.setForeground(chooser.getColor()); + previewPanelHolder.add(previewPanel); + previewPanel.addMouseListener(getHandler()); + previewPanel.setInheritsPopupMenu(true); } - previewPanel.setForeground(chooser.getColor()); - previewPanelHolder.add(previewPanel); - previewPanel.addMouseListener(getHandler()); - previewPanel.setInheritsPopupMenu(true); + } + + /** + * Removes installed preview panel from the UI delegate. + * + * @since 1.7 + */ + protected void uninstallPreviewPanel() { + if (this.previewPanel != null) { + this.previewPanel.removeMouseListener(getHandler()); + this.previewPanelHolder.remove(this.previewPanel); + } + this.chooser.remove(this.previewPanelHolder); } protected void installDefaults() { @@ -209,7 +212,6 @@ chooser.removePropertyChangeListener( propertyChangeListener ); chooser.getSelectionModel().removeChangeListener(previewListener); previewListener = null; - previewPanel.removeMouseListener(getHandler()); } private void selectionChanged(ColorSelectionModel model) { @@ -312,9 +314,8 @@ } } else if (prop == JColorChooser.PREVIEW_PANEL_PROPERTY) { - if (evt.getNewValue() != previewPanel) { - installPreviewPanel(); - } + uninstallPreviewPanel(); + installPreviewPanel(); } else if (prop == JColorChooser.SELECTION_MODEL_PROPERTY) { ColorSelectionModel oldModel = (ColorSelectionModel) evt.getOldValue(); @@ -352,5 +353,4 @@ super("color"); } } - } diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Thu Aug 12 19:55:48 2010 -0700 @@ -202,8 +202,8 @@ * Implementation of ComboPopup.show(). */ public void show() { + comboBox.firePopupMenuWillBecomeVisible(); setListSelection(comboBox.getSelectedIndex()); - Point location = getPopupLocation(); show( comboBox, location.x, location.y ); } @@ -344,7 +344,8 @@ protected void firePopupMenuWillBecomeVisible() { super.firePopupMenuWillBecomeVisible(); - comboBox.firePopupMenuWillBecomeVisible(); + // comboBox.firePopupMenuWillBecomeVisible() is called from BasicComboPopup.show() method + // to let the user change the popup menu from the PopupMenuListener.popupMenuWillBecomeVisible() } protected void firePopupMenuWillBecomeInvisible() { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/javax/swing/text/DefaultFormatter.java --- a/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/text/DefaultFormatter.java Thu Aug 12 19:55:48 2010 -0700 @@ -570,7 +570,9 @@ direction = -1; } - if (getOverwriteMode() && rh.text != null) { + if (getOverwriteMode() && rh.text != null && + getFormattedTextField().getSelectedText() == null) + { rh.length = Math.min(Math.max(rh.length, rh.text.length()), rh.fb.getDocument().getLength() - rh.offset); } diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/javax/swing/text/InternationalFormatter.java --- a/jdk/src/share/classes/javax/swing/text/InternationalFormatter.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/javax/swing/text/InternationalFormatter.java Thu Aug 12 19:55:48 2010 -0700 @@ -622,18 +622,8 @@ /** * Overriden in an attempt to honor the literals. - *

    - * If we do - * not allow invalid values and are in overwrite mode, this does the - * following for each character in the replacement range: - *

      - *
    1. If the character is a literal, add it to the string to replace - * with. If there is text to insert and it doesn't match the - * literal, then insert the literal in the the middle of the insert - * text. This allows you to either paste in literals or not and - * get the same behavior. - *
    2. If there is no text to insert, replace it with ' '. - *
    + *

    If we do not allow invalid values and are in overwrite mode, this + * {@code rh.length} is corrected as to preserve trailing literals. * If not in overwrite mode, and there is text to insert it is * inserted at the next non literal index going forward. If there * is only text to remove, it is removed from the next non literal @@ -643,61 +633,27 @@ if (!getAllowsInvalid()) { String text = rh.text; int tl = (text != null) ? text.length() : 0; + JTextComponent c = getFormattedTextField(); - if (tl == 0 && rh.length == 1 && getFormattedTextField(). - getSelectionStart() != rh.offset) { + if (tl == 0 && rh.length == 1 && c.getSelectionStart() != rh.offset) { // Backspace, adjust to actually delete next non-literal. rh.offset = getNextNonliteralIndex(rh.offset, -1); - } - if (getOverwriteMode()) { - StringBuffer replace = null; + } else if (getOverwriteMode()) { + int pos = rh.offset; + int textPos = pos; + boolean overflown = false; - for (int counter = 0, textIndex = 0, - max = Math.max(tl, rh.length); counter < max; - counter++) { - if (isLiteral(rh.offset + counter)) { - if (replace != null) { - replace.append(getLiteral(rh.offset + - counter)); - } - if (textIndex < tl && text.charAt(textIndex) == - getLiteral(rh.offset + counter)) { - textIndex++; - } - else if (textIndex == 0) { - rh.offset++; - rh.length--; - counter--; - max--; - } - else if (replace == null) { - replace = new StringBuffer(max); - replace.append(text.substring(0, textIndex)); - replace.append(getLiteral(rh.offset + - counter)); - } + for (int i = 0; i < rh.length; i++) { + while (isLiteral(pos)) pos++; + if (pos >= string.length()) { + pos = textPos; + overflown = true; + break; } - else if (textIndex < tl) { - if (replace != null) { - replace.append(text.charAt(textIndex)); - } - textIndex++; - } - else { - // Nothing to replace it with, assume ' ' - if (replace == null) { - replace = new StringBuffer(max); - if (textIndex > 0) { - replace.append(text.substring(0, textIndex)); - } - } - if (replace != null) { - replace.append(' '); - } - } + textPos = ++pos; } - if (replace != null) { - rh.text = replace.toString(); + if (overflown || c.getSelectedText() == null) { + rh.length = pos - rh.offset; } } else if (tl > 0) { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/net/dns/ResolverConfiguration.java --- a/jdk/src/share/classes/sun/net/dns/ResolverConfiguration.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/net/dns/ResolverConfiguration.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, 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 @@ -26,7 +26,6 @@ package sun.net.dns; import java.util.List; -import java.io.IOException; /** * The configuration of the client resolver. @@ -68,7 +67,7 @@ * * @return list of domain names */ - public abstract List searchlist(); + public abstract List searchlist(); /** * Returns a list of name servers used for host name lookup. @@ -78,7 +77,7 @@ * * @return list of the name servers */ - public abstract List nameservers(); + public abstract List nameservers(); /** diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java --- a/jdk/src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/net/spi/nameservice/dns/DNSNameService.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, 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 @@ -45,20 +45,21 @@ public final class DNSNameService implements NameService { // List of domains specified by property - private LinkedList domainList = null; + private LinkedList domainList = null; // JNDI-DNS URL for name servers specified via property private String nameProviderUrl = null; // Per-thread soft cache of the last temporary context - private static ThreadLocal contextRef = new ThreadLocal(); + private static ThreadLocal> contextRef = + new ThreadLocal<>(); // Simple class to encapsulate the temporary context private static class ThreadContext { private DirContext dirCtxt; - private List nsList; + private List nsList; - public ThreadContext(DirContext dirCtxt, List nsList) { + public ThreadContext(DirContext dirCtxt, List nsList) { this.dirCtxt = dirCtxt; this.nsList = nsList; } @@ -67,16 +68,16 @@ return dirCtxt; } - public List nameservers() { + public List nameservers() { return nsList; } } // Returns a per-thread DirContext private DirContext getTemporaryContext() throws NamingException { - SoftReference ref = (SoftReference)contextRef.get(); + SoftReference ref = contextRef.get(); ThreadContext thrCtxt = null; - List nsList = null; + List nsList = null; // if no property specified we need to obtain the list of servers // @@ -87,7 +88,7 @@ // specified then we need to check if the DNS configuration // has changed. // - if ((ref != null) && ((thrCtxt = (ThreadContext)ref.get()) != null)) { + if ((ref != null) && ((thrCtxt = ref.get()) != null)) { if (nameProviderUrl == null) { if (!thrCtxt.nameservers().equals(nsList)) { // DNS configuration has changed @@ -98,7 +99,7 @@ // new thread context needs to be created if (thrCtxt == null) { - final Hashtable env = new Hashtable(); + final Hashtable env = new Hashtable<>(); env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); @@ -119,10 +120,9 @@ // DirContext dirCtxt; try { - dirCtxt = (DirContext) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws NamingException { + dirCtxt = java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public DirContext run() throws NamingException { // Create the DNS context using NamingManager rather than using // the initial context constructor. This avoids having the initial // context constructor call itself. @@ -130,7 +130,7 @@ if (!(ctx instanceof DirContext)) { return null; // cannot create a DNS context } - return ctx; + return (DirContext)ctx; } }); } catch (java.security.PrivilegedActionException pae) { @@ -161,18 +161,18 @@ * * @throws UnknownHostException if lookup fails or other error. */ - private ArrayList resolve(final DirContext ctx, final String name, final String[] ids, - int depth) throws UnknownHostException + private ArrayList resolve(final DirContext ctx, final String name, + final String[] ids, int depth) + throws UnknownHostException { - ArrayList results = new ArrayList(); + ArrayList results = new ArrayList<>(); Attributes attrs; // do the query try { - attrs = (Attributes) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws NamingException { + attrs = java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public Attributes run() throws NamingException { return ctx.getAttributes(name, ids); } }); @@ -181,7 +181,7 @@ } // non-requested type returned so enumeration is empty - NamingEnumeration ne = attrs.getAll(); + NamingEnumeration ne = attrs.getAll(); if (!ne.hasMoreElements()) { throw new UnknownHostException("DNS record not found"); } @@ -190,7 +190,7 @@ UnknownHostException uhe = null; try { while (ne.hasMoreElements()) { - Attribute attr = (Attribute)ne.next(); + Attribute attr = ne.next(); String attrID = attr.getID(); for (NamingEnumeration e = attr.getAll(); e.hasMoreElements();) { @@ -251,13 +251,12 @@ // no property specified so check host DNS resolver configured // with at least one nameserver in dotted notation. // - List nsList = ResolverConfiguration.open().nameservers(); - if (nsList.size() == 0) + List nsList = ResolverConfiguration.open().nameservers(); + if (nsList.isEmpty()) { throw new RuntimeException("no nameservers provided"); + } boolean found = false; - Iterator i = nsList.iterator(); - while (i.hasNext()) { - String addr = (String)i.next(); + for (String addr: nsList) { if (IPAddressUtil.isIPv4LiteralAddress(addr) || IPAddressUtil.isIPv6LiteralAddress(addr)) { found = true; @@ -308,8 +307,8 @@ // suffix if the list has one entry. if (results == null) { - List searchList = null; - Iterator i; + List searchList = null; + Iterator i; boolean usingSearchList = false; if (domainList != null) { @@ -324,7 +323,7 @@ // iterator through each domain suffix while (i.hasNext()) { - String parentDomain = (String)i.next(); + String parentDomain = i.next(); int start = 0; while ((start = parentDomain.indexOf(".")) != -1 && start < parentDomain.length() -1) { @@ -407,7 +406,7 @@ String literalip = ""; String[] ids = { "PTR" }; DirContext ctx; - ArrayList results = null; + ArrayList results = null; try { ctx = getTemporaryContext(); } catch (NamingException nx) { @@ -420,7 +419,7 @@ literalip += "IN-ADDR.ARPA."; results = resolve(ctx, literalip, ids, 0); - host = (String)results.get(0); + host = results.get(0); } else if (addr.length == 16) { // IPv6 Address /** * Because RFC 3152 changed the root domain name for reverse @@ -437,7 +436,7 @@ try { results = resolve(ctx, ip6lit, ids, 0); - host = (String)results.get(0); + host = results.get(0); } catch (UnknownHostException e) { host = null; } @@ -445,7 +444,7 @@ // IP6.ARPA lookup failed, let's try the older IP6.INT ip6lit = literalip + "IP6.INT."; results = resolve(ctx, ip6lit, ids, 0); - host = (String)results.get(0); + host = results.get(0); } } } catch (Exception e) { @@ -478,11 +477,10 @@ * @return String containing the JNDI-DNS provider URL * corresponding to the supplied List of nameservers. */ - private static String createProviderURL(List nsList) { - Iterator i = nsList.iterator(); + private static String createProviderURL(List nsList) { StringBuffer sb = new StringBuffer(); - while (i.hasNext()) { - appendIfLiteralAddress((String)i.next(), sb); + for (String s: nsList) { + appendIfLiteralAddress(s, sb); } return sb.toString(); } diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java --- a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java Thu Aug 12 19:55:48 2010 -0700 @@ -336,7 +336,12 @@ } public void sendUrgentData(int data) throws IOException { - throw new SocketException("Urgent data not supported"); + synchronized (sc.blockingLock()) { + if (!sc.isBlocking()) + throw new IllegalBlockingModeException(); + int n = sc.sendOutOfBandData((byte)data); + assert n == 1; + } } public void setOOBInline(boolean on) throws SocketException { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java --- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Aug 12 19:55:48 2010 -0700 @@ -498,6 +498,36 @@ return write0(Util.subsequence(srcs, offset, length)); } + // package-private + int sendOutOfBandData(byte b) throws IOException { + synchronized (writeLock) { + ensureWriteOpen(); + int n = 0; + try { + begin(); + synchronized (stateLock) { + if (!isOpen()) + return 0; + writerThread = NativeThread.current(); + } + for (;;) { + n = sendOutOfBandData(fd, b); + if ((n == IOStatus.INTERRUPTED) && isOpen()) + continue; + return IOStatus.normalize(n); + } + } finally { + writerCleanup(); + end((n > 0) || (n == IOStatus.UNAVAILABLE)); + synchronized (stateLock) { + if ((n <= 0) && (!isOutputOpen)) + throw new AsynchronousCloseException(); + } + assert IOStatus.check(n); + } + } + } + protected void implConfigureBlocking(boolean block) throws IOException { IOUtil.configureBlocking(fd, block); } @@ -957,6 +987,9 @@ boolean block, boolean ready) throws IOException; + private static native int sendOutOfBandData(FileDescriptor fd, byte data) + throws IOException; + static { Util.load(); nd = new SocketDispatcher(); diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/krb5/Config.java --- a/jdk/src/share/classes/sun/security/krb5/Config.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/krb5/Config.java Thu Aug 12 19:55:48 2010 -0700 @@ -42,6 +42,8 @@ import java.util.StringTokenizer; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.List; +import sun.net.dns.ResolverConfiguration; import sun.security.krb5.internal.crypto.EType; import sun.security.krb5.internal.ktab.*; import sun.security.krb5.internal.Krb5; @@ -1180,6 +1182,33 @@ } // get the domain realm mapping from the configuration String mapRealm = PrincipalName.mapHostToRealm(hostName); + if (mapRealm == null) { + // No match. Try search and/or domain in /etc/resolv.conf + List srchlist = ResolverConfiguration.open().searchlist(); + for (String domain: srchlist) { + realm = checkRealm(domain); + if (realm != null) { + break; + } + } + } else { + realm = checkRealm(mapRealm); + } + if (realm == null) { + throw new KrbException(Krb5.KRB_ERR_GENERIC, + "Unable to locate Kerberos realm"); + } + return realm; + } + + /** + * Check if the provided realm is the correct realm + * @return the realm if correct, or null otherwise + */ + private static String checkRealm(String mapRealm) { + if (DEBUG) { + System.out.println("getRealmFromDNS: trying " + mapRealm); + } String[] records = null; String newRealm = mapRealm; while ((records == null) && (newRealm != null)) { @@ -1188,23 +1217,14 @@ newRealm = Realm.parseRealmComponent(newRealm); // if no DNS TXT records found, try again using sub-realm } - if (records == null) { - // no DNS TXT records - throw new KrbException(Krb5.KRB_ERR_GENERIC, - "Unable to locate Kerberos realm"); - } - boolean found = false; - for (int i = 0; i < records.length; i++) { - if (records[i].equals(mapRealm)) { - found = true; - realm = records[i]; + if (records != null) { + for (int i = 0; i < records.length; i++) { + if (records[i].equalsIgnoreCase(mapRealm)) { + return records[i]; + } } } - if (found == false) { - throw new KrbException(Krb5.KRB_ERR_GENERIC, - "Unable to locate Kerberos realm"); - } - return realm; + return null; } /** @@ -1218,10 +1238,16 @@ String kdcs = null; String[] srvs = null; // locate DNS SRV record using UDP - srvs = KrbServiceLocator.getKerberosService(realm, "_udp."); + if (DEBUG) { + System.out.println("getKDCFromDNS using UDP"); + } + srvs = KrbServiceLocator.getKerberosService(realm, "_udp"); if (srvs == null) { // locate DNS SRV record using TCP - srvs = KrbServiceLocator.getKerberosService(realm, "_tcp."); + if (DEBUG) { + System.out.println("getKDCFromDNS using UDP"); + } + srvs = KrbServiceLocator.getKerberosService(realm, "_tcp"); } if (srvs == null) { // no DNS SRV records diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/krb5/Credentials.java --- a/jdk/src/share/classes/sun/security/krb5/Credentials.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java Thu Aug 12 19:55:48 2010 -0700 @@ -36,6 +36,7 @@ import sun.security.krb5.internal.crypto.EType; import java.io.IOException; import java.util.Date; +import java.util.Locale; import java.net.InetAddress; /** @@ -287,7 +288,7 @@ // The default ticket cache on Windows is not a file. String os = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("os.name")); - if (os.toUpperCase().startsWith("WINDOWS")) { + if (os.toUpperCase(Locale.ENGLISH).startsWith("WINDOWS")) { Credentials creds = acquireDefaultCreds(); if (creds == null) { if (DEBUG) { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/pkcs/PKCS9Attribute.java --- a/jdk/src/share/classes/sun/security/pkcs/PKCS9Attribute.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS9Attribute.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -28,6 +28,7 @@ import java.io.IOException; import java.io.OutputStream; import java.security.cert.CertificateException; +import java.util.Locale; import java.util.Date; import java.util.Hashtable; import sun.security.x509.CertificateExtensions; @@ -742,7 +743,7 @@ * the name. */ public static ObjectIdentifier getOID(String name) { - return NAME_OID_TABLE.get(name.toLowerCase()); + return NAME_OID_TABLE.get(name.toLowerCase(Locale.ENGLISH)); } /** diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Thu Aug 12 19:55:48 2010 -0700 @@ -26,6 +26,7 @@ import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.Locale; import java.security.*; import java.security.spec.*; @@ -201,7 +202,7 @@ } private int parseMode(String mode) throws NoSuchAlgorithmException { - mode = mode.toUpperCase(); + mode = mode.toUpperCase(Locale.ENGLISH); int result; if (mode.equals("ECB")) { result = MODE_ECB; @@ -222,7 +223,7 @@ throws NoSuchPaddingException { paddingObj = null; padBuffer = null; - padding = padding.toUpperCase(); + padding = padding.toUpperCase(Locale.ENGLISH); if (padding.equals("NOPADDING")) { paddingType = PAD_NONE; } else if (padding.equals("PKCS5PADDING")) { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Thu Aug 12 19:55:48 2010 -0700 @@ -29,6 +29,8 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.*; +import java.util.Locale; + import javax.crypto.*; import javax.crypto.spec.*; @@ -110,7 +112,7 @@ protected void engineSetPadding(String padding) throws NoSuchPaddingException { - String lowerPadding = padding.toLowerCase(); + String lowerPadding = padding.toLowerCase(Locale.ENGLISH); if (lowerPadding.equals("pkcs1Padding")) { // empty } else { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java --- a/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2010 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 @@ -52,6 +52,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Locale; import sun.security.x509.AccessDescription; import sun.security.x509.GeneralNameInterface; import sun.security.x509.URIName; @@ -162,7 +163,7 @@ } this.uri = ((URICertStoreParameters) params).uri; // if ldap URI, use an LDAPCertStore to fetch certs and CRLs - if (uri.getScheme().toLowerCase().equals("ldap")) { + if (uri.getScheme().toLowerCase(Locale.ENGLISH).equals("ldap")) { if (LDAP.helper() == null) throw new NoSuchAlgorithmException("LDAP not present"); ldap = true; diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/util/Debug.java --- a/jdk/src/share/classes/sun/security/util/Debug.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/util/Debug.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, 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 @@ -28,6 +28,7 @@ import java.math.BigInteger; import java.util.regex.Pattern; import java.util.regex.Matcher; +import java.util.Locale; /** * A utility class for debuging. @@ -262,7 +263,7 @@ source = left; // convert the rest to lower-case characters - target.append(source.toString().toLowerCase()); + target.append(source.toString().toLowerCase(Locale.ENGLISH)); return target.toString(); } diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/util/DerOutputStream.java --- a/jdk/src/share/classes/sun/security/util/DerOutputStream.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/util/DerOutputStream.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -25,17 +25,16 @@ package sun.security.util; -import java.io.FilterOutputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; -import java.util.Vector; import java.util.Comparator; import java.util.Arrays; import java.math.BigInteger; +import java.util.Locale; /** @@ -501,7 +500,7 @@ pattern = "yyyyMMddHHmmss'Z'"; } - SimpleDateFormat sdf = new SimpleDateFormat(pattern); + SimpleDateFormat sdf = new SimpleDateFormat(pattern, Locale.US); sdf.setTimeZone(tz); byte[] time = (sdf.format(d)).getBytes("ISO-8859-1"); diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/x509/AVA.java --- a/jdk/src/share/classes/sun/security/x509/AVA.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/x509/AVA.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -1227,7 +1227,7 @@ (String keyword, int standard, Map extraKeywordMap) throws IOException { - keyword = keyword.toUpperCase(); + keyword = keyword.toUpperCase(Locale.ENGLISH); if (standard == AVA.RFC2253) { if (keyword.startsWith(" ") || keyword.endsWith(" ")) { throw new IOException("Invalid leading or trailing space " + diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/x509/AlgorithmId.java --- a/jdk/src/share/classes/sun/security/x509/AlgorithmId.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/x509/AlgorithmId.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2010, 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 @@ -553,9 +553,10 @@ for (Enumeration enum_ = provs[i].keys(); enum_.hasMoreElements(); ) { String alias = (String)enum_.nextElement(); + String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH); int index; - if (alias.toUpperCase().startsWith("ALG.ALIAS") && - (index=alias.toUpperCase().indexOf("OID.", 0)) != -1) { + if (upperCaseAlias.startsWith("ALG.ALIAS") && + (index=upperCaseAlias.indexOf("OID.", 0)) != -1) { index += "OID.".length(); if (index == alias.length()) { // invalid alias entry @@ -565,19 +566,26 @@ oidTable = new HashMap(); } oidString = alias.substring(index); - String stdAlgName - = provs[i].getProperty(alias).toUpperCase(); - if (oidTable.get(stdAlgName) == null) { + String stdAlgName = provs[i].getProperty(alias); + if (stdAlgName != null) { + stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); + } + if (stdAlgName != null && + oidTable.get(stdAlgName) == null) { oidTable.put(stdAlgName, new ObjectIdentifier(oidString)); } } } } + + if (oidTable == null) { + oidTable = new HashMap(1); + } initOidTable = true; } - return oidTable.get(name.toUpperCase()); + return oidTable.get(name.toUpperCase(Locale.ENGLISH)); } private static ObjectIdentifier oid(int ... values) { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/x509/DNSName.java --- a/jdk/src/share/classes/sun/security/x509/DNSName.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/x509/DNSName.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -26,6 +26,7 @@ package sun.security.x509; import java.io.IOException; +import java.util.Locale; import sun.security.util.*; @@ -198,8 +199,9 @@ else if (inputName.getType() != NAME_DNS) constraintType = NAME_DIFF_TYPE; else { - String inName = (((DNSName)inputName).getName()).toLowerCase(); - String thisName = name.toLowerCase(); + String inName = + (((DNSName)inputName).getName()).toLowerCase(Locale.ENGLISH); + String thisName = name.toLowerCase(Locale.ENGLISH); if (inName.equals(thisName)) constraintType = NAME_MATCH; else if (thisName.endsWith(inName)) { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/share/classes/sun/security/x509/RFC822Name.java --- a/jdk/src/share/classes/sun/security/x509/RFC822Name.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/share/classes/sun/security/x509/RFC822Name.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2010, 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 @@ -26,6 +26,7 @@ package sun.security.x509; import java.io.IOException; +import java.util.Locale; import sun.security.util.*; @@ -187,8 +188,9 @@ constraintType = NAME_DIFF_TYPE; } else { //RFC2459 specifies that case is not significant in RFC822Names - String inName = (((RFC822Name)inputName).getName()).toLowerCase(); - String thisName = name.toLowerCase(); + String inName = + (((RFC822Name)inputName).getName()).toLowerCase(Locale.ENGLISH); + String thisName = name.toLowerCase(Locale.ENGLISH); if (inName.equals(thisName)) { constraintType = NAME_MATCH; } else if (thisName.endsWith(inName)) { diff -r 96a57de47def -r 67584b95a0f0 jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java --- a/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/solaris/classes/sun/net/dns/ResolverConfigurationImpl.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, 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 @@ -56,8 +56,11 @@ // Parse /etc/resolv.conf to get the values for a particular // keyword. // - private LinkedList resolvconf(String keyword, int maxperkeyword, int maxkeywords) { - LinkedList ll = new LinkedList(); + private LinkedList resolvconf(String keyword, + int maxperkeyword, + int maxkeywords) + { + LinkedList ll = new LinkedList<>(); try { BufferedReader in = @@ -99,8 +102,8 @@ return ll; } - private LinkedList searchlist; - private LinkedList nameservers; + private LinkedList searchlist; + private LinkedList nameservers; // Load DNS configuration from OS @@ -118,9 +121,9 @@ // get the name servers from /etc/resolv.conf nameservers = - (LinkedList)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction>() { + public LinkedList run() { // typically MAXNS is 3 but we've picked 5 here // to allow for additional servers if required. return resolvconf("nameserver", 1, 5); @@ -137,15 +140,15 @@ // obtain search list or local domain - private LinkedList getSearchList() { + private LinkedList getSearchList() { - LinkedList sl; + LinkedList sl; // first try the search keyword in /etc/resolv.conf - sl = (LinkedList)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + sl = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction>() { + public LinkedList run() { LinkedList ll; // first try search keyword (max 6 domains) @@ -177,10 +180,10 @@ // try domain keyword in /etc/resolv.conf - sl = (LinkedList)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - LinkedList ll; + sl = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction>() { + public LinkedList run() { + LinkedList ll; ll = resolvconf("domain", 1, 1); if (ll.size() > 0) { @@ -197,7 +200,7 @@ // no local domain so try fallback (RPC) domain or // hostname - sl = new LinkedList(); + sl = new LinkedList<>(); String domain = fallbackDomain0(); if (domain != null && domain.length() > 0) { sl.add(domain); @@ -213,7 +216,7 @@ opts = new OptionsImpl(); } - public List searchlist() { + public List searchlist() { synchronized (lock) { loadConfig(); @@ -222,7 +225,7 @@ } } - public List nameservers() { + public List nameservers() { synchronized (lock) { loadConfig(); diff -r 96a57de47def -r 67584b95a0f0 jdk/src/solaris/native/java/net/NetworkInterface.c --- a/jdk/src/solaris/native/java/net/NetworkInterface.c Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/solaris/native/java/net/NetworkInterface.c Thu Aug 12 19:55:48 2010 -0700 @@ -131,7 +131,7 @@ static short getSubnet(JNIEnv *env, int sock, const char *ifname); static int getIndex(int sock, const char *ifname); -static int getFlags(JNIEnv *env, int sock, const char *ifname); +static int getFlags(int sock, const char *ifname); static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf); static int getMTU(JNIEnv *env, int sock, const char *ifname); @@ -550,7 +550,7 @@ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy); - ret = getFlags(env, sock, name_utf); + ret = getFlags(sock, name_utf); close(sock); (*env)->ReleaseStringUTFChars(env, name, name_utf); @@ -753,19 +753,27 @@ * If IPv6 is available then enumerate IPv6 addresses. */ #ifdef AF_INET6 - sock = openSocket(env, AF_INET6); - if (sock < 0 && (*env)->ExceptionOccurred(env)) { - freeif(ifs); - return NULL; - } + + /* User can disable ipv6 expicitly by -Djava.net.preferIPv4Stack=true, + * so we have to call ipv6_available() + */ + if (ipv6_available()) { - ifs = enumIPv6Interfaces(env, sock, ifs); - close(sock); + sock = openSocket(env, AF_INET6); + if (sock < 0 && (*env)->ExceptionOccurred(env)) { + freeif(ifs); + return NULL; + } - if ((*env)->ExceptionOccurred(env)) { - freeif(ifs); - return NULL; - } + ifs = enumIPv6Interfaces(env, sock, ifs); + close(sock); + + if ((*env)->ExceptionOccurred(env)) { + freeif(ifs); + return NULL; + } + + } #endif return ifs; @@ -877,7 +885,7 @@ * the 'parent' interface with the new records. */ *name_colonP = 0; - if (getFlags(env,sock,name) < 0) { + if (getFlags(sock, name) < 0) { // failed to access parent interface do not create parent. // We are a virtual interface with no parent. isVirtual = 1; @@ -1249,7 +1257,7 @@ return if2.ifr_mtu; } -static int getFlags(JNIEnv *env, int sock, const char *ifname) { +static int getFlags(int sock, const char *ifname) { struct ifreq if2; int ret = -1; @@ -1625,13 +1633,12 @@ } -static int getFlags(JNIEnv *env, int sock, const char *ifname) { +static int getFlags(int sock, const char *ifname) { struct lifreq lifr; memset((caddr_t)&lifr, 0, sizeof(lifr)); strcpy((caddr_t)&(lifr.lifr_name), ifname); if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) < 0) { - NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFFLAGS failed"); return -1; } diff -r 96a57de47def -r 67584b95a0f0 jdk/src/solaris/native/java/nio/MappedByteBuffer.c --- a/jdk/src/solaris/native/java/nio/MappedByteBuffer.c Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/solaris/native/java/nio/MappedByteBuffer.c Thu Aug 12 19:55:48 2010 -0700 @@ -32,14 +32,11 @@ #include #include - JNIEXPORT jboolean JNICALL -Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, - jlong address, jlong len) +Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address, + jlong len, jint numPages) { jboolean loaded = JNI_TRUE; - jint pageSize = sysconf(_SC_PAGESIZE); - jint numPages = (len + pageSize - 1) / pageSize; int result = 0; int i = 0; void *a = (void *) jlong_to_ptr(address); @@ -55,9 +52,9 @@ } result = mincore(a, (size_t)len, vec); - if (result != 0) { + if (result == -1) { + JNU_ThrowIOExceptionWithLastError(env, "mincore failed"); free(vec); - JNU_ThrowIOExceptionWithLastError(env, "mincore failed"); return JNI_FALSE; } @@ -72,23 +69,15 @@ } -JNIEXPORT jint JNICALL +JNIEXPORT void JNICALL Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address, - jlong len, jint pageSize) + jlong len) { - int pageIncrement = pageSize / sizeof(int); - int numPages = (len + pageSize - 1) / pageSize; - int *ptr = (int *)jlong_to_ptr(address); - int i = 0; - int j = 0; - int result = madvise((caddr_t)ptr, len, MADV_WILLNEED); - - /* touch every page */ - for (i=0; i stringToList(String str) { + LinkedList ll = new LinkedList<>(); // comma and space are valid delimites StringTokenizer st = new StringTokenizer(str, ", "); @@ -112,7 +111,7 @@ opts = new OptionsImpl(); } - public List searchlist() { + public List searchlist() { synchronized (lock) { loadConfig(); @@ -121,7 +120,7 @@ } } - public List nameservers() { + public List nameservers() { synchronized (lock) { loadConfig(); diff -r 96a57de47def -r 67584b95a0f0 jdk/src/windows/native/java/nio/MappedByteBuffer.c --- a/jdk/src/windows/native/java/nio/MappedByteBuffer.c Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/src/windows/native/java/nio/MappedByteBuffer.c Thu Aug 12 19:55:48 2010 -0700 @@ -31,8 +31,8 @@ #include JNIEXPORT jboolean JNICALL -Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, - jlong address, jlong len) +Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address, + jlong len, jint numPages) { jboolean loaded = JNI_FALSE; /* Information not available? @@ -43,22 +43,11 @@ return loaded; } -JNIEXPORT jint JNICALL +JNIEXPORT void JNICALL Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address, - jlong len, jint pageSize) + jlong len) { - int *ptr = (int *) jlong_to_ptr(address); - int pageIncrement = pageSize / sizeof(int); - jlong numPages = (len + pageSize - 1) / pageSize; - int i = 0; - int j = 0; - - /* touch every page */ - for (i=0; iGetStringLength(text); + if (0 == m_dwSize) { + m_pStr = NULL; } else { - m_dwSize = env->GetStringLength(text); m_pStr = (LPWSTR)safe_Malloc( (m_dwSize+1)*sizeof(WCHAR) ); env->GetStringRegion(text, 0, m_dwSize, reinterpret_cast(m_pStr)); m_pStr[m_dwSize] = 0; @@ -341,12 +349,16 @@ void Resize(jsize cbTCharCount) { m_dwSize = cbTCharCount; + //It is ok to have non-null terminated string here. + //The function is used only for space reservation in staff buffer for + //followed data copying process. And that is the reason why we ignore + //the special case m_dwSize==0 here. m_pStr = (LPWSTR)safe_Realloc(m_pStr, (m_dwSize+1)*sizeof(WCHAR) ); } //we are in UNICODE now, so LPWSTR:=:LPTSTR - operator LPWSTR() { return m_pStr; } - operator LPARAM() { return (LPARAM)m_pStr; } - void *GetData() { return (void *)m_pStr; } + operator LPWSTR() { return getNonEmptyString(); } + operator LPARAM() { return (LPARAM)getNonEmptyString(); } + void *GetData() { return (void *)getNonEmptyString(); } jsize GetSize() { return m_dwSize; } }; diff -r 96a57de47def -r 67584b95a0f0 jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/ProblemList.txt Thu Aug 12 19:55:48 2010 -0700 @@ -366,139 +366,6 @@ # jdk_net -# Suspect many of these tests auffer from using fixed ports, no concrete -# evidence. - -# Times out on Windows X64 -sun/net/www/http/KeepAliveStream/KeepAliveStreamCloseWithWrongContentLength.java generic-all - -# Dies on Solaris 10 sparc and sparcv9, Linux -ea -esa with -# Interrupted or IO exception, maybe writing to non-unique named file? -com/sun/net/httpserver/bugs/B6373555.java generic-all - -# Fails on OpenSolaris, times out -java/net/MulticastSocket/SetOutgoingIf.java generic-all - -# Timed out on Solaris 10 X86. -com/sun/net/httpserver/Test3.java generic-all - -# Exception in test on windows -com/sun/net/httpserver/bugs/B6373555.java windows-all - -# One of these pollutes the samevm on Linux, too many open files, kills jtreg -com/sun/net/httpserver/bugs/B6339483.java generic-all -com/sun/net/httpserver/bugs/B6341616.java generic-all - -# Suspects in cascading samevm problem, solaris 11 i586 (needs othervm?) -# Suspect use of setHttps*()? -com/sun/net/httpserver/SelCacheTest.java generic-all -com/sun/net/httpserver/Test1.java generic-all -com/sun/net/httpserver/Test12.java generic-all -com/sun/net/httpserver/Test13.java generic-all -com/sun/net/httpserver/Test6a.java generic-all -com/sun/net/httpserver/Test7a.java generic-all -com/sun/net/httpserver/Test8a.java generic-all -com/sun/net/httpserver/Test9.java generic-all -com/sun/net/httpserver/Test9a.java generic-all - -# 10,000 connections, fails on Linux and makes tests&jtreg fail with samevm -com/sun/net/httpserver/bugs/B6361557.java generic-all - -# Address already in use with samevm? Always? Solaris sparc, probably ports -java/net/Authenticator/B4933582.sh generic-all -java/net/DatagramSocket/SendSize.java generic-all - -# Solaris 11: exception wrong address??? -java/net/Inet6Address/B6558853.java generic-all - -# Not closing stream on file i6a1, windows samevm problem -java/net/Inet6Address/serialize/Serialize.java generic-all - -# Linux x64 fails "network unreachable"? -java/net/ipv6tests/TcpTest.java generic-all - -# Linux i586, fails with unexpected output -java/net/MulticastSocket/NoLoopbackPackets.java linux-i586 - -# Address already in use -java/net/DatagramSocket/DatagramTimeout.java generic-all - -# Fails on windows, takes too long and fails -# Solaris 10 sparcv9, samevm, java.lang.Exception: Takes too long. Dead lock -java/net/Socket/DeadlockTest.java generic-all - -# Linux i586 address already in use or connection error, samevm issues -java/net/Socket/AccurateTimeout.java generic-all -java/net/Socket/asyncClose/BrokenPipe.java generic-all -java/net/Socket/CloseAvailable.java generic-all - -# Linux X64 address already in use, samevm issues -java/net/Socket/LingerTest.java generic-all -java/net/Socket/LinkLocal.java generic-all -java/net/Socket/NullHost.java generic-all -java/net/Socket/ProxyCons.java generic-all -java/net/Socket/ReadTimeout.java generic-all - -# Linux X64 address already in use, samevm issues -java/net/Socket/SetReceiveBufferSize.java generic-all - -# Linux i586 address already in use or connection error, samevm issues -java/net/Socket/setReuseAddress/Basic.java generic-all -java/net/Socket/setReuseAddress/Restart.java generic-all - -# Linux X64 address already in use, samevm issues -java/net/Socket/SetSoLinger.java generic-all - -# Address already in use, windows samevm -java/net/Socket/Timeout.java generic-all - -# Linux X64 address already in use, samevm issues -java/net/Socket/ShutdownBoth.java generic-all -java/net/Socket/SoTimeout.java generic-all -java/net/Socket/TestClose.java generic-all -java/net/Socket/UrgentDataTest.java generic-all -java/net/SocketInputStream/SocketClosedException.java generic-all -java/net/SocketInputStream/SocketTimeout.java generic-all - -# Linux i586, address already in use or timeout, samevm issues -java/net/URLConnection/DisconnectAfterEOF.java generic-all -java/net/URLConnection/HandleContentTypeWithAttrs.java generic-all -java/net/URLConnection/Responses.java generic-all -java/net/URLConnection/TimeoutTest.java generic-all -java/net/URLConnection/ZeroContentLength.java generic-all - -# Solaris 11 i586 fails with samevm, not sure why -java/net/ResponseCache/B6181108.java generic-all -java/net/ResponseCache/ResponseCacheTest.java generic-all -java/net/URL/GetContent.java generic-all -java/net/URLConnection/HttpContinueStackOverflow.java generic-all -java/net/URLConnection/Redirect307Test.java generic-all -java/net/URLConnection/RedirectLimit.java generic-all -java/net/URLConnection/ResendPostBody.java generic-all -java/net/URL/OpenStream.java generic-all -java/net/URLClassLoader/ClassLoad.java generic-all -java/net/URLConnection/SetIfModifiedSince.java generic-all -java/net/URLConnection/URLConnectionHeaders.java generic-all - -# Linux i586 Connection refused or address already in use, samevm issues -sun/net/ftp/B6427768.java generic-all -sun/net/ftp/FtpGetContent.java generic-all -sun/net/ftp/FtpURL.java generic-all - -# Failed on solaris 10 i586, Exception: should have gotten HttpRetryException? -sun/net/www/http/ChunkedOutputStream/Test.java generic-all - -# Trouble cleaning up threads in samevm mode on solaris 11 i586 -sun/net/www/http/HttpClient/ProxyTest.java generic-all -sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java generic-all -sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java generic-all -sun/net/www/http/HttpClient/B6726695.java generic-all -sun/net/www/http/HttpClient/MultiThreadTest.java generic-all -sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java generic-all - -# Connection refused, windows samevm -sun/net/www/protocol/http/DigestTest.java generic-all - ############################################################################ # jdk_io diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/jdi/ShellScaffold.sh --- a/jdk/test/com/sun/jdi/ShellScaffold.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/jdi/ShellScaffold.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2010, 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 @@ -141,7 +141,10 @@ cleanup() { if [ -r "$failFile" ] ; then - cat $failFile >& 2 + ls -l "$failFile" >&2 + echo "" >&2 + cat "$failFile" >&2 + echo "" >&2 fi # Kill all processes that have our special @@ -337,6 +340,10 @@ failFile=$tmpFileDir/testFailed debuggeepidFile=$tmpFileDir/debuggeepid rm -f $failFile $debuggeepidFile + if [ -f "$failFile" ]; then + echo "ERROR: unable to delete existing failFile:" >&2 + ls -l "$failFile" >&2 + fi if [ -z "$pkg" ] ; then pkgSlash= @@ -524,6 +531,10 @@ # See 6562090. Maybe there is a way that the exit # can cause jdb to not get the quit. sleep 5 + + # The exit code value here doesn't matter since this function + # is called as part of a pipeline and it is not the last command + # in the pipeline. exit 1 fi @@ -938,6 +949,10 @@ done if [ -r "$failFile" ] ; then + ls -l "$failFile" >&2 + echo "" >&2 + cat "$failFile" >&2 + echo "" >&2 exit 1 fi } @@ -946,33 +961,45 @@ # $3 is the number of lines to search (from the end) grepForString() { - # See bug 6220903. Sometimes the jdb '> ' prompt chars - # get inserted into the string we are searching for - # so ignore those chars. if [ -z "$3" ] ; then theCmd=cat else theCmd="tail -$3" fi + case "$2" in - *\>*) - # Target string contains a > so we better - # not ignore it + *\>*) + # Target string contains a '>' so we better not ignore it $theCmd $1 | $grep -s "$2" > $devnull 2>&1 - return $? + stat="$?" ;; + *) + # Target string does not contain a '>'. + # NOTE: if $1 does not end with a new line, piping it to sed + # doesn't include the chars on the last line. Detect this + # case, and add a new line. + theFile="$1" + if [ `tail -1 "$theFile" | wc -l | sed -e 's@ @@g'` = 0 ] ; then + # The target file doesn't end with a new line so we have + # add one to a copy of the target file so the sed command + # below can filter that last line. + cp "$theFile" "$theFile.tmp" + theFile="$theFile.tmp" + echo >> "$theFile" + fi + + # See bug 6220903. Sometimes the jdb prompt chars ('> ') can + # get interleaved in the target file which can keep us from + # matching the target string. + $theCmd "$theFile" | sed -e 's@> @@g' -e 's@>@@g' \ + | $grep -s "$2" > $devnull 2>&1 + stat=$? + if [ "$theFile" != "$1" ]; then + # remove the copy of the target file + rm -f "$theFile" + fi + unset theFile esac - # Target string does not contain a >. - # Ignore > and '> ' in the file. - # NOTE: if $1 does not end with a new line, piping it to sed doesn't include the - # chars on the last line. Detect this case, and add a new line. - cp $1 $1.tmp - if [ `tail -1 $1.tmp | wc -l | sed -e 's@ @@g'` = 0 ] ; then - echo >> $1.tmp - fi - $theCmd $1.tmp | sed -e 's@> @@g' -e 's@>@@g' | $grep -s "$2" > $devnull 2>&1 - stat=$? - rm -f $1.tmp return $stat } @@ -1037,6 +1064,11 @@ echo echo "--Done: test passed" exit 0 + else + ls -l "$failFile" >&2 + echo "" >&2 + cat "$failFile" >&2 + echo "" >&2 fi } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6676075 + * @summary RegistryContext (com.sun.jndi.url.rmi.rmiURLContext) coding problem + */ + +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; + +import com.sun.jndi.rmi.registry.*; + +public class ContextWithNullProperties { + + public static void main(String[] args) throws Exception { + + // Create registry on port 1099 if one is not already running. + try { + LocateRegistry.createRegistry(1099); + } catch (RemoteException e) { + } + + System.out.println("Connecting to the default Registry..."); + // Connect to the default Registry. + // Pass null as the JNDI environment properties (see final argument) + RegistryContext ctx = new RegistryContext(null, -1, null); + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/Test1.java --- a/jdk/test/com/sun/net/httpserver/Test1.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/Test1.java Thu Aug 12 19:55:48 2010 -0700 @@ -24,17 +24,15 @@ /** * @test * @bug 6270015 + * @run main/othervm Test1 * @summary Light weight HTTP server */ import com.sun.net.httpserver.*; -import java.util.*; import java.util.concurrent.*; import java.io.*; import java.net.*; -import java.security.*; -import java.security.cert.*; import javax.net.ssl.*; /* basic http/s connectivity test diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/Test11.java --- a/jdk/test/com/sun/net/httpserver/Test11.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/Test11.java Thu Aug 12 19:55:48 2010 -0700 @@ -28,7 +28,6 @@ */ import java.net.*; -import java.util.*; import java.util.concurrent.*; import java.io.*; import com.sun.net.httpserver.*; @@ -52,22 +51,25 @@ public static void main (String[] args) throws Exception { System.out.print ("Test 11: "); - HttpServer server = HttpServer.create (new InetSocketAddress(0), 0); - HttpContext ctx = server.createContext ( - "/foo/bar/", new Handler () - ); - ExecutorService s = Executors.newCachedThreadPool(); - server.setExecutor (s); - server.start (); - URL url = new URL ("http://localhost:" + server.getAddress().getPort()+ - "/Foo/bar/test.html"); - HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); - int r = urlc.getResponseCode(); - System.out.println ("OK"); - s.shutdown(); - server.stop(5); - if (r == 200) { - throw new RuntimeException ("wrong response received"); + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + ExecutorService s = Executors.newCachedThreadPool(); + try { + HttpContext ctx = server.createContext ( + "/foo/bar/", new Handler () + ); + s = Executors.newCachedThreadPool(); + server.start (); + URL url = new URL ("http://localhost:" + server.getAddress().getPort()+ + "/Foo/bar/test.html"); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); + int r = urlc.getResponseCode(); + if (r == 200) { + throw new RuntimeException ("wrong response received"); + } + System.out.println ("OK"); + } finally { + s.shutdown(); + server.stop(2); } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/Test12.java --- a/jdk/test/com/sun/net/httpserver/Test12.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/Test12.java Thu Aug 12 19:55:48 2010 -0700 @@ -24,17 +24,15 @@ /** * @test * @bug 6270015 + * @run main/othervm Test12 * @summary Light weight HTTP server */ import com.sun.net.httpserver.*; -import java.util.*; import java.util.concurrent.*; import java.io.*; import java.net.*; -import java.security.*; -import java.security.cert.*; import javax.net.ssl.*; /* basic http/s connectivity test diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/Test13.java --- a/jdk/test/com/sun/net/httpserver/Test13.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/Test13.java Thu Aug 12 19:55:48 2010 -0700 @@ -24,17 +24,16 @@ /** * @test * @bug 6270015 + * @run main/othervm Test13 * @summary Light weight HTTP server */ import com.sun.net.httpserver.*; -import java.util.*; import java.util.concurrent.*; import java.io.*; import java.net.*; -import java.security.*; -import java.security.cert.*; + import javax.net.ssl.*; /* basic http/s connectivity test diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/Test6a.java --- a/jdk/test/com/sun/net/httpserver/Test6a.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/Test6a.java Thu Aug 12 19:55:48 2010 -0700 @@ -24,17 +24,15 @@ /** * @test * @bug 6270015 + * @run main/othervm Test6a * @summary Light weight HTTP server */ import com.sun.net.httpserver.*; -import java.util.*; import java.util.concurrent.*; import java.io.*; import java.net.*; -import java.security.*; -import javax.security.auth.callback.*; import javax.net.ssl.*; /** diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/Test7a.java --- a/jdk/test/com/sun/net/httpserver/Test7a.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/Test7a.java Thu Aug 12 19:55:48 2010 -0700 @@ -24,18 +24,15 @@ /** * @test * @bug 6270015 + * @run main/othervm Test7a * @summary Light weight HTTP server */ import com.sun.net.httpserver.*; -import java.util.*; import java.util.concurrent.*; -import java.util.logging.*; import java.io.*; import java.net.*; -import java.security.*; -import javax.security.auth.callback.*; import javax.net.ssl.*; /** diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/Test8a.java --- a/jdk/test/com/sun/net/httpserver/Test8a.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/Test8a.java Thu Aug 12 19:55:48 2010 -0700 @@ -24,18 +24,15 @@ /** * @test * @bug 6270015 + * @run main/othervm Test8a * @summary Light weight HTTP server */ import com.sun.net.httpserver.*; -import java.util.*; import java.util.concurrent.*; -import java.util.logging.*; import java.io.*; import java.net.*; -import java.security.*; -import javax.security.auth.callback.*; import javax.net.ssl.*; /** @@ -50,46 +47,50 @@ //h.setLevel (Level.INFO); //log.addHandler (h); //log.setLevel (Level.INFO); - Handler handler = new Handler(); - InetSocketAddress addr = new InetSocketAddress (0); - HttpsServer server = HttpsServer.create (addr, 0); - HttpContext ctx = server.createContext ("/test", handler); - ExecutorService executor = Executors.newCachedThreadPool(); - SSLContext ssl = new SimpleSSLContext(System.getProperty("test.src")).get(); - server.setHttpsConfigurator(new HttpsConfigurator (ssl)); - server.setExecutor (executor); - server.start (); + HttpsServer server = null; + ExecutorService executor = null; + try { + Handler handler = new Handler(); + InetSocketAddress addr = new InetSocketAddress (0); + server = HttpsServer.create (addr, 0); + HttpContext ctx = server.createContext ("/test", handler); + executor = Executors.newCachedThreadPool(); + SSLContext ssl = new SimpleSSLContext(System.getProperty("test.src")).get(); + server.setHttpsConfigurator(new HttpsConfigurator (ssl)); + server.setExecutor (executor); + server.start (); - URL url = new URL ("https://localhost:"+server.getAddress().getPort()+"/test/foo.html"); - System.out.print ("Test8a: " ); - HttpsURLConnection urlc = (HttpsURLConnection)url.openConnection (); - urlc.setDoOutput (true); - urlc.setRequestMethod ("POST"); - urlc.setHostnameVerifier (new DummyVerifier()); - urlc.setSSLSocketFactory (ssl.getSocketFactory()); - OutputStream os = new BufferedOutputStream (urlc.getOutputStream(), 8000); - for (int i=0; i selkeys = selector.selectedKeys(); for (SelectionKey key : selkeys) { if (key.isReadable()) { SocketChannel chan = (SocketChannel)key.channel(); - buf.clear(); + ByteBuffer buf = (ByteBuffer)key.attachment(); try { - int x = chan.read (buf); - if (x == -1) { + int x = chan.read(buf); + if (x == -1 || responseComplete(buf)) { + key.attach(null); chan.close(); + responses++; } } catch (IOException e) {} } } - if (i< NUM) { - SocketChannel schan = SocketChannel.open (destaddr); - String cmd = "GET /test/foo.html HTTP/1.1\r\nContent-length: 0\r\n\r\n"; - buf.rewind (); - buf.put (cmd.getBytes()); - buf.flip(); + if (requests < NUM) { + SocketChannel schan = SocketChannel.open(destaddr); + requestBuf.rewind(); int c = 0; - while (buf.remaining() > 0) { - c += schan.write (buf); + while (requestBuf.remaining() > 0) { + c += schan.write(requestBuf); } - schan.configureBlocking (false); - schan.register (selector, SelectionKey.OP_READ, null); - } else { + schan.configureBlocking(false); + schan.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(100)); + requests++; + } + if (responses == NUM) { System.out.println ("Finished clients"); - server.stop (1); - executor.shutdown (); - return; + break; } } + server.stop (1); + selector.close(); + executor.shutdown (); + + } + + /* Look for CR LF CR LF */ + static boolean responseComplete(ByteBuffer buf) { + int pos = buf.position(); + buf.flip(); + byte[] lookingFor = new byte[] {'\r', '\n', '\r', '\n' }; + int lookingForCount = 0; + while (buf.hasRemaining()) { + byte b = buf.get(); + if (b == lookingFor[lookingForCount]) { + lookingForCount++; + if (lookingForCount == 4) { + return true; + } + } else { + lookingForCount = 0; + } + } + buf.position(pos); + buf.limit(buf.capacity()); + return false; } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/com/sun/net/httpserver/bugs/B6373555.java --- a/jdk/test/com/sun/net/httpserver/bugs/B6373555.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/com/sun/net/httpserver/bugs/B6373555.java Thu Aug 12 19:55:48 2010 -0700 @@ -46,7 +46,7 @@ private static Object lock; static HttpServer httpServer; static ExecutorService pool, execs; - static int NUM = 4000; + static int NUM = 1000; public static void main(String[] args) throws Exception { try { @@ -125,7 +125,7 @@ } } catch(Exception e) { - //e.printStackTrace(); + e.printStackTrace(); System.out.print ("."); error = true; } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/beans/XMLEncoder/Test4631471.java --- a/jdk/test/java/beans/XMLEncoder/Test4631471.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/beans/XMLEncoder/Test4631471.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4631471 + * @bug 4631471 6972468 * @summary Tests DefaultTreeModel encoding * @author Sergey Malenkov, Mark Davidson */ @@ -37,6 +37,12 @@ public abstract class Test4631471 extends AbstractTest { public static void main(String[] args) throws Exception { + main(); + System.setSecurityManager(new SecurityManager()); + main(); + } + + private static void main() throws Exception { // the DefaultMutableTreeNode will archive correctly new Test4631471() { protected Object getObject() { diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/beans/XMLEncoder/Test4903007.java --- a/jdk/test/java/beans/XMLEncoder/Test4903007.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/beans/XMLEncoder/Test4903007.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4903007 + * @bug 4903007 6972468 * @summary Tests encoding of container with boxes and BoxLayout * @author Sergey Malenkov, Mark Davidson */ @@ -36,7 +36,7 @@ public class Test4903007 extends AbstractTest { public static void main(String[] args) throws Exception { - new Test4903007().test(false); // TODO: could not encode with security manager + new Test4903007().test(true); } protected JPanel getObject() { diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java --- a/jdk/test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 5023552 + * @bug 5023552 6972468 * @summary Tests JLayeredPane encoding * @author Sergey Malenkov */ @@ -35,7 +35,7 @@ public final class javax_swing_JLayeredPane extends AbstractTest { public static void main(String[] args) { - new javax_swing_JLayeredPane().test(false); // TODO: could not encode with security manager + new javax_swing_JLayeredPane().test(true); } private static void init(JLayeredPane pane, int layer, int x, int y, int w, int h, Color color) { diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/lang/Throwable/SuppressedExceptions.java --- a/jdk/test/java/lang/Throwable/SuppressedExceptions.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/lang/Throwable/SuppressedExceptions.java Thu Aug 12 19:55:48 2010 -0700 @@ -26,7 +26,7 @@ /* * @test - * @bug 6911258 6962571 + * @bug 6911258 6962571 6963622 * @summary Basic tests of suppressed exceptions * @author Joseph D. Darcy */ @@ -35,11 +35,22 @@ private static String message = "Bad suppressed exception information"; public static void main(String... args) throws Exception { + noSelfSuppression(); basicSupressionTest(); serializationTest(); selfReference(); } + private static void noSelfSuppression() { + Throwable throwable = new Throwable(); + try { + throwable.addSuppressedException(throwable); + throw new RuntimeException("IllegalArgumentException for self-suppresion not thrown."); + } catch (IllegalArgumentException iae) { + ; // Expected + } + } + private static void basicSupressionTest() { Throwable throwable = new Throwable(); RuntimeException suppressed = new RuntimeException("A suppressed exception."); @@ -156,9 +167,8 @@ throwable1.printStackTrace(); - - throwable1.addSuppressedException(throwable1); throwable1.addSuppressedException(throwable2); + throwable2.addSuppressedException(throwable1); throwable1.printStackTrace(); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/DatagramSocket/DatagramTimeout.java --- a/jdk/test/java/net/DatagramSocket/DatagramTimeout.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/DatagramSocket/DatagramTimeout.java Thu Aug 12 19:55:48 2010 -0700 @@ -27,25 +27,25 @@ * @summary test to see if timeout hangs * @run main/timeout=15 DatagramTimeout */ -import java.net.*; -import java.io.*; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketTimeoutException; public class DatagramTimeout { - - public static ServerSocket sock; - public static void main(String[] args) throws Exception { boolean success = false; + DatagramSocket sock = new DatagramSocket(); + try { - DatagramSocket sock; DatagramPacket p; byte[] buffer = new byte[50]; p = new DatagramPacket(buffer, buffer.length); - sock = new DatagramSocket(2333); sock.setSoTimeout(2); sock.receive(p); } catch (SocketTimeoutException e) { success = true; + } finally { + sock.close(); } if (!success) throw new RuntimeException("Socket timeout failure."); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/DatagramSocket/SendSize.java --- a/jdk/test/java/net/DatagramSocket/SendSize.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/DatagramSocket/SendSize.java Thu Aug 12 19:55:48 2010 -0700 @@ -32,35 +32,26 @@ * @author Benjamin Renaud */ -import java.io.*; -import java.net.*; -import java.util.*; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; public class SendSize { - - static final int clientPort = 8989; - static final int serverPort = 9999; static final int bufferLength = 512; static final int packetLength = 256; public static void main(String[] args) throws Exception { - new ServerThread().start(); - new ClientThread().start(); + DatagramSocket serverSocket = new DatagramSocket(); + new ServerThread(serverSocket).start(); + new ClientThread(serverSocket.getLocalPort()).start(); } - static class ServerThread extends Thread { - - int port; DatagramSocket server; - ServerThread(int port) throws IOException { - this.port = port; - this.server = new DatagramSocket(port); - } - - ServerThread() throws IOException { - this(SendSize.serverPort); + ServerThread(DatagramSocket server) { + this.server = server; } public void run() { @@ -85,33 +76,22 @@ } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("caugth: " + e); + } finally { + if (server != null) { server.close(); } } } } static class ClientThread extends Thread { - int port; int serverPort; - int bufferLength; - int packetLength; - DatagramSocket client; InetAddress host; - ClientThread(int port, int serverPort, - int bufferLength, int packetLength) throws IOException { - this.port = port; + ClientThread(int serverPort)throws IOException { this.serverPort = serverPort; this.host = InetAddress.getLocalHost(); - this.bufferLength = bufferLength; - this.packetLength = packetLength; - this.client = new DatagramSocket(port, host); - } - - ClientThread() throws IOException { - this(SendSize.clientPort, SendSize.serverPort, - SendSize.bufferLength, SendSize.packetLength); + this.client = new DatagramSocket(); } public void run() { @@ -129,6 +109,8 @@ } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("caught: " + e); + } finally { + if (client != null) { client.close(); } } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Inet6Address/B6558853.java --- a/jdk/test/java/net/Inet6Address/B6558853.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Inet6Address/B6558853.java Thu Aug 12 19:55:48 2010 -0700 @@ -43,6 +43,9 @@ InetAddress dest = null; while (l.hasMoreElements() && dest == null) { NetworkInterface nif = l.nextElement(); + if (!nif.isUp()) + continue; + for (InterfaceAddress a : nif.getInterfaceAddresses()) { if (a.getAddress() instanceof Inet6Address) { Inet6Address a6 = (Inet6Address) a.getAddress(); @@ -53,6 +56,7 @@ } } } + System.out.println("Using " + dest); if (dest != null) { B6558853 test = new B6558853(dest, port); Thread thread = new Thread(test); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Inet6Address/serialize/Serialize.java --- a/jdk/test/java/net/Inet6Address/serialize/Serialize.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Inet6Address/serialize/Serialize.java Thu Aug 12 19:55:48 2010 -0700 @@ -72,6 +72,7 @@ File file = new File (System.getProperty("test.src"), "serial1.4.2.ser"); ois = new ObjectInputStream(new FileInputStream(file)); nobj = (Inet6Address) ois.readObject(); + ois.close(); if (!nobj.equals (InetAddress.getByName ("::1"))) { throw new RuntimeException ("old ::1 not deserialized right"); } @@ -90,6 +91,8 @@ nobj = (Inet6Address) ois.readObject(); } catch (NullPointerException e) { throw new RuntimeException("6656849 Not fixed: NullPointer when deserializing"); + } finally { + ois.close(); } System.out.println(nobj); System.out.println("All tests passed"); @@ -102,6 +105,7 @@ ObjectInputStream ois = new ObjectInputStream(new FileInputStream("i6a1.ser")); Inet6Address nobj = (Inet6Address) ois.readObject(); + ois.close(); if (nobj.equals(obj)) { return true; diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/InetAddress/CheckJNI.java --- a/jdk/test/java/net/InetAddress/CheckJNI.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/InetAddress/CheckJNI.java Thu Aug 12 19:55:48 2010 -0700 @@ -56,6 +56,8 @@ while (ifs.hasMoreElements()) { NetworkInterface nif = (NetworkInterface)ifs.nextElement(); + if (!nif.isUp()) + continue; Enumeration addrs = nif.getInetAddresses(); while (addrs.hasMoreElements()) { InetAddress addr = (InetAddress) addrs.nextElement(); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/MulticastSocket/SetOutgoingIf.java --- a/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/MulticastSocket/SetOutgoingIf.java Thu Aug 12 19:55:48 2010 -0700 @@ -76,6 +76,10 @@ // now determine what (if any) type of addresses are assigned to this interface for (InetAddress addr : Collections.list(nic.getInetAddresses())) { + if (addr.isAnyLocalAddress()) + continue; + + System.out.println(" addr " + addr); if (addr instanceof Inet4Address) { netIf.ipv4Address(true); } else if (addr instanceof Inet6Address) { diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/NetworkInterface/IPv4Only.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/NetworkInterface/IPv4Only.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6964714 + * @run main/othervm IPv4Only + * @summary Test the networkinterface listing with java.net.preferIPv4Stack=true. + */ + + +import java.net.*; +import java.util.*; + + +public class IPv4Only { + public static void main(String[] args) throws Exception { + System.setProperty("java.net.preferIPv4Stack","true"); + + Enumeration nifs = NetworkInterface.getNetworkInterfaces(); + while (nifs.hasMoreElements()) { + NetworkInterface nif = nifs.nextElement(); + Enumeration addrs = nif.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress hostAddr = addrs.nextElement(); + if ( hostAddr instanceof Inet6Address ){ + throw new RuntimeException( "NetworkInterfaceV6List failed - found v6 address " + hostAddr.getHostAddress() ); + } + } + } + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/ResponseCache/B6181108.java --- a/jdk/test/java/net/ResponseCache/B6181108.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/ResponseCache/B6181108.java Thu Aug 12 19:55:48 2010 -0700 @@ -67,9 +67,10 @@ out.flush(); s.close(); - ss.close(); } catch (Exception e) { e.printStackTrace(); + } finally { + try { ss.close(); } catch (IOException unused) {} } } @@ -100,6 +101,7 @@ URLConnection urlc = url.openConnection(); int i = ((HttpURLConnection)(urlc)).getResponseCode(); System.out.println ("response code = " + i); + ResponseCache.setDefault(null); } public static void main(String args[]) throws Exception { diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/ResponseCache/ResponseCacheTest.java --- a/jdk/test/java/net/ResponseCache/ResponseCacheTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/ResponseCache/ResponseCacheTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -30,7 +30,6 @@ import java.net.*; import java.util.*; import java.io.*; -import java.nio.*; import sun.net.www.ParseUtil; import javax.net.ssl.*; @@ -43,11 +42,16 @@ static URL url1; static URL url2; static String FNPrefix, OutFNPrefix; + static List streams = new ArrayList<>(); + static List files = new ArrayList<>(); + /* * Our "http" server to return a 404 */ public void run() { + Socket s = null; + FileInputStream fis = null; try { - Socket s = ss.accept(); + s = ss.accept(); InputStream is = s.getInputStream (); BufferedReader r = new BufferedReader(new InputStreamReader(is)); @@ -68,7 +72,7 @@ out.print("Content-Length: "+file2.length()+"\r\n"); out.print("Connection: close\r\n"); out.print("\r\n"); - FileInputStream fis = new FileInputStream(file2); + fis = new FileInputStream(file2); byte[] buf = new byte[(int)file2.length()]; int len; while ((len = fis.read(buf)) != -1) { @@ -81,6 +85,10 @@ ss.close(); } catch (Exception e) { e.printStackTrace(); + } finally { + try { ss.close(); } catch (IOException unused) {} + try { s.close(); } catch (IOException unused) {} + try { fis.close(); } catch (IOException unused) {} } } static class NameVerifier implements HostnameVerifier { @@ -144,11 +152,14 @@ // assert (headers1 == headers2 && file1 == file2.2) File file1 = new File(OutFNPrefix+"file1"); File file2 = new File(OutFNPrefix+"file2.2"); + files.add(file1); + files.add(file2); System.out.println("headers1"+headers1+"\nheaders2="+headers2); if (!headers1.equals(headers2) || file1.length() != file2.length()) { throw new RuntimeException("test failed"); } } + public static void main(String args[]) throws Exception { try { ResponseCache.setDefault(new MyResponseCache()); @@ -157,6 +168,12 @@ new ResponseCacheTest(); } finally{ ResponseCache.setDefault(null); + for (Closeable c: streams) { + try { c.close(); } catch (IOException unused) {} + } + for (File f: files) { + f.delete(); + } } } @@ -184,6 +201,7 @@ public MyCacheResponse(String filename) { try { fis = new FileInputStream(new File(filename)); + streams.add(fis); ObjectInputStream ois = new ObjectInputStream(fis); headers = (Map>)ois.readObject(); } catch (Exception ex) { @@ -206,6 +224,8 @@ try { File file = new File(filename); fos = new FileOutputStream(file); + streams.add(fos); + files.add(file); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(rspHeaders); } catch (Exception ex) { diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/ResponseCache/getResponseCode.java --- a/jdk/test/java/net/ResponseCache/getResponseCode.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/ResponseCache/getResponseCode.java Thu Aug 12 19:55:48 2010 -0700 @@ -39,6 +39,7 @@ public class getResponseCode { static URL url; static String FNPrefix; + static List resources = new ArrayList<>(); getResponseCode() throws Exception { url = new URL("http://localhost/file1.cache"); @@ -57,6 +58,9 @@ new getResponseCode(); } finally{ ResponseCache.setDefault(null); + for (Closeable c : resources) { + try { c.close(); } catch (IOException unused) {} + } } } @@ -77,6 +81,7 @@ public MyResponse(String filename) { try { fis = new FileInputStream(new File(filename)); + resources.add(fis); headers = (Map>)new ObjectInputStream(fis).readObject(); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/AccurateTimeout.java --- a/jdk/test/java/net/Socket/AccurateTimeout.java Wed Aug 11 10:05:56 2010 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * @bug 4512028 - * @summary Check the tolerance on read timeouts. - */ -import java.net.*; -import java.io.*; - -public class AccurateTimeout { - - static final int TOLERANCE = 100; - - static boolean skipTest() { - String os = System.getProperty("os.name"); - if (os.equals("Windows 95") || - os.equals("Windows 98") || - os.equals("Windows Me")) { - - System.out.println("Due to an OS bug timeout tolerance cannot be tested on this OS"); - return true; - } - return false; - } - - public static void main(String args[]) throws Exception { - - if (skipTest()) { - return; - } - - int failures = 0; - int timeout; - - System.out.println(""); - System.out.println("Testing Socket.getInputStream().read() ..."); - System.out.println(""); - - ServerSocket ss = new ServerSocket(0); - Socket s1 = new Socket(InetAddress.getLocalHost(), ss.getLocalPort()); - Socket s2 = ss.accept(); - - InputStream in = s1.getInputStream(); - - timeout = 100; - while (timeout < 2500) { - s1.setSoTimeout(timeout); - - long startTime = System.currentTimeMillis(); - try { - in.read(); - } catch (SocketTimeoutException e) { - } - long actual = System.currentTimeMillis() - startTime; - - System.out.print("excepted: " + timeout + " actual: " + actual); - - if (Math.abs(actual-timeout) > TOLERANCE) { - System.out.print(" *** FAIL: outside tolerance"); - failures++; - } else { - System.out.print(" PASS."); - } - - System.out.println(""); - timeout += 200; - } - - s1.close(); - s2.close(); - ss.close(); - - - // ---------- - - - System.out.println(""); - System.out.println("Testing DatagramSocket.receive ..."); - System.out.println(""); - - byte b[] = new byte[8]; - DatagramPacket p = new DatagramPacket(b, b.length); - - DatagramSocket ds = new DatagramSocket(); - - timeout = 100; - while (timeout < 2500) { - ds.setSoTimeout(timeout); - - long startTime = System.currentTimeMillis(); - try { - ds.receive(p); - } catch (SocketTimeoutException e) { - } - long actual = System.currentTimeMillis() - startTime; - - System.out.print("excepted: " + timeout + " actual: " + actual); - - if (Math.abs(actual-timeout) > TOLERANCE) { - System.out.print(" *** FAIL: outside tolerance"); - failures++; - } else { - System.out.print(" PASS."); - } - - System.out.println(""); - timeout += 200; - } - - ds.close(); - - System.out.println(""); - - // --------- - - if (failures > 0) { - throw new Exception("Test failed: " + failures + - " test(s) outside tolerance"); - } - - } - -} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/CloseAvailable.java --- a/jdk/test/java/net/Socket/CloseAvailable.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/CloseAvailable.java Thu Aug 12 19:55:48 2010 -0700 @@ -47,6 +47,7 @@ t.start(); Socket soc = ss.accept(); + ss.close(); DataInputStream is = new DataInputStream(soc.getInputStream()); is.close(); @@ -64,7 +65,7 @@ public void run() { try { Socket s = new Socket(addr, port); - + s.close(); } catch (Exception e) { e.printStackTrace(); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/DeadlockTest.java --- a/jdk/test/java/net/Socket/DeadlockTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/DeadlockTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -33,29 +33,32 @@ public class DeadlockTest { public static void main(String [] argv) throws Exception { + ServerSocket ss = new ServerSocket(0); + Socket clientSocket = new Socket(); - // Start the server thread - Thread s1 = new Thread(new ServerThread()); - s1.start(); + try { + // Start the server thread + Thread s1 = new Thread(new ServerThread(ss)); + s1.start(); - // Sleep to make sure s1 has created a server socket - Thread.sleep(1000); + // Start the client thread + ClientThread ct = new ClientThread(clientSocket, ss.getLocalPort()); + Thread c1 = new Thread(ct); + c1.start(); - // Start the client thread - ClientThread ct = new ClientThread(); - Thread c1 = new Thread(ct); - c1.start(); - - // Wait for the client thread to finish - c1.join(40000); + // Wait for the client thread to finish + c1.join(20000); - // If timeout, we assume there is a deadlock - if (c1.isAlive() == true) { - // Close the socket to force the server thread - // terminate too - s1.stop(); - ct.getSock().close(); - throw new Exception("Takes too long. Dead lock"); + // If timeout, we assume there is a deadlock + if (c1.isAlive() == true) { + // Close the socket to force the server thread + // terminate too + s1.stop(); + throw new Exception("Takes too long. Dead lock"); + } + } finally { + ss.close(); + clientSocket.close(); } } } @@ -71,8 +74,8 @@ Socket sock; - public ServerThread() throws Exception { - + public ServerThread(ServerSocket serverSocket) throws Exception { + this.server = serverSocket; } public void ping(int cnt) { @@ -85,7 +88,6 @@ try { if (Thread.currentThread().getName().startsWith("child") == false) { - server = new ServerSocket(4711); sock = server.accept(); new Thread(this, "child").start(); @@ -107,6 +109,7 @@ } } catch (Throwable e) { + System.out.println(e); // If anything goes wrong, just quit. } @@ -141,10 +144,11 @@ Socket sock; - public ClientThread() throws Exception { + public ClientThread(Socket sock, int serverPort) throws Exception { try { - System.out.println("About to create a socket"); - sock = new Socket(InetAddress.getLocalHost().getHostName(), 4711); + System.out.println("About to connect the client socket"); + this.sock = sock; + this.sock.connect(new InetSocketAddress("localhost", serverPort)); System.out.println("connected"); out = new ObjectOutputStream(sock.getOutputStream()); @@ -156,10 +160,6 @@ } } - public Socket getSock() { - return sock; - } - private int cnt = 1; public void run() { @@ -213,6 +213,7 @@ System.out.println("write message done " + cnt++); } catch (IOException ioe) { // Ignore the exception + System.out.println(ioe); } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/LingerTest.java --- a/jdk/test/java/net/Socket/LingerTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/LingerTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -81,7 +81,7 @@ public void run() { System.out.println ("Another starts"); try { - Thread.currentThread().sleep(delay); + Thread.sleep(delay); Socket s = new Socket("localhost", port); synchronized (this) { connected = true; @@ -105,7 +105,6 @@ Socket s1 = new Socket("localhost", ss.getLocalPort()); Socket s2 = ss.accept(); - // setup conditions for untransmitted data and lengthy // linger interval s1.setSendBufferSize(128*1024); @@ -122,14 +121,15 @@ thr.start(); // give sender time to queue the data - Thread.currentThread().sleep(1000); + Thread.sleep(1000); // close the socket asynchronously (new Thread(new Closer(s1))).start(); // give another time to run - Thread.currentThread().sleep(10000); + Thread.sleep(10000); + ss.close(); // check that another is done if (!another.connected()) { throw new RuntimeException("Another thread is blocked"); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/LinkLocal.java --- a/jdk/test/java/net/Socket/LinkLocal.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/LinkLocal.java Thu Aug 12 19:55:48 2010 -0700 @@ -58,11 +58,10 @@ } catch (SocketException e) { failed++; System.out.println("Test failed: " + e); + } finally { + s.close(); + ss.close(); } - - // clean up - s.close(); - ss.close(); } static void UdpTest(InetAddress ia, boolean connected) throws Exception { @@ -93,16 +92,16 @@ ds1.send(p); System.out.println("Packet has been sent."); - ds2.setSoTimeout(1000); + ds2.setSoTimeout(5000); ds2.receive(p); System.out.println("Test passed - packet received."); } catch (SocketException e) { failed++; System.out.println("Test failed: " + e); + } finally { + ds1.close(); + ds2.close(); } - - ds1.close(); - ds2.close(); } static void TestAddress(InetAddress ia) throws Exception { @@ -138,6 +137,9 @@ Enumeration nifs = NetworkInterface.getNetworkInterfaces(); while (nifs.hasMoreElements()) { NetworkInterface ni = (NetworkInterface)nifs.nextElement(); + if (!ni.isUp()) + continue; + Enumeration addrs = ni.getInetAddresses(); while (addrs.hasMoreElements()) { InetAddress addr = (InetAddress)addrs.nextElement(); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/ProxyCons.java --- a/jdk/test/java/net/Socket/ProxyCons.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/ProxyCons.java Thu Aug 12 19:55:48 2010 -0700 @@ -39,6 +39,7 @@ public void run () { try { Socket s = server.accept (); + s.close(); while (!finished ()) { Thread.sleep (500); } @@ -58,10 +59,9 @@ public ProxyCons() { } - void test() { + void test() throws Exception { + ServerSocket ss = new ServerSocket(0); try { - ServerSocket ss = new ServerSocket(); - ss.bind(new InetSocketAddress(0)); Server s = new Server(ss); s.start(); Socket sock = new Socket(Proxy.NO_PROXY); @@ -70,10 +70,12 @@ sock.close(); } catch (java.io.IOException e) { throw new RuntimeException(e); + } finally { + ss.close(); } } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { ProxyCons c = new ProxyCons(); c.test(); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/ReadTimeout.java --- a/jdk/test/java/net/Socket/ReadTimeout.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/ReadTimeout.java Thu Aug 12 19:55:48 2010 -0700 @@ -44,7 +44,7 @@ sin = InetAddress.getLocalHost(); srv = new ServerSocket(port); port = srv.getLocalPort(); - soc = new Socket(sin, port, true); + soc = new Socket(sin, port); soc1 = srv.accept(); soc.setSoTimeout(tout); @@ -53,10 +53,10 @@ os = soc1.getOutputStream(); is.read(); } catch(InterruptedIOException e) { + } finally { + soc.close(); + soc1.close(); + srv.close(); } - - soc.close(); - soc1.close(); - srv.close(); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/SetReceiveBufferSize.java --- a/jdk/test/java/net/Socket/SetReceiveBufferSize.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/SetReceiveBufferSize.java Thu Aug 12 19:55:48 2010 -0700 @@ -32,29 +32,14 @@ import java.net.ServerSocket; public class SetReceiveBufferSize { - class Server extends Thread { - private ServerSocket ss; - public Server(ServerSocket ss) { - this.ss = ss; - } - - public void run() { - try { - ss.accept(); - } catch (Exception e) { - } - } - } - public static void main(String[] args) throws Exception { SetReceiveBufferSize s = new SetReceiveBufferSize(); } public SetReceiveBufferSize() throws Exception { ServerSocket ss = new ServerSocket(0); - Server serv = new Server(ss); - serv.start(); Socket s = new Socket("localhost", ss.getLocalPort()); + Socket accepted = ss.accept(); try { s.setReceiveBufferSize(0); } catch (IllegalArgumentException e) { @@ -62,6 +47,8 @@ } catch (Exception ex) { } finally { ss.close(); + s.close(); + accepted.close(); } throw new RuntimeException("IllegalArgumentException not thrown!"); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/SetSoLinger.java --- a/jdk/test/java/net/Socket/SetSoLinger.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/SetSoLinger.java Thu Aug 12 19:55:48 2010 -0700 @@ -30,36 +30,24 @@ import java.net.*; -public class SetSoLinger implements Runnable { - static ServerSocket ss; - static InetAddress addr; - static int port; +public class SetSoLinger { + static final int LINGER = 65546; public static void main(String args[]) throws Exception { - boolean error = true; - int linger = 65546; - int value = 0; - addr = InetAddress.getLocalHost(); - ss = new ServerSocket(0); - port = ss.getLocalPort(); + int value; + InetAddress addr = InetAddress.getLocalHost(); + ServerSocket ss = new ServerSocket(0); + int port = ss.getLocalPort(); - Thread t = new Thread(new SetSoLinger()); - t.start(); + Socket s = new Socket(addr, port); Socket soc = ss.accept(); - soc.setSoLinger(true, linger); + soc.setSoLinger(true, LINGER); value = soc.getSoLinger(); soc.close(); + s.close(); + ss.close(); if(value != 65535) throw new RuntimeException("Failed. Value not properly reduced."); } - - public void run() { - try { - Socket s = new Socket(addr, port); - } catch (Exception e) { - e.printStackTrace(); - } - } - } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/ShutdownBoth.java --- a/jdk/test/java/net/Socket/ShutdownBoth.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/ShutdownBoth.java Thu Aug 12 19:55:48 2010 -0700 @@ -36,12 +36,14 @@ Socket s1 = new Socket(ss.getInetAddress(), ss.getLocalPort()); Socket s2 = ss.accept(); - s1.shutdownInput(); - s1.shutdownOutput(); // failed b55 - - s1.close(); - s2.close(); - ss.close(); + try { + s1.shutdownInput(); + s1.shutdownOutput(); // failed b55 + } finally { + s1.close(); + s2.close(); + ss.close(); + } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/SoTimeout.java --- a/jdk/test/java/net/Socket/SoTimeout.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/SoTimeout.java Thu Aug 12 19:55:48 2010 -0700 @@ -52,9 +52,10 @@ t.start(); Socket s = serverSocket.accept(); + serverSocket.close(); - // set a 1 second timeout on the socket - s.setSoTimeout(1000); + // set a 5 second timeout on the socket + s.setSoTimeout(5000); s.getInputStream().read(b, 0, b.length); s.close(); @@ -64,7 +65,7 @@ // this sequence should complete fairly quickly and if it // takes something resembling the the SoTimeout value then // we are probably incorrectly blocking and not waking up - if (waited > 500) { + if (waited > 2000) { throw new Exception("shouldn't take " + waited + " to complete"); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/Timeout.java --- a/jdk/test/java/net/Socket/Timeout.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/Timeout.java Thu Aug 12 19:55:48 2010 -0700 @@ -31,18 +31,16 @@ import java.io.*; public class Timeout { - - public static ServerSocket sock; - public static void main(String[] args) throws Exception { boolean success = false; + ServerSocket sock = new ServerSocket(0); try { - ServerSocket sock; - sock = new ServerSocket(2333); sock.setSoTimeout(2); sock.accept(); } catch (InterruptedIOException e) { success = true; + } finally { + sock.close(); } if (!success) throw new RuntimeException("Socket timeout failure."); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/UrgentDataTest.java --- a/jdk/test/java/net/Socket/UrgentDataTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/UrgentDataTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -90,63 +90,64 @@ } public void run () throws Exception { - if (isClient) { - client = new Socket (clHost, clPort); - clis = client.getInputStream(); - clos = client.getOutputStream(); - client.setOOBInline (true); - if (client.getOOBInline() != true) { - throw new RuntimeException ("Setting OOBINLINE failed"); - } - } - if (isServer) { - server = listener.accept (); - sis = server.getInputStream(); - sos = server.getOutputStream(); - } - if (isClient) { - clos.write ("Hello".getBytes ()); - client.sendUrgentData (100); - clos.write ("world".getBytes ()); - } - // read Hello world from server (during which oob byte must have been dropped) - String s = "Helloworld"; - if (isServer) { - for (int y=0; y= 0) { throw ioe; } + } finally { + server.close(); } - server.close(); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/Socket/setReuseAddress/Restart.java --- a/jdk/test/java/net/Socket/setReuseAddress/Restart.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/Socket/setReuseAddress/Restart.java Thu Aug 12 19:55:48 2010 -0700 @@ -39,27 +39,28 @@ */ public static void main(String args[]) throws Exception { - - InetSocketAddress isa = new InetSocketAddress(0); - ServerSocket ss = new ServerSocket(); - ss.bind(isa); + ServerSocket ss = new ServerSocket(0); + Socket s1 = null, s2 = null; + try { + int port = ss.getLocalPort(); - int port = ss.getLocalPort(); + s1 = new Socket(InetAddress.getLocalHost(), port); + s2 = ss.accept(); - Socket s1 = new Socket(InetAddress.getLocalHost(), port); - Socket s2 = ss.accept(); + // close server socket and the accepted connection + ss.close(); + s2.close(); - // close server socket and the accepted connection - ss.close(); - s2.close(); - - boolean failed = false; + ss = new ServerSocket(); + ss.bind( new InetSocketAddress(port) ); + ss.close(); - ss = new ServerSocket(); - ss.bind( new InetSocketAddress(port) ); - ss.close(); - - // close the client socket - s1.close(); + // close the client socket + s1.close(); + } finally { + if (ss != null) ss.close(); + if (s1 != null) s1.close(); + if (s2 != null) s2.close(); + } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/SocketInputStream/SocketClosedException.java --- a/jdk/test/java/net/SocketInputStream/SocketClosedException.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/SocketInputStream/SocketClosedException.java Thu Aug 12 19:55:48 2010 -0700 @@ -32,68 +32,37 @@ import java.net.*; public class SocketClosedException { + static void doServerSide() throws Exception { + try { + Socket socket = serverSocket.accept(); - /* - * Is the server ready to serve? - */ - volatile static boolean serverReady = false; + OutputStream os = socket.getOutputStream(); - /* - * Define the server side of the test. - * - * If the server prematurely exits, serverReady will be set to true - * to avoid infinite hangs. - */ - static void doServerSide() throws Exception { - ServerSocket serverSocket = new ServerSocket(serverPort); - serverPort = serverSocket.getLocalPort(); - - /* - * Signal Client, we're ready for a connect. - */ - serverReady = true; - - Socket socket = serverSocket.accept(); - - InputStream is = socket.getInputStream(); - OutputStream os = socket.getOutputStream(); - - os.write(85); - os.flush(); - socket.close(); + os.write(85); + os.flush(); + socket.close(); + } finally { + serverSocket.close(); + } } - /* - * Define the client side of the test. - * - * If the server prematurely exits, serverReady will be set to true - * to avoid infinite hangs. - */ - static void doClientSide() throws Exception { + static void doClientSide(int port) throws Exception { + Socket socket = new Socket("localhost", port); + InputStream is = socket.getInputStream(); - /* - * Wait for server to get started. - */ - while (!serverReady) { - Thread.sleep(5000); - } - - Socket socket = new Socket("localhost", serverPort); - InputStream is = socket.getInputStream(); - OutputStream os = socket.getOutputStream(); - - int read = is.read(); + is.read(); socket.close(); - read = is.read(); + is.read(); } - static int serverPort = 0; + static ServerSocket serverSocket; static Exception serverException = null; public static void main(String[] args) throws Exception { + serverSocket = new ServerSocket(0); startServer(); try { - doClientSide(); + doClientSide(serverSocket.getLocalPort()); } catch (SocketException e) { if (!e.getMessage().equalsIgnoreCase("Socket closed")) { throw new Exception("Received a wrong exception message: " + @@ -108,21 +77,14 @@ } static void startServer() { - Thread serverThread = new Thread() { + (new Thread() { public void run() { try { doServerSide(); } catch (Exception e) { - /* - * server thread just died. - * Release the client, if not active already... - */ - System.err.println("Server died..."); - serverReady = true; - serverException = e; + e.printStackTrace(); } } - }; - serverThread.start(); + }).start(); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/SocketInputStream/SocketTimeout.java --- a/jdk/test/java/net/SocketInputStream/SocketTimeout.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/SocketInputStream/SocketTimeout.java Thu Aug 12 19:55:48 2010 -0700 @@ -31,26 +31,24 @@ import java.io.*; public class SocketTimeout { + static final int TIMEOUT = 1000; + public static void main(String args[]) throws Exception { - InetAddress sin = null; + InetAddress sin = InetAddress.getLocalHost(); Socket soc = null,soc1 = null; InputStream is = null; - OutputStream os = null; ServerSocket srv = null; int port = 0; - int tout = 1000; - sin = InetAddress.getLocalHost(); - srv = new ServerSocket(port); + srv = new ServerSocket(0); port = srv.getLocalPort(); soc = new Socket(sin, port); soc1 = srv.accept(); - soc.setSoTimeout(tout); - srv.setSoTimeout(tout); + soc.setSoTimeout(TIMEOUT); + srv.setSoTimeout(TIMEOUT); try { is = soc.getInputStream(); - os = soc1.getOutputStream(); is.read(); } catch(InterruptedIOException e) { try { @@ -59,6 +57,9 @@ } catch(NoClassDefFoundError e1) { throw new Exception ("SocketTimeoutException: not found"); } + } finally { + soc.close(); + soc1.close(); } // now check accept @@ -72,12 +73,14 @@ } catch(NoClassDefFoundError e1) { throw new Exception ("SocketTimeoutException: not found"); } + } finally { + srv.close(); } // Now check DatagramSocket.receive() DatagramSocket dg = new DatagramSocket (); - dg.setSoTimeout (tout); + dg.setSoTimeout (TIMEOUT); try { dg.receive (new DatagramPacket (new byte [64], 64)); @@ -88,11 +91,8 @@ } catch(NoClassDefFoundError e1) { throw new Exception ("SocketTimeoutException: not found"); } + } finally { + dg.close(); } - - soc.close(); - soc1.close(); - srv.close(); - dg.close(); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URL/GetContent.java --- a/jdk/test/java/net/URL/GetContent.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URL/GetContent.java Thu Aug 12 19:55:48 2010 -0700 @@ -53,11 +53,13 @@ // wait for client to read response - otherwise http // client get error and re-establish connection - Thread.currentThread().sleep(2000); + Thread.sleep(2000); s.close(); } catch (Exception e) { e.printStackTrace(); + } finally { + try { ss.close(); } catch (IOException unused) {} } } @@ -81,8 +83,6 @@ error = false; } - ss.close(); - if (error) throw new RuntimeException("No IOException generated."); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLClassLoader/ClassLoad.java --- a/jdk/test/java/net/URLClassLoader/ClassLoad.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLClassLoader/ClassLoad.java Thu Aug 12 19:55:48 2010 -0700 @@ -27,20 +27,45 @@ * @summary Test for FileNotFoundException when loading bogus class */ -import java.net.*; -import java.io.*; +import java.io.InputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.URL; +import java.net.URLClassLoader; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; public class ClassLoad { public static void main(String[] args) throws Exception { boolean error = true; + + // Start a dummy server to return 404 + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + HttpHandler handler = new HttpHandler() { + public void handle(HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + while (is.read() != -1); + t.sendResponseHeaders (404, -1); + t.close(); + } + }; + server.createContext("/", handler); + server.start(); + + // Client request try { - URL url = new URL(args.length >= 1 ? args[0] : "http://jini.east/"); + URL url = new URL("http://localhost:" + server.getAddress().getPort()); String name = args.length >= 2 ? args[1] : "foo.bar.Baz"; ClassLoader loader = new URLClassLoader(new URL[] { url }); + System.out.println(url); Class c = loader.loadClass(name); System.out.println("Loaded class \"" + c.getName() + "\"."); } catch (ClassNotFoundException ex) { + System.out.println(ex); error = false; + } finally { + server.stop(0); } if (error) throw new RuntimeException("No ClassNotFoundException generated"); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/DisconnectAfterEOF.java --- a/jdk/test/java/net/URLConnection/DisconnectAfterEOF.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/DisconnectAfterEOF.java Thu Aug 12 19:55:48 2010 -0700 @@ -56,7 +56,6 @@ int cl = -1; int remaining = -1; StringBuffer sb = new StringBuffer(); - Random r = new Random(); boolean close = false; boolean inBody = false; @@ -239,8 +238,6 @@ } public static void main(String args[]) throws Exception { - Random r = new Random(); - // start server ServerSocket ss = new ServerSocket(0); Server svr = new Server(ss); @@ -273,7 +270,7 @@ URLConnection uc1 = doRequest(uri); doResponse(uc1); - Thread.currentThread().sleep(2000); + Thread.sleep(2000); URLConnection uc2 = doRequest(uri); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/HandleContentTypeWithAttrs.java --- a/jdk/test/java/net/URLConnection/HandleContentTypeWithAttrs.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/HandleContentTypeWithAttrs.java Thu Aug 12 19:55:48 2010 -0700 @@ -111,9 +111,8 @@ } catch(Exception e) { System.out.print("Server failure\n"); e.printStackTrace(); - try { - serverSocket.close(); - } catch(IOException e2) {} + } finally { + try { serverSocket.close(); } catch(IOException unused) {} } } else { try { @@ -127,10 +126,9 @@ } catch(Exception e) { // System.out.print("Service handler failure\n"); // e.printStackTrace(); + } finally { + try { close(); } catch(IOException unused) {} } - try { - close(); - } catch(IOException e2) {} } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/HttpContinueStackOverflow.java --- a/jdk/test/java/net/URLConnection/HttpContinueStackOverflow.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/HttpContinueStackOverflow.java Thu Aug 12 19:55:48 2010 -0700 @@ -30,7 +30,7 @@ */ import java.io.BufferedReader; import java.io.InputStreamReader; -import java.io.OutputStreamWriter; +import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; @@ -41,61 +41,56 @@ static class Server implements Runnable { int port; + ServerSocket serverSock ; - Server(int port) { - this.port = port; + Server() throws IOException { + serverSock = new ServerSocket(0); + } + + int getLocalPort() { + return serverSock.getLocalPort(); } public void run() { + Socket sock = null; try { - /* bind to port and wait for connection */ - ServerSocket serverSock = new ServerSocket( port ); serverSock.setSoTimeout(10000); - Socket sock = serverSock.accept(); + sock = serverSock.accept(); /* setup streams and read http request */ BufferedReader in = new BufferedReader( new InputStreamReader(sock.getInputStream())); PrintStream out = new PrintStream( sock.getOutputStream() ); - String request = in.readLine(); + in.readLine(); /* send continue followed by invalid response */ out.println("HTTP/1.1 100 Continue\r"); out.println("\r"); out.println("junk junk junk"); out.flush(); - - sock.close(); } catch (Exception e) { e.printStackTrace(); + } finally { + try { serverSock.close(); } catch (IOException unused) {} + try { sock.close(); } catch (IOException unused) {} } } } - HttpContinueStackOverflow(int port) throws Exception { + HttpContinueStackOverflow() throws Exception { /* create the server */ - Server s = new Server(port); - Thread thr = new Thread(s); - thr.start(); - - /* wait for server to bind to port */ - try { - Thread.currentThread().sleep(2000); - } catch (Exception e) { } + Server s = new Server(); + (new Thread(s)).start(); /* connect to server, connect to server and get response code */ - URL url = new URL("http", "localhost", port, "anything.html"); + URL url = new URL("http", "localhost", s.getLocalPort(), "anything.html"); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - int respCode = conn.getResponseCode(); + conn.getResponseCode(); System.out.println("TEST PASSED"); } public static void main(String args[]) throws Exception { - int port = 4090; - if (args.length > 0) { - port = Integer.parseInt(args[0]); - } System.out.println("Testing 100-Continue"); - new HttpContinueStackOverflow(port); + new HttpContinueStackOverflow(); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/Redirect307Test.java --- a/jdk/test/java/net/URLConnection/Redirect307Test.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/Redirect307Test.java Thu Aug 12 19:55:48 2010 -0700 @@ -37,11 +37,11 @@ OutputStream os; int port; - String reply1 = "HTTP/1.1 307 Temporary Redirect\r\n" + + String reply1Part1 = "HTTP/1.1 307 Temporary Redirect\r\n" + "Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" + "Server: Apache/1.3.14 (Unix)\r\n" + "Location: http://localhost:"; - String reply2 = "/redirected.html\r\n" + + String reply1Part2 = "/redirected.html\r\n" + "Connection: close\r\n" + "Content-Type: text/html; charset=iso-8859-1\r\n\r\n" + "Hello"; @@ -49,9 +49,10 @@ RedirServer (ServerSocket y) { s = y; port = s.getLocalPort(); + System.out.println("Server created listening on " + port); } - String reply3 = "HTTP/1.1 200 Ok\r\n" + + String reply2 = "HTTP/1.1 200 Ok\r\n" + "Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" + "Server: Apache/1.3.14 (Unix)\r\n" + "Connection: close\r\n" + @@ -64,16 +65,24 @@ is = s1.getInputStream (); os = s1.getOutputStream (); is.read (); - String reply = reply1 + port + reply2; + String reply = reply1Part1 + port + reply1Part2; os.write (reply.getBytes()); + os.close(); /* wait for redirected connection */ s.setSoTimeout (5000); s1 = s.accept (); + is = s1.getInputStream (); os = s1.getOutputStream (); - os.write (reply3.getBytes()); + is.read(); + os.write (reply2.getBytes()); + os.close(); } catch (Exception e) { /* Just need thread to terminate */ + System.out.println("Server: caught " + e); + e.printStackTrace(); + } finally { + try { s.close(); } catch (IOException unused) {} } } }; @@ -84,10 +93,7 @@ public static final int DELAY = 10; public static void main(String[] args) throws Exception { - int nLoops = 1; - int nSize = 10; - int port, n =0; - byte b[] = new byte[nSize]; + int port; RedirServer server; ServerSocket sock; @@ -119,7 +125,8 @@ } } catch(IOException e) { - throw new RuntimeException ("Exception caught"); + e.printStackTrace(); + throw new RuntimeException ("Exception caught + " + e); } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/RedirectLimit.java --- a/jdk/test/java/net/URLConnection/RedirectLimit.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/RedirectLimit.java Thu Aug 12 19:55:48 2010 -0700 @@ -76,15 +76,19 @@ is.read (); String reply = reply1 + port + "/redirect" + i + reply2; os.write (reply.getBytes()); + os.close(); } s1 = s.accept (); is = s1.getInputStream (); os = s1.getOutputStream (); is.read (); os.write (reply3.getBytes()); + os.close(); } catch (Exception e) { /* Just need thread to terminate */ + } finally { + try { s.close(); } catch (IOException unused) {} } } }; diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/ResendPostBody.java --- a/jdk/test/java/net/URLConnection/ResendPostBody.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/ResendPostBody.java Thu Aug 12 19:55:48 2010 -0700 @@ -109,8 +109,11 @@ while (!finished()) { Thread.sleep (1000); } + out.close(); } catch (Exception e) { System.err.println ("Server Exception: " + e); + } finally { + try { server.close(); } catch (IOException unused) {} } } } @@ -134,7 +137,7 @@ public void execute () throws Exception { - byte b[] = "X=ABCDEFGHZZZ".getBytes(); + byte b[] = "X=ABCDEFGHZZZ".getBytes(); ss = new ServerSocket (0); server = new Server (ss); @@ -163,8 +166,9 @@ /* Read the response */ int resp = conURL.getResponseCode (); + server.setFinished (true); + if (resp != 200) throw new RuntimeException ("Response code was not 200: " + resp); - server.setFinished (true); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/SetIfModifiedSince.java --- a/jdk/test/java/net/URLConnection/SetIfModifiedSince.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/SetIfModifiedSince.java Thu Aug 12 19:55:48 2010 -0700 @@ -23,7 +23,7 @@ /* @test * @bug 4397096 - * @run main SetIfModifiedSince + * @run main/othervm SetIfModifiedSince * @summary setIfModifiedSince() of HttpURLConnection sets invalid date of default locale */ diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/TimeoutTest.java --- a/jdk/test/java/net/URLConnection/TimeoutTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/TimeoutTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -43,8 +43,9 @@ try { Socket s = server.accept (); while (!finished ()) { - Thread.sleep (2000); + Thread.sleep (1000); } + s.close(); } catch (Exception e) { } } @@ -70,9 +71,12 @@ URL url = new URL ("http://127.0.0.1:"+ss.getLocalPort()); URLConnection urlc = url.openConnection (); InputStream is = urlc.getInputStream (); + throw new RuntimeException("Should have received timeout"); } catch (SocketTimeoutException e) { - s.done (); return; + } finally { + s.done(); + ss.close(); } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/URLConnectionHeaders.java --- a/jdk/test/java/net/URLConnection/URLConnectionHeaders.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/URLConnectionHeaders.java Thu Aug 12 19:55:48 2010 -0700 @@ -70,8 +70,10 @@ w.newLine(); w.flush(); s.close (); - srv.close (); // or else the HTTPURLConnection will retry - } catch (IOException e) { e.printStackTrace();} + } catch (IOException e) { e.printStackTrace(); + } finally { + try { srv.close(); } catch (IOException unused) {} + } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/net/URLConnection/ZeroContentLength.java --- a/jdk/test/java/net/URLConnection/ZeroContentLength.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/net/URLConnection/ZeroContentLength.java Thu Aug 12 19:55:48 2010 -0700 @@ -58,6 +58,14 @@ contentLength = cl; } + static synchronized String getResponse() { + return response; + } + + static synchronized int getContentLength() { + return contentLength; + } + /* * Worker thread to service single connection - can service * multiple http requests on same connection. @@ -71,25 +79,44 @@ this.id = id; } + final int CR = '\r'; + final int LF = '\n'; + public void run() { try { s.setSoTimeout(2000); - int max = 100; + int max = 20; // there should only be 20 connections + InputStream in = new BufferedInputStream(s.getInputStream()); for (;;) { - - // read entire request from client - byte b[] = new byte[100]; - InputStream in = s.getInputStream(); - int n, total=0; + // read entire request from client, until CR LF CR LF + int c, total=0; try { - do { - n = in.read(b); - if (n > 0) total += n; - } while (n > 0); - } catch (SocketTimeoutException e) { } + while ((c = in.read()) > 0) { + total++; + if (c == CR) { + if ((c = in.read()) > 0) { + total++; + if (c == LF) { + if ((c = in.read()) > 0) { + total++; + if (c == CR) { + if ((c = in.read()) > 0) { + total++; + if (c == LF) { + break; + } + } + } + } + } + } + } + + } + } catch (SocketTimeoutException e) {} debug("worker " + id + ": Read request from client " + @@ -105,19 +132,20 @@ new BufferedOutputStream( s.getOutputStream() )); - out.print("HTTP/1.1 " + response + "\r\n"); - if (contentLength >= 0) { - out.print("Content-Length: " + contentLength + + out.print("HTTP/1.1 " + getResponse() + "\r\n"); + int clen = getContentLength(); + if (clen >= 0) { + out.print("Content-Length: " + clen + "\r\n"); } out.print("\r\n"); - for (int i=0; i upper || got < lower) { throw new RuntimeException ("checkTime failed: got " + got + " expected " + expected); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/nio/MappedByteBuffer/Basic.java --- a/jdk/test/java/nio/MappedByteBuffer/Basic.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/nio/MappedByteBuffer/Basic.java Thu Aug 12 19:55:48 2010 -0700 @@ -22,7 +22,7 @@ */ /* @test - * @bug 4462336 + * @bug 4462336 6799037 * @summary Simple MappedByteBuffer tests * @run main/othervm Basic */ @@ -52,6 +52,12 @@ mbb.force(); if (!mbb.isReadOnly()) throw new RuntimeException("Incorrect isReadOnly"); + + // repeat with unaligned position in file + mbb = fc.map(FileChannel.MapMode.READ_ONLY, 1, 10); + mbb.load(); + mbb.isLoaded(); + mbb.force(); fc.close(); fis.close(); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/nio/MappedByteBuffer/Truncate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/nio/MappedByteBuffer/Truncate.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6934977 + * @summary Test MappedByteBuffer operations after mapped bye buffer becomes + * inaccessible + * @run main/othervm Truncate + */ + +import java.io.*; +import java.nio.*; +import java.nio.channels.*; +import java.util.concurrent.Callable; + +public class Truncate { + + static final long INITIAL_FILE_SIZE = 32000L; + static final long TRUNCATED_FILE_SIZE = 512L; + + public static void main(String[] args) throws Exception { + File blah = File.createTempFile("blah", null); + blah.deleteOnExit(); + + final FileChannel fc = new RandomAccessFile(blah, "rw").getChannel(); + fc.position(INITIAL_FILE_SIZE).write(ByteBuffer.wrap("THE END".getBytes())); + final MappedByteBuffer mbb = + fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size()); + boolean truncated; + try { + fc.truncate(TRUNCATED_FILE_SIZE); + truncated = true; + } catch (IOException ioe) { + // probably on Windows where a file cannot be truncated when + // there is a file mapping. + truncated = false; + } + if (truncated) { + // Test 1: access region that is no longer accessible + execute(new Callable() { + public Void call() { + mbb.get((int)TRUNCATED_FILE_SIZE + 1); + mbb.put((int)TRUNCATED_FILE_SIZE + 2, (byte)123); + return null; + } + }); + // Test 2: load buffer into memory + execute(new Callable() { + public Void call() throws IOException { + mbb.load(); + return null; + } + }); + } + fc.close(); + } + + // Runs the given task in its own thread. If operating correcting the + // the thread will terminate with an InternalError as the mapped buffer + // is inaccessible. + static void execute(final Callable c) { + Runnable r = new Runnable() { + public void run() { + try { + Object ignore = c.call(); + } catch (Exception ignore) { + } + } + }; + Thread t = new Thread(r); + t.start(); + try { t.join(); } catch (InterruptedException ignore) { } + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/nio/channels/SocketChannel/OutOfBand.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/nio/channels/SocketChannel/OutOfBand.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2010, 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 Test socket adapter sendUrgentData method + * @bug 6963907 + */ + +import java.net.*; +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.io.IOException; +import java.util.Random; + +public class OutOfBand { + + private static final Random rand = new Random(); + + public static void main(String[] args) throws Exception { + ServerSocketChannel ssc = null; + SocketChannel sc1 = null; + SocketChannel sc2 = null; + + try { + + // establish loopback connection + ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0)); + InetAddress lh = InetAddress.getLocalHost(); + SocketAddress remote = + new InetSocketAddress(lh, ssc.socket().getLocalPort()); + sc1 = SocketChannel.open(remote); + sc2 = ssc.accept(); + + // enable SO_OOBLINE on server side + sc2.socket().setOOBInline(true); + + // run tests + test1(sc1, sc2); + test2(sc1, sc2); + test3(sc1, sc2); + test4(sc1); + + } finally { + if (sc1 != null) sc1.close(); + if (sc2 != null) sc2.close(); + if (ssc != null) ssc.close(); + } + } + + /** + * Basic test to check that OOB/TCP urgent byte is received. + */ + static void test1(SocketChannel client, SocketChannel server) + throws Exception + { + assert server.socket().getOOBInline(); + ByteBuffer bb = ByteBuffer.allocate(100); + for (int i=0; i<1000; i++) { + int b1 = -127 + rand.nextInt(384); + client.socket().sendUrgentData(b1); + + bb.clear(); + if (server.read(bb) != 1) + throw new RuntimeException("One byte expected"); + bb.flip(); + byte b2 = bb.get(); + if ((byte)b1 != b2) + throw new RuntimeException("Unexpected byte"); + } + } + + /** + * Basic test to check that OOB/TCP urgent byte is received, maybe with + * OOB mark changing. + */ + static void test2(final SocketChannel client, SocketChannel server) + throws Exception + { + assert server.socket().getOOBInline(); + Runnable sender = new Runnable() { + public void run() { + try { + for (int i=0; i<256; i++) + client.socket().sendUrgentData(i); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + }; + Thread thr = new Thread(sender); + thr.start(); + + ByteBuffer bb = ByteBuffer.allocate(256); + while (bb.hasRemaining()) { + if (server.read(bb) < 0) + throw new RuntimeException("Unexpected EOF"); + } + bb.flip(); + byte expect = 0; + while (bb.hasRemaining()) { + if (bb.get() != expect) + throw new RuntimeException("Unexpected byte"); + expect++; + } + + thr.join(); + } + + /** + * Test that is close to some real world examples where an urgent byte is + * used to "cancel" a long running query or transaction on the server. + */ + static void test3(SocketChannel client, final SocketChannel server) + throws Exception + { + final int STOP = rand.nextInt(256); + + assert server.socket().getOOBInline(); + Runnable reader = new Runnable() { + public void run() { + ByteBuffer bb = ByteBuffer.allocate(100); + try { + int n = server.read(bb); + if (n != 1) { + String msg = (n < 0) ? "Unexpected EOF" : + "One byte expected"; + throw new RuntimeException(msg); + } + bb.flip(); + if (bb.get() != (byte)STOP) + throw new RuntimeException("Unexpected byte"); + bb.flip(); + server.write(bb); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + + } + }; + + Thread thr = new Thread(reader); + thr.start(); + + // "stop" server + client.socket().sendUrgentData(STOP); + + // wait for server reply + ByteBuffer bb = ByteBuffer.allocate(100); + int n = client.read(bb); + if (n != 1) + throw new RuntimeException("Unexpected number of bytes"); + bb.flip(); + if (bb.get() != (byte)STOP) + throw new RuntimeException("Unexpected reply"); + + thr.join(); + } + + static void test4(SocketChannel sc) throws IOException { + boolean blocking = sc.isBlocking(); + sc.configureBlocking(false); + try { + sc.socket().sendUrgentData(0); + throw new RuntimeException("IllegalBlockingModeException expected"); + } catch (IllegalBlockingModeException x) { + // expected + } finally { + sc.configureBlocking(blocking); + } + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java --- a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.java Thu Aug 12 19:55:48 2010 -0700 @@ -23,24 +23,32 @@ import java.util.logging.*; -public class AnonLoggerWeakRefLeak { - public static int DEFAULT_LOOP_TIME = 60; // time is in seconds +public class AnonLoggerWeakRefLeak extends SimpleApplication { + // The test driver script will allow this program to run until we + // reach DEFAULT_LOOP_TIME or a decrease in instance counts is + // observed. For this particular WeakReference leak, the count + // was always observed to be increasing so if we get a decreasing + // count, then the leak is fixed in the bits being tested. + // Two minutes has been enough time to observe a decrease in + // fixed bits on overloaded systems, but the test will likely + // finish more quickly. + public static int DEFAULT_LOOP_TIME = 120; // time is in seconds - public static void main(String[] args) { + // execute the AnonLoggerWeakRefLeak app work + public void doMyAppWork(String[] args) throws Exception { int loop_time = 0; int max_loop_time = DEFAULT_LOOP_TIME; - if (args.length == 0) { + // args[0] is the port-file + if (args.length < 2) { System.out.println("INFO: using default time of " + max_loop_time + " seconds."); } else { try { - max_loop_time = Integer.parseInt(args[0]); + max_loop_time = Integer.parseInt(args[1]); } catch (NumberFormatException nfe) { - System.err.println("Error: '" + args[0] + throw new RuntimeException("Error: '" + args[1] + "': is not a valid seconds value."); - System.err.println("Usage: AnonLoggerWeakRefLeak [seconds]"); - System.exit(1); } } @@ -73,4 +81,12 @@ System.out.println("INFO: final loop count = " + count); } + + public static void main(String[] args) throws Exception { + AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak(); + + SimpleApplication.setMyApp(myApp); + + SimpleApplication.main(args); + } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh --- a/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/util/logging/AnonLoggerWeakRefLeak.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,3 +1,5 @@ +#!/bin/sh + # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -23,76 +25,24 @@ # @test # @bug 6942989 -# @ignore until 6964018 is fixed # @summary Check for WeakReference leak in anonymous Logger objects # @author Daniel D. Daugherty # -# @run build AnonLoggerWeakRefLeak -# @run shell/timeout=180 AnonLoggerWeakRefLeak.sh +# @library ../../../sun/tools/common +# @build SimpleApplication ShutdownSimpleApplication +# @build AnonLoggerWeakRefLeak +# @run shell/timeout=240 AnonLoggerWeakRefLeak.sh -# The timeout is: 2 minutes for infrastructure and 1 minute for the test +# The timeout is: 2 minutes for infrastructure and 2 minutes for the test # -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi +. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh +. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -JAVA="${TESTJAVA}"/bin/java -JMAP="${TESTJAVA}"/bin/jmap -JPS="${TESTJAVA}"/bin/jps - -set -eu TEST_NAME="AnonLoggerWeakRefLeak" TARGET_CLASS="java\.lang\.ref\.WeakReference" -is_cygwin=false -is_mks=false -is_windows=false - -case `uname -s` in -CYGWIN*) - is_cygwin=true - is_windows=true - ;; -Windows_*) - is_mks=true - is_windows=true - ;; -*) - ;; -esac - - -# wrapper for grep -# -grep_cmd() { - set +e - if $is_windows; then - # need dos2unix to get rid of CTRL-M chars from java output - dos2unix | grep "$@" - status="$?" - else - grep "$@" - status="$?" - fi - set -e -} - # MAIN begins here # @@ -105,62 +55,64 @@ # see if this version of jmap supports the '-histo:live' option jmap_option="-histo:live" set +e -"${JMAP}" "$jmap_option" 0 > "$TEST_NAME.jmap" 2>&1 -grep '^Usage: ' "$TEST_NAME.jmap" > /dev/null 2>&1 +"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1 status="$?" set -e -if [ "$status" = 0 ]; then - echo "INFO: switching jmap option from '$jmap_option'\c" - jmap_option="-histo" - echo " to '$jmap_option'." +if [ "$status" != 0 ]; then + # usage message doesn't show ':live' option + + if $isWindows; then + # If SA isn't present, then jmap gives a different usage message + # that doesn't show the ':live' option. However, that's a bug that + # is covered by 6971851 so we try using the option just to be sure. + # For some reason, this problem has only been seen on OpenJDK6 on + # Windows. Not sure why. + set +e + # Note: Don't copy this code to try probing process 0 on Linux; it + # will kill the process group in strange ways. + "${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1 + status="$?" + set -e + if [ "$status" = 0 ]; then + # Usage message generated so flag the problem. + status=1 + else + # No usage message so clear the flag. + status=0 + fi + fi + + if [ "$status" != 0 ]; then + echo "ERROR: 'jmap $jmap_option' is not supported so this test" + echo "ERROR: cannot work reliably. Aborting!" + exit 2 + fi fi -"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" \ - "$TEST_NAME" $seconds > "$TEST_NAME.log" 2>&1 & -test_pid="$!" -echo "INFO: starting $TEST_NAME as pid = $test_pid" - -# wait for test program to get going -count=0 -while [ "$count" -lt 30 ]; do - sleep 2 - grep_cmd '^INFO: call count = 0$' < "$TEST_NAME.log" > /dev/null 2>&1 - if [ "$status" = 0 ]; then - break - fi - count=`expr $count + 1` -done +# Start application and use TEST_NAME.port for coordination +startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds -if [ "$count" -ge 30 ]; then - echo "ERROR: $TEST_NAME failed to get going." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" - exit 1 -elif [ "$count" -gt 1 ]; then - echo "INFO: $TEST_NAME took $count loops to start." -fi - -if $is_cygwin; then - # We need the Windows pid for jmap and not the Cygwin pid. - # Note: '\t' works on Cygwin, but doesn't seem to work on Solaris. - jmap_pid=`"${JPS}"| grep_cmd "[ \t]$TEST_NAME$" | sed 's/[ \t].*//'` - if [ -z "$jmap_pid" ]; then - echo "FAIL: jps could not map Cygwin pid to Windows pid." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" - exit 2 - fi - echo "INFO: pid = $test_pid maps to Windows pid = $jmap_pid" -else - jmap_pid="$test_pid" -fi +finished_early=false decreasing_cnt=0 increasing_cnt=0 loop_cnt=0 prev_instance_cnt=0 +MAX_JMAP_TRY_CNT=10 +jmap_retry_cnt=0 +loop_cnt_on_retry=0 + while true; do + # see if the target process has finished its run and bail if it has + set +e + grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1 + status="$?" + set -e + if [ "$status" = 0 ]; then + break + fi + # Output format for 'jmap -histo' in JDK1.5.0: # # <#bytes> <#instances> @@ -170,38 +122,70 @@ # : <#instances> <#bytes> # set +e - "${JMAP}" "$jmap_option" "$jmap_pid" > "$TEST_NAME.jmap" 2>&1 + "${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1 status="$?" set -e if [ "$status" != 0 ]; then echo "INFO: jmap exited with exit code = $status" - if [ "$loop_cnt" = 0 ]; then - echo "INFO: on the first iteration so no samples were taken." - echo "INFO: start of jmap output:" - cat "$TEST_NAME.jmap" - echo "INFO: end of jmap output." + + # There are intermittent jmap failures; see 6498448. + # + # So far the following have been observed in a jmap call + # that was not in a race with target process termination: + # + # (Solaris specific, 2nd sample) + # : Unable to open door: target process not responding or HotSpot VM not loaded + # The -F option can be used when the target process is not responding + # + # (on Solaris so far) + # java.io.IOException + # + # (on Solaris so far, 1st sample) + # : Permission denied + # + sed 's/^/INFO: /' "$TEST_NAME.jmap" + + if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then + # loop count hasn't changed + jmap_retry_cnt=`expr $jmap_retry_cnt + 1` + else + # loop count has changed so remember it + jmap_retry_cnt=1 + loop_cnt_on_retry="$loop_cnt" + fi + + # This is '-ge' because we have the original attempt plus + # MAX_JMAP_TRY_CNT - 1 retries. + if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then + echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \ + "without making any progress." echo "FAIL: jmap is unable to take any samples." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" + killApplication exit 2 fi - echo "INFO: The likely reason is that $TEST_NAME has finished running." - break + + # short delay and try again + # Note: sleep 1 didn't help with ": Permission denied" + sleep 2 + echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)." + continue fi - instance_cnt=`grep_cmd "[ ]$TARGET_CLASS$" \ - < "$TEST_NAME.jmap" \ + set +e + instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \ + "$TEST_NAME.jmap" \ | sed ' # strip leading whitespace; does nothing in JDK1.5.0 - s/^[ ][ ]*// + s/^'"${PATTERN_WS}${PATTERN_WS}"'*// # strip <#bytes> in JDK1.5.0; does nothing otherwise - s/^[1-9][0-9]*[ ][ ]*// + s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// # strip : field; does nothing in JDK1.5.0 - s/^[1-9][0-9]*:[ ][ ]*// + s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*// # strip field - s/[ ].*// + s/'"${PATTERN_WS}"'.*// '` + set -e if [ -z "$instance_cnt" ]; then echo "INFO: instance count is unexpectedly empty" if [ "$loop_cnt" = 0 ]; then @@ -211,8 +195,7 @@ cat "$TEST_NAME.jmap" echo "INFO: end of jmap output." echo "FAIL: cannot find the instance count value." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" + killApplication exit 2 fi else @@ -221,7 +204,17 @@ if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then increasing_cnt=`expr $increasing_cnt + 1` else + # actually decreasing or the same decreasing_cnt=`expr $decreasing_cnt + 1` + + # For this particular WeakReference leak, the count was + # always observed to be increasing so if we get a decreasing + # or the same count, then the leak is fixed in the bits + # being tested. + echo "INFO: finishing early due to non-increasing instance count." + finished_early=true + killApplication + break fi prev_instance_cnt="$instance_cnt" fi @@ -232,8 +225,22 @@ loop_cnt=`expr $loop_cnt + 1` done +if [ $finished_early = false ]; then + stopApplication "$TEST_NAME.port" + waitForApplication +fi + +echo "INFO: $TEST_NAME has finished running." echo "INFO: increasing_cnt = $increasing_cnt" echo "INFO: decreasing_cnt = $decreasing_cnt" +if [ "$jmap_retry_cnt" -gt 0 ]; then + echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)" +fi + +if [ "$loop_cnt" = 0 ]; then + echo "FAIL: jmap is unable to take any samples." >&2 + exit 2 +fi echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" if [ "$decreasing_cnt" = 0 ]; then @@ -242,6 +249,6 @@ exit 2 fi -echo "INFO: is both increasing and decreasing." +echo "INFO: is not always increasing." echo "PASS: This indicates that there is not a memory leak." exit 0 diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/util/logging/LoggerWeakRefLeak.java --- a/jdk/test/java/util/logging/LoggerWeakRefLeak.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/util/logging/LoggerWeakRefLeak.java Thu Aug 12 19:55:48 2010 -0700 @@ -23,27 +23,32 @@ import java.util.logging.*; -public class LoggerWeakRefLeak { - // AnonLoggerWeakRefLeak checks for one weak reference leak. - // LoggerWeakRefLeak checks for two weak reference leaks so - // this test runs twice as long, by default. +public class LoggerWeakRefLeak extends SimpleApplication { + // The test driver script will allow this program to run until we + // reach DEFAULT_LOOP_TIME or a decrease in instance counts is + // observed. For these particular WeakReference leaks, the count + // was always observed to be increasing so if we get a decreasing + // count, then the leaks are fixed in the bits being tested. + // Two minutes has been enough time to observe a decrease in + // fixed bits on overloaded systems, but the test will likely + // finish more quickly. public static int DEFAULT_LOOP_TIME = 120; // time is in seconds - public static void main(String[] args) { + // execute the LoggerWeakRefLeak app work + public void doMyAppWork(String[] args) throws Exception { int loop_time = 0; int max_loop_time = DEFAULT_LOOP_TIME; - if (args.length == 0) { + // args[0] is the port-file + if (args.length < 2) { System.out.println("INFO: using default time of " + max_loop_time + " seconds."); } else { try { - max_loop_time = Integer.parseInt(args[0]); + max_loop_time = Integer.parseInt(args[1]); } catch (NumberFormatException nfe) { - System.err.println("Error: '" + args[0] + throw new RuntimeException("Error: '" + args[1] + "': is not a valid seconds value."); - System.err.println("Usage: LoggerWeakRefLeak [seconds]"); - System.exit(1); } } @@ -86,4 +91,12 @@ System.out.println("INFO: final loop count = " + count); } + + public static void main(String[] args) throws Exception { + AnonLoggerWeakRefLeak myApp = new AnonLoggerWeakRefLeak(); + + SimpleApplication.setMyApp(myApp); + + SimpleApplication.main(args); + } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/java/util/logging/LoggerWeakRefLeak.sh --- a/jdk/test/java/util/logging/LoggerWeakRefLeak.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/java/util/logging/LoggerWeakRefLeak.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,3 +1,5 @@ +#!/bin/sh + # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -23,76 +25,24 @@ # @test # @bug 6942989 -# @ignore until 6964018 is fixed # @summary Check for WeakReference leak in Logger objects # @author Daniel D. Daugherty # -# @run build LoggerWeakRefLeak +# @library ../../../sun/tools/common +# @build SimpleApplication ShutdownSimpleApplication +# @build LoggerWeakRefLeak # @run shell/timeout=240 LoggerWeakRefLeak.sh -# The timeout is: 2 minutes for infrastructure and 1 minute for the test +# The timeout is: 2 minutes for infrastructure and 2 minutes for the test # -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi +. ${TESTSRC}/../../../sun/tools/common/CommonSetup.sh +. ${TESTSRC}/../../../sun/tools/common/ApplicationSetup.sh -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -JAVA="${TESTJAVA}"/bin/java -JMAP="${TESTJAVA}"/bin/jmap -JPS="${TESTJAVA}"/bin/jps - -set -eu TEST_NAME="LoggerWeakRefLeak" TARGET_CLASS="java\.lang\.ref\.WeakReference" -is_cygwin=false -is_mks=false -is_windows=false - -case `uname -s` in -CYGWIN*) - is_cygwin=true - is_windows=true - ;; -Windows_*) - is_mks=true - is_windows=true - ;; -*) - ;; -esac - - -# wrapper for grep -# -grep_cmd() { - set +e - if $is_windows; then - # need dos2unix to get rid of CTRL-M chars from java output - dos2unix | grep "$@" - status="$?" - else - grep "$@" - status="$?" - fi - set -e -} - # MAIN begins here # @@ -105,62 +55,64 @@ # see if this version of jmap supports the '-histo:live' option jmap_option="-histo:live" set +e -"${JMAP}" "$jmap_option" 0 > "$TEST_NAME.jmap" 2>&1 -grep '^Usage: ' "$TEST_NAME.jmap" > /dev/null 2>&1 +"${JMAP}" 2>&1 | grep ':live' > /dev/null 2>&1 status="$?" set -e -if [ "$status" = 0 ]; then - echo "INFO: switching jmap option from '$jmap_option'\c" - jmap_option="-histo" - echo " to '$jmap_option'." +if [ "$status" != 0 ]; then + # usage message doesn't show ':live' option + + if $isWindows; then + # If SA isn't present, then jmap gives a different usage message + # that doesn't show the ':live' option. However, that's a bug that + # is covered by 6971851 so we try using the option just to be sure. + # For some reason, this problem has only been seen on OpenJDK6 on + # Windows. Not sure why. + set +e + # Note: Don't copy this code to try probing process 0 on Linux; it + # will kill the process group in strange ways. + "${JMAP}" "$jmap_option" 0 2>&1 | grep 'Usage' > /dev/null 2>&1 + status="$?" + set -e + if [ "$status" = 0 ]; then + # Usage message generated so flag the problem. + status=1 + else + # No usage message so clear the flag. + status=0 + fi + fi + + if [ "$status" != 0 ]; then + echo "ERROR: 'jmap $jmap_option' is not supported so this test" + echo "ERROR: cannot work reliably. Aborting!" + exit 2 + fi fi -"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" \ - "$TEST_NAME" $seconds > "$TEST_NAME.log" 2>&1 & -test_pid="$!" -echo "INFO: starting $TEST_NAME as pid = $test_pid" - -# wait for test program to get going -count=0 -while [ "$count" -lt 30 ]; do - sleep 2 - grep_cmd '^INFO: call count = 0$' < "$TEST_NAME.log" > /dev/null 2>&1 - if [ "$status" = 0 ]; then - break - fi - count=`expr $count + 1` -done +# Start application and use TEST_NAME.port for coordination +startApplication "$TEST_NAME" "$TEST_NAME.port" $seconds -if [ "$count" -ge 30 ]; then - echo "ERROR: $TEST_NAME failed to get going." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" - exit 1 -elif [ "$count" -gt 1 ]; then - echo "INFO: $TEST_NAME took $count loops to start." -fi - -if $is_cygwin; then - # We need the Windows pid for jmap and not the Cygwin pid. - # Note: '\t' works on Cygwin, but doesn't seem to work on Solaris. - jmap_pid=`"${JPS}"| grep_cmd "[ \t]$TEST_NAME$" | sed 's/[ \t].*//'` - if [ -z "$jmap_pid" ]; then - echo "FAIL: jps could not map Cygwin pid to Windows pid." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" - exit 2 - fi - echo "INFO: pid = $test_pid maps to Windows pid = $jmap_pid" -else - jmap_pid="$test_pid" -fi +finished_early=false decreasing_cnt=0 increasing_cnt=0 loop_cnt=0 prev_instance_cnt=0 +MAX_JMAP_TRY_CNT=10 +jmap_retry_cnt=0 +loop_cnt_on_retry=0 + while true; do + # see if the target process has finished its run and bail if it has + set +e + grep "^INFO: final loop count = " "$appOutput" > /dev/null 2>&1 + status="$?" + set -e + if [ "$status" = 0 ]; then + break + fi + # Output format for 'jmap -histo' in JDK1.5.0: # # <#bytes> <#instances> @@ -170,38 +122,70 @@ # : <#instances> <#bytes> # set +e - "${JMAP}" "$jmap_option" "$jmap_pid" > "$TEST_NAME.jmap" 2>&1 + "${JMAP}" "$jmap_option" "$appJavaPid" > "$TEST_NAME.jmap" 2>&1 status="$?" set -e if [ "$status" != 0 ]; then echo "INFO: jmap exited with exit code = $status" - if [ "$loop_cnt" = 0 ]; then - echo "INFO: on the first iteration so no samples were taken." - echo "INFO: start of jmap output:" - cat "$TEST_NAME.jmap" - echo "INFO: end of jmap output." + + # There are intermittent jmap failures; see 6498448. + # + # So far the following have been observed in a jmap call + # that was not in a race with target process termination: + # + # (Solaris specific, 2nd sample) + # : Unable to open door: target process not responding or HotSpot VM not loaded + # The -F option can be used when the target process is not responding + # + # (on Solaris so far) + # java.io.IOException + # + # (on Solaris so far, 1st sample) + # : Permission denied + # + sed 's/^/INFO: /' "$TEST_NAME.jmap" + + if [ "$loop_cnt" = "$loop_cnt_on_retry" ]; then + # loop count hasn't changed + jmap_retry_cnt=`expr $jmap_retry_cnt + 1` + else + # loop count has changed so remember it + jmap_retry_cnt=1 + loop_cnt_on_retry="$loop_cnt" + fi + + # This is '-ge' because we have the original attempt plus + # MAX_JMAP_TRY_CNT - 1 retries. + if [ "$jmap_retry_cnt" -ge "$MAX_JMAP_TRY_CNT" ]; then + echo "INFO: jmap failed $MAX_JMAP_TRY_CNT times in a row" \ + "without making any progress." echo "FAIL: jmap is unable to take any samples." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" + killApplication exit 2 fi - echo "INFO: The likely reason is that $TEST_NAME has finished running." - break + + # short delay and try again + # Note: sleep 1 didn't help with ": Permission denied" + sleep 2 + echo "INFO: retrying jmap (retry=$jmap_retry_cnt, loop=$loop_cnt)." + continue fi - instance_cnt=`grep_cmd "[ ]$TARGET_CLASS$" \ - < "$TEST_NAME.jmap" \ + set +e + instance_cnt=`grep "${PATTERN_WS}${TARGET_CLASS}${PATTERN_EOL}" \ + "$TEST_NAME.jmap" \ | sed ' # strip leading whitespace; does nothing in JDK1.5.0 - s/^[ ][ ]*// + s/^'"${PATTERN_WS}${PATTERN_WS}"'*// # strip <#bytes> in JDK1.5.0; does nothing otherwise - s/^[1-9][0-9]*[ ][ ]*// + s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// # strip : field; does nothing in JDK1.5.0 - s/^[1-9][0-9]*:[ ][ ]*// + s/^[1-9][0-9]*:'"${PATTERN_WS}${PATTERN_WS}"'*// # strip field - s/[ ].*// + s/'"${PATTERN_WS}"'.*// '` + set -e if [ -z "$instance_cnt" ]; then echo "INFO: instance count is unexpectedly empty" if [ "$loop_cnt" = 0 ]; then @@ -211,8 +195,7 @@ cat "$TEST_NAME.jmap" echo "INFO: end of jmap output." echo "FAIL: cannot find the instance count value." >&2 - echo "INFO: killing $test_pid" - kill "$test_pid" + killApplication exit 2 fi else @@ -221,7 +204,17 @@ if [ "$instance_cnt" -gt "$prev_instance_cnt" ]; then increasing_cnt=`expr $increasing_cnt + 1` else + # actually decreasing or the same decreasing_cnt=`expr $decreasing_cnt + 1` + + # For these particular WeakReference leaks, the count was + # always observed to be increasing so if we get a decreasing + # or the same count, then the leaks are fixed in the bits + # being tested. + echo "INFO: finishing early due to non-increasing instance count." + finished_early=true + killApplication + break fi prev_instance_cnt="$instance_cnt" fi @@ -232,8 +225,22 @@ loop_cnt=`expr $loop_cnt + 1` done +if [ $finished_early = false ]; then + stopApplication "$TEST_NAME.port" + waitForApplication +fi + +echo "INFO: $TEST_NAME has finished running." echo "INFO: increasing_cnt = $increasing_cnt" echo "INFO: decreasing_cnt = $decreasing_cnt" +if [ "$jmap_retry_cnt" -gt 0 ]; then + echo "INFO: jmap_retry_cnt = $jmap_retry_cnt (in $loop_cnt iterations)" +fi + +if [ "$loop_cnt" = 0 ]; then + echo "FAIL: jmap is unable to take any samples." >&2 + exit 2 +fi echo "INFO: The instance count of" `eval echo $TARGET_CLASS` "objects" if [ "$decreasing_cnt" = 0 ]; then @@ -242,6 +249,6 @@ exit 2 fi -echo "INFO: is both increasing and decreasing." +echo "INFO: is not always increasing." echo "PASS: This indicates that there is not a memory leak." exit 0 diff -r 96a57de47def -r 67584b95a0f0 jdk/test/javax/swing/JColorChooser/Test6199676.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JColorChooser/Test6199676.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6199676 + * @summary Tests preview panel after L&F changing + * @author Sergey Malenkov + */ + +import java.awt.Component; +import java.awt.Container; +import javax.swing.JColorChooser; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; + +public class Test6199676 implements Runnable { + public static void main(String[] args) { + SwingUtilities.invokeLater(new Test6199676()); + } + + private static void exit(String error) { + if (error != null) { + System.err.println(error); + System.exit(1); + } + else { + System.exit(0); + } + } + + private static Component getPreview(Container container) { + String name = "ColorChooser.previewPanelHolder"; + for (Component component : container.getComponents()) { + if (!name.equals(component.getName())) { + component = (component instanceof Container) + ? getPreview((Container) component) + : null; + } + if (component instanceof Container) { + container = (Container) component; + return 1 == container.getComponentCount() + ? container.getComponent(0) + : null; + } + } + return null; + } + + private static boolean isShowing(Component component) { + return (component != null) && component.isShowing(); + } + + private int index; + private boolean updated; + private JColorChooser chooser; + + public synchronized void run() { + if (this.chooser == null) { + this.chooser = new JColorChooser(); + + JFrame frame = new JFrame(getClass().getName()); + frame.add(this.chooser); + frame.setVisible(true); + } + else if (this.updated) { + if (isShowing(this.chooser.getPreviewPanel())) { + exit("custom preview panel is showing"); + } + exit(null); + } + else { + Component component = this.chooser.getPreviewPanel(); + if (component == null) { + component = getPreview(this.chooser); + } + if (!isShowing(component)) { + exit("default preview panel is not showing"); + } + this.updated = true; + this.chooser.setPreviewPanel(new JPanel()); + } + LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels(); + LookAndFeelInfo info = infos[++this.index % infos.length]; + try { + UIManager.setLookAndFeel(info.getClassName()); + } + catch (Exception exception) { + exit("could not change L&F"); + } + SwingUtilities.updateComponentTreeUI(this.chooser); + SwingUtilities.invokeLater(this); + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/javax/swing/JComboBox/4743225/bug4743225.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JComboBox/4743225/bug4743225.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2010, 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 + * @bug 4743225 + * @summary Size of JComboBox list is wrong when list is populated via PopupMenuListener + * @author Alexander Potochkin + */ + +import sun.awt.SunToolkit; + +import javax.accessibility.AccessibleContext; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import javax.swing.plaf.basic.BasicComboPopup; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; + +public class bug4743225 extends JFrame { + + private static JComboBox cb; + private static volatile boolean flag; + + public bug4743225() { + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setLayout(new FlowLayout()); + cb = new JComboBox(new Object[] {"one", "two", "three"}); + cb.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + cb.addItem("Test"); + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + } + + public void popupMenuCanceled(PopupMenuEvent e) { + } + }); + add(cb); + pack(); + } + + public static BasicComboPopup getPopup() { + AccessibleContext c = cb.getAccessibleContext(); + for(int i = 0; i < c.getAccessibleChildrenCount(); i ++) { + if (c.getAccessibleChild(i) instanceof BasicComboPopup) { + return (BasicComboPopup) c.getAccessibleChild(i); + } + } + throw new AssertionError("No BasicComboPopup found"); + } + + public static void main(String... args) throws Exception { + + Robot robot = new Robot(); + robot.setAutoDelay(20); + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + new bug4743225().setVisible(true); + } + }); + toolkit.realSync(); + + // calling this method from main thread is ok + Point point = cb.getLocationOnScreen(); + robot.mouseMove(point.x + 10, point.y + 10); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + if(getPopup().getList().getLastVisibleIndex() == 3) { + flag = true; + } + } + }); + + if (!flag) { + throw new RuntimeException("The ComboBox popup wasn't correctly updated"); + } + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/javax/swing/JFormattedTextField/Test6462562.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JFormattedTextField/Test6462562.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2010, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + @bug 6462562 + @summary Tests text input into JFormattedTextField + with an InternationalFormatter + @author Peter Zhelezniakov + @run main Test6462562 +*/ + +import java.awt.event.ActionEvent; +import java.text.DateFormat; +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import javax.swing.Action; +import javax.swing.JFormattedTextField; +import javax.swing.SwingUtilities; +import javax.swing.text.Caret; +import javax.swing.text.DateFormatter; +import javax.swing.text.DefaultEditorKit; +import javax.swing.text.InternationalFormatter; +import javax.swing.text.NumberFormatter; + + +public class Test6462562 +{ + static final String BACKSPACE = new String("backspace"); + static final String DELETE = new String("delete"); + + boolean failed = false; + + void test() { + testPercentFormat(); + testCurrencyFormat(); + testIntegerFormat(); + testDateFormat(); + + if (failed) { + throw new RuntimeException("Some testcases failed, see output above"); + } + System.err.println("(-; All testcases passed ;-)"); + } + + TestFormattedTextField create(NumberFormat format) { + format.setMaximumFractionDigits(0); + NumberFormatter fmt = new NumberFormatter(format); + return new TestFormattedTextField(fmt); + } + + TestFormattedTextField create(DateFormat format) { + DateFormatter fmt = new DateFormatter(format); + return new TestFormattedTextField(fmt); + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + new Test6462562().test(); + } + }); + } + + class TestFormattedTextField extends JFormattedTextField + { + final Action backspace; + final Action delete; + final Action insert; + + final ActionEvent dummyEvent; + + public TestFormattedTextField(InternationalFormatter fmt) { + super(fmt); + fmt.setAllowsInvalid(false); + fmt.setOverwriteMode(true); + + backspace = getActionMap().get(DefaultEditorKit.deletePrevCharAction); + delete = getActionMap().get(DefaultEditorKit.deleteNextCharAction); + insert = getActionMap().get(DefaultEditorKit.insertContentAction); + dummyEvent = new ActionEvent(this, 0, null); + } + + public boolean test(int pos, int selectionLength, String todo, Object expectedResult) { + Object v0 = getValue(); + + Caret caret = getCaret(); + caret.setDot(pos); + if (selectionLength > 0) { + caret.moveDot(pos + selectionLength); + } + + String desc = todo; + if (todo == BACKSPACE) { + backspace.actionPerformed(dummyEvent); + } else if (todo == DELETE) { + delete.actionPerformed(dummyEvent); + } else { + desc = "insert('" + todo + "')"; + insert.actionPerformed(new ActionEvent(this, 0, todo)); + } + + try { + commitEdit(); + } catch (ParseException e) { + e.printStackTrace(); + failed = true; + return false; + } + + Object v1 = getValue(); + if (! v1.equals(expectedResult)) { + System.err.printf("Failure: value='%s', mark=%d, dot=%d, action=%s\n", + v0, pos, pos + selectionLength, desc); + System.err.printf(" Result: '%s', expected: '%s'\n", v1, expectedResult); + failed = true; + return false; + } + return true; + } + } + + void testPercentFormat() { + NumberFormat format = NumberFormat.getPercentInstance(Locale.US); + TestFormattedTextField ftf = create(format); + ftf.setValue(.34); + + System.err.println("Testing NumberFormat.getPercentInstance(Locale.US)"); + + // test inserting individual characters + ftf.test(0, 0, "1", .14); + ftf.test(2, 0, "2", 1.42); + ftf.test(1, 0, "0", 1.02); + + // test inserting several characters at once - e.g. from clipboard + ftf.test(0, 0, "1024", 10.24); + ftf.test(3, 0, "333", 103.33); + ftf.test(6, 0, "77", 10333.77); + ftf.test(4, 0, "99", 10399.77); + ftf.test(6, 0, "00", 10390.07); + + // test inserting strings that contain some formatting + ftf.test(0, 0, "2,2", 2290.07); + ftf.test(2, 0, "2,2", 222.27); + ftf.test(4, 0, "2,2", 222.22); + ftf.test(6, 0, "33,33", 2222233.33); + + // test delete + ftf.test(0, 0, DELETE, 222233.33); + ftf.test(10, 0, DELETE, 222233.33); + ftf.test(5, 0, DELETE, 22223.33); + ftf.test(6, 0, DELETE, 2222.33); + + // test backspace + ftf.test(0, 0, BACKSPACE, 2222.33); + ftf.test(7, 0, BACKSPACE, 222.23); + ftf.test(4, 0, BACKSPACE, 22.23); + ftf.test(2, 0, BACKSPACE, 2.23); + + // test replacing selection + ftf.test(0, 1, "555", 555.23); + ftf.test(4, 2, "555", 5555.55); + ftf.test(2, 3, "1", 551.55); + ftf.test(3, 2, "6", 55.65); + ftf.test(4, 2, "12", 556.12); + ftf.test(3, 4, "0", 5.5); + ftf.test(0, 3, "111222333444555", 1112223334445.55); + + // test deleting selection + ftf.test(0, 2, DELETE, 12223334445.55); + ftf.test(0, 3, BACKSPACE, 223334445.55); + ftf.test(12, 2, DELETE, 2233344.45); + ftf.test(9, 2, BACKSPACE, 22333.44); + ftf.test(4, 3, DELETE, 223.44); + ftf.test(1, 2, BACKSPACE, 23.44); + ftf.test(3, 3, DELETE, .23); + ftf.test(1, 2, BACKSPACE, .02); + } + + void testCurrencyFormat() { + NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US); + TestFormattedTextField ftf = create(format); + ftf.setValue(56L); + + System.err.println("Testing NumberFormat.getCurrencyInstance(Locale.US)"); + + // test inserting individual characters + ftf.test(1, 0, "1", 16L); + ftf.test(3, 0, "2", 162L); + ftf.test(2, 0, "0", 102L); + + // test inserting several characters at once - e.g. from clipboard + ftf.test(1, 0, "1024", 1024L); + ftf.test(4, 0, "333", 10333L); + ftf.test(7, 0, "77", 1033377L); + ftf.test(5, 0, "99", 1039977L); + ftf.test(7, 0, "00", 1039007L); + + // test inserting strings that contain some formatting + ftf.test(1, 0, "2,2", 229007L); + ftf.test(3, 0, "2,2", 22227L); + ftf.test(4, 0, "2,2", 2222L); + ftf.test(6, 0, "33,33", 22223333L); + + // test delete + ftf.test(1, 0, DELETE, 2223333L); + ftf.test(10, 0, DELETE, 2223333L); + ftf.test(5, 0, DELETE, 222333L); + ftf.test(5, 0, DELETE, 22233L); + + // test backspace + ftf.test(1, 0, BACKSPACE, 22233L); + ftf.test(7, 0, BACKSPACE, 2223L); + ftf.test(4, 0, BACKSPACE, 223L); + ftf.test(2, 0, BACKSPACE, 23L); + + // test replacing selection + ftf.test(1, 1, "555", 5553L); + ftf.test(4, 2, "555", 55555L); + ftf.test(2, 3, "1", 5155L); + ftf.test(3, 2, "6", 565L); + ftf.test(1, 3, "111222333444555", 111222333444555L); + + // test deleting selection + ftf.test(1, 2, DELETE, 1222333444555L); + ftf.test(1, 3, BACKSPACE, 22333444555L); + ftf.test(13, 2, DELETE, 223334445L); + ftf.test(10, 2, BACKSPACE, 2233344L); + ftf.test(4, 4, DELETE, 2244L); + ftf.test(1, 4, BACKSPACE, 4L); + } + + void testIntegerFormat() { + NumberFormat format = NumberFormat.getIntegerInstance(Locale.US); + TestFormattedTextField ftf = create(format); + ftf.setValue(56L); + + System.err.println("Testing NumberFormat.getIntegerInstance(Locale.US)"); + + // test inserting individual characters + ftf.test(0, 0, "1", 16L); + ftf.test(2, 0, "2", 162L); + ftf.test(1, 0, "0", 102L); + + // test inserting several characters at once - e.g. from clipboard + ftf.test(0, 0, "1024", 1024L); + ftf.test(3, 0, "333", 10333L); + ftf.test(6, 0, "77", 1033377L); + ftf.test(4, 0, "99", 1039977L); + ftf.test(6, 0, "00", 1039007L); + + // test inserting strings that contain some formatting + ftf.test(0, 0, "2,2", 229007L); + ftf.test(2, 0, "2,2", 22227L); + ftf.test(3, 0, "2,2", 2222L); + ftf.test(5, 0, "33,33", 22223333L); + + // test delete + ftf.test(0, 0, DELETE, 2223333L); + ftf.test(9, 0, DELETE, 2223333L); + ftf.test(4, 0, DELETE, 222333L); + ftf.test(4, 0, DELETE, 22233L); + + // test backspace + ftf.test(0, 0, BACKSPACE, 22233L); + ftf.test(6, 0, BACKSPACE, 2223L); + ftf.test(2, 0, BACKSPACE, 223L); + ftf.test(2, 0, BACKSPACE, 23L); + + // test replacing selection + ftf.test(0, 1, "555", 5553L); + ftf.test(3, 2, "555", 55555L); + ftf.test(1, 3, "1", 5155L); + ftf.test(2, 2, "6", 565L); + ftf.test(0, 3, "111222333444555", 111222333444555L); + + // test deleting selection + ftf.test(0, 2, DELETE, 1222333444555L); + ftf.test(0, 3, BACKSPACE, 22333444555L); + ftf.test(12, 2, DELETE, 223334445L); + ftf.test(9, 2, BACKSPACE, 2233344L); + ftf.test(3, 4, DELETE, 2244L); + ftf.test(0, 4, BACKSPACE, 4L); + } + + Date date(DateFormat format, String spec) { + try { + return format.parse(spec); + } catch (ParseException e) { + throw new Error("Error in test"); + } + } + + void testDateFormat() { + DateFormat format = new SimpleDateFormat("MM/dd/yyyy", Locale.US); + TestFormattedTextField ftf = create(format); + ftf.setValue(date(format, "12/05/2005")); + + System.err.println("Testing SimpleDateFormat(\"MM/dd/yyyy\", Locale.US)"); + + // test inserting individual characters + ftf.test(0, 0, "0", date(format, "02/05/2005")); + ftf.test(4, 0, "4", date(format, "02/04/2005")); + ftf.test(6, 0, "1", date(format, "02/04/1005")); + ftf.test(9, 0, "9", date(format, "02/04/1009")); + + // test inserting several characters at once - e.g. from clipboard + ftf.test(0, 0, "11", date(format, "11/04/1009")); + ftf.test(3, 0, "23", date(format, "11/23/1009")); + ftf.test(6, 0, "191", date(format, "11/23/1919")); + + // test delete + ftf.test(0, 0, DELETE, date(format, "01/23/1919")); + ftf.test(3, 0, DELETE, date(format, "01/03/1919")); + ftf.test(10, 0, DELETE, date(format, "01/03/1919")); + ftf.test(1, 0, DELETE, date(format, "12/03/1918")); + ftf.test(4, 0, DELETE, date(format, "11/30/1918")); + + // test backspace + ftf.test(0, 0, BACKSPACE, date(format, "11/30/1918")); + ftf.test(1, 0, BACKSPACE, date(format, "01/30/1918")); + ftf.test(4, 0, BACKSPACE, date(format, "12/31/1917")); + ftf.test(10, 0, BACKSPACE, date(format, "12/31/0191")); + ftf.test(3, 0, BACKSPACE, date(format, "01/31/0191")); + ftf.test(5, 0, BACKSPACE, date(format, "01/03/0191")); + + // test replacing selection + ftf.test(0, 1, "1", date(format, "11/03/0191")); + ftf.test(3, 1, "2", date(format, "11/23/0191")); + ftf.test(6, 2, "20", date(format, "11/23/2091")); + + // test deleting selection + ftf.test(0, 1, BACKSPACE, date(format, "01/23/2091")); + ftf.test(3, 1, DELETE, date(format, "01/03/2091")); + ftf.test(6, 2, BACKSPACE, date(format, "01/03/0091")); + ftf.test(8, 1, DELETE, date(format, "01/03/0001")); + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/ftp/FtpGetContent.java --- a/jdk/test/sun/net/ftp/FtpGetContent.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/ftp/FtpGetContent.java Thu Aug 12 19:55:48 2010 -0700 @@ -391,6 +391,10 @@ done = true; } + synchronized boolean done() { + return done; + } + synchronized public void setPortEnabled(boolean ok) { portEnabled = ok; } @@ -431,12 +435,13 @@ public void run() { try { Socket client; - while (!done) { + while (!done()) { client = server.accept(); (new FtpServerHandler(client)).start(); } - server.close(); } catch(Exception e) { + } finally { + try { server.close(); } catch (IOException unused) {} } } } @@ -463,18 +468,13 @@ bytesRead = stream.read(buffer); } stream.close(); - server.terminate(); - server.interrupt(); if (totalBytes != filesize) throw new RuntimeException("wrong file size!"); } catch (IOException e) { - try { - server.terminate(); - server.interrupt(); - } catch (Exception e2) { - } throw new RuntimeException(e.getMessage()); + } finally { + server.terminate(); + server.server.close(); } } - } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/ftp/FtpURL.java --- a/jdk/test/sun/net/ftp/FtpURL.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/ftp/FtpURL.java Thu Aug 12 19:55:48 2010 -0700 @@ -438,8 +438,9 @@ client = server.accept(); (new FtpServerHandler(client)).run(); } - server.close(); } catch(Exception e) { + } finally { + try { server.close(); } catch (IOException unused) {} } } } @@ -448,10 +449,9 @@ } public FtpURL() throws Exception { - FtpServer server = null; + FtpServer server = new FtpServer(0); BufferedReader in = null; try { - server = new FtpServer(0); server.start(); int port = server.getPort(); @@ -497,17 +497,14 @@ throw new RuntimeException("Incorrect filename received"); if (! "/usr".equals(server.pwd())) throw new RuntimeException("Incorrect pwd received"); - in.close(); // We're done! } catch (Exception e) { - try { - in.close(); - server.terminate(); - server.interrupt(); - } catch(Exception ex) { - } throw new RuntimeException("FTP support error: " + e.getMessage()); + } finally { + try { in.close(); } catch (IOException unused) {} + server.terminate(); + server.server.close(); } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java --- a/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -30,9 +30,7 @@ * @summary ChunkedEncoding unit test; MeteredStream/ProgressData problem */ -import java.io.*; import java.net.*; -import java.security.*; import java.util.BitSet; import sun.net.ProgressMeteringPolicy; import sun.net.ProgressMonitor; @@ -42,8 +40,10 @@ public class ChunkedEncodingWithProgressMonitorTest { public static void main (String[] args) throws Exception { ProgressMonitor.setMeteringPolicy(new MyProgressMeteringPolicy()); - ProgressMonitor.getDefault().addProgressListener(new MyProgressListener()); + ProgressListener listener = new MyProgressListener(); + ProgressMonitor.getDefault().addProgressListener(listener); ChunkedEncodingTest.test(); + ProgressMonitor.getDefault().removeProgressListener(listener); if (flag.cardinality() != 3) { throw new RuntimeException("All three methods in ProgressListener"+ diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java --- a/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java Thu Aug 12 19:55:48 2010 -0700 @@ -34,7 +34,7 @@ public class Test implements HttpHandler { - static int count = 0; + static volatile int count = 0; static final String str1 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+ "1234567890abcdefkjsdlkjflkjsldkfjlsdkjflkj"+ @@ -46,9 +46,9 @@ public void handle(HttpExchange exchange) { String reqbody; try { - switch (count) { - case 0: /* test1 -- keeps conn alive */ - case 1: /* test2 -- closes conn */ + switch (exchange.getRequestURI().toString()) { + case "/test/test1": /* test1 -- keeps conn alive */ + case "/test/test2": /* test2 -- closes conn */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); if (!reqbody.equals(str1)) { @@ -72,7 +72,7 @@ resHeaders.set("Connection", "close"); } break; - case 2: /* test 3 */ + case "/test/test3": /* test 3 */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); @@ -93,19 +93,19 @@ exchange.sendResponseHeaders(200, reqbody.length()); write(exchange.getResponseBody(), reqbody); break; - case 3: /* test 4 */ - case 4: /* test 5 */ + case "/test/test4": /* test 4 */ + case "/test/test5": /* test 5 */ printRequestURI(exchange); break; - case 5: /* test 6 */ + case "/test/test6": /* test 6 */ printRequestURI(exchange); resHeaders = exchange.getResponseHeaders() ; resHeaders.set("Location", "http://foo.bar/"); resHeaders.set("Connection", "close"); exchange.sendResponseHeaders(307, 0); break; - case 6: /* test 7 */ - case 7: /* test 8 */ + case "/test/test7": /* test 7 */ + case "/test/test8": /* test 8 */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); if (reqbody != null && !"".equals(reqbody)) { @@ -116,7 +116,7 @@ resHeaders.set("Connection", "close"); exchange.sendResponseHeaders(200, 0); break; - case 8: /* test 9 */ + case "/test/test9": /* test 9 */ printRequestURI(exchange); reqbody = read(exchange.getRequestBody()); if (!reqbody.equals(str1)) { @@ -134,7 +134,7 @@ exchange.sendResponseHeaders(200, reqbody.length()); write(exchange.getResponseBody(), reqbody); break; - case 9: /* test10 */ + case "/test/test10": /* test10 */ printRequestURI(exchange); InputStream is = exchange.getRequestBody(); String s = read (is, str1.length()); @@ -158,7 +158,7 @@ exchange.sendResponseHeaders(200, 0); } break; - case 10: /* test11 */ + case "/test/test11": /* test11 */ printRequestURI(exchange); is = exchange.getRequestBody(); s = read (is, str1.length()); @@ -182,7 +182,7 @@ exchange.sendResponseHeaders(200, 0); } break; - case 11: /* test12 */ + case "/test/test12": /* test12 */ printRequestURI(exchange); is = exchange.getRequestBody(); @@ -203,8 +203,8 @@ } break; } + count ++; exchange.close(); - count ++; } catch (IOException e) { e.printStackTrace(); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/http/HttpClient/B6726695.java --- a/jdk/test/sun/net/www/http/HttpClient/B6726695.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/http/HttpClient/B6726695.java Thu Aug 12 19:55:48 2010 -0700 @@ -147,6 +147,8 @@ serverIgnore(s); } catch (IOException e) { e.printStackTrace(); + } finally { + try { server.close(); } catch (IOException unused) {} } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/http/HttpClient/MultiThreadTest.java --- a/jdk/test/sun/net/www/http/HttpClient/MultiThreadTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/http/HttpClient/MultiThreadTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -100,11 +100,12 @@ } } catch (Exception e) { throw new RuntimeException (e.getMessage()); - } - synchronized (threadlock) { - threadCounter --; - if (threadCounter == 0) { - threadlock.notifyAll(); + } finally { + synchronized (threadlock) { + threadCounter --; + if (threadCounter == 0) { + threadlock.notifyAll(); + } } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/http/HttpClient/ProxyTest.java --- a/jdk/test/sun/net/www/http/HttpClient/ProxyTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/http/HttpClient/ProxyTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -47,7 +47,7 @@ private class HttpProxyServer extends Thread { private ServerSocket server; private int port; - private boolean done = false; + private volatile boolean done = false; private String askedUrl; /** @@ -125,12 +125,8 @@ } } - public HttpProxyServer(int port) { - this.port = port; - } - - public HttpProxyServer() { - this(0); + public HttpProxyServer() throws IOException { + server = new ServerSocket(0); } public int getPort() { @@ -148,51 +144,49 @@ */ synchronized public void terminate() { done = true; + try { server.close(); } catch (IOException unused) {} } public void run() { try { - server = new ServerSocket(port); Socket client; while (!done) { client = server.accept(); (new HttpProxyHandler(client)).start(); } - server.close(); } catch (Exception e) { + } finally { + try { server.close(); } catch (IOException unused) {} } } } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { ProxyTest test = new ProxyTest(); } - public ProxyTest() { + public ProxyTest() throws Exception { + BufferedReader in = null; String testURL = "ftp://anonymous:password@myhost.mydomain/index.html"; HttpProxyServer server = new HttpProxyServer(); try { - server.start(); - int port = 0; - while (port == 0) { - Thread.sleep(500); - port = server.getPort(); - } + server.start(); + int port = server.getPort(); - System.setProperty("ftp.proxyHost","localhost"); - System.setProperty("ftp.proxyPort", String.valueOf(port)); - URL url = new URL(testURL); - InputStream ins = url.openStream(); - BufferedReader in = new BufferedReader(new InputStreamReader(ins)); - String line; - do { - line = in.readLine(); - } while (line != null); - in.close(); - server.terminate(); - server.interrupt(); + Proxy ftpProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", port)); + URL url = new URL(testURL); + InputStream ins = (url.openConnection(ftpProxy)).getInputStream(); + in = new BufferedReader(new InputStreamReader(ins)); + String line; + do { + line = in.readLine(); + } while (line != null); + in.close(); } catch (Exception e) { e.printStackTrace(); + } finally { + server.terminate(); + try { in.close(); } catch (IOException unused) {} } /* * If the URLs don't match, we've got a bug! diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java --- a/jdk/test/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/http/KeepAliveCache/KeepAliveTimerThread.java Thu Aug 12 19:55:48 2010 -0700 @@ -91,9 +91,10 @@ out.flush(); s.close(); - server.close(); } catch (Exception e) { e.printStackTrace(); + } finally { + try { server.close(); } catch (IOException unused) {} } } } @@ -118,6 +119,8 @@ if (grp.activeCount() > 0) { throw new RuntimeException("Keep-alive thread started in wrong thread group"); } + + grp.destroy(); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/http/KeepAliveStream/KeepAliveStreamCloseWithWrongContentLength.java --- a/jdk/test/sun/net/www/http/KeepAliveStream/KeepAliveStreamCloseWithWrongContentLength.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/http/KeepAliveStream/KeepAliveStreamCloseWithWrongContentLength.java Thu Aug 12 19:55:48 2010 -0700 @@ -43,10 +43,6 @@ srv = s; } - Socket getSocket () { - return (s); - } - public void run() { try { s = srv.accept (); @@ -57,7 +53,7 @@ is.read(); } OutputStreamWriter ow = - new OutputStreamWriter(s.getOutputStream()); + new OutputStreamWriter((os = s.getOutputStream())); ow.write("HTTP/1.0 200 OK\n"); // Note: The client expects 10 bytes. @@ -71,19 +67,16 @@ // Note: The (buggy) server only sends 9 bytes. ow.write("123456789"); ow.flush(); - ow.close(); } catch (Exception e) { + } finally { + try {if (os != null) { os.close(); }} catch (IOException e) {} } } } - /* - * - */ - - public static void main (String[] args) { + public static void main (String[] args) throws Exception { + ServerSocket serversocket = new ServerSocket (0); try { - ServerSocket serversocket = new ServerSocket (0); int port = serversocket.getLocalPort (); XServer server = new XServer (serversocket); server.start (); @@ -100,11 +93,12 @@ } } is.close(); - server.getSocket().close (); } catch (IOException e) { return; } catch (NullPointerException e) { throw new RuntimeException (e); + } finally { + if (serversocket != null) serversocket.close(); } } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/httptest/HttpServer.java --- a/jdk/test/sun/net/www/httptest/HttpServer.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/httptest/HttpServer.java Thu Aug 12 19:55:48 2010 -0700 @@ -188,6 +188,7 @@ sock.configureBlocking (false); sock.register (selector, SelectionKey.OP_READ); nconn ++; + System.out.println("SERVER: new connection. chan[" + sock + "]"); if (nconn == maxconn) { /* deregister */ listenerKey.cancel (); @@ -197,7 +198,9 @@ if (key.isReadable()) { boolean closed; SocketChannel chan = (SocketChannel) key.channel(); + System.out.println("SERVER: connection readable. chan[" + chan + "]"); if (key.attachment() != null) { + System.out.println("Server: comsume"); closed = consume (chan); } else { closed = read (chan, key); @@ -375,6 +378,7 @@ synchronized void orderlyCloseChannel (SelectionKey key) throws IOException { SocketChannel ch = (SocketChannel)key.channel (); + System.out.println("SERVER: orderlyCloseChannel chan[" + ch + "]"); ch.socket().shutdownOutput(); key.attach (this); clist.add (key); @@ -382,6 +386,8 @@ synchronized void abortiveCloseChannel (SelectionKey key) throws IOException { SocketChannel ch = (SocketChannel)key.channel (); + System.out.println("SERVER: abortiveCloseChannel chan[" + ch + "]"); + Socket s = ch.socket (); s.setSoLinger (true, 0); ch.close(); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/net/www/protocol/http/DigestTest.java --- a/jdk/test/sun/net/www/protocol/http/DigestTest.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/net/www/protocol/http/DigestTest.java Thu Aug 12 19:55:48 2010 -0700 @@ -95,10 +95,11 @@ os.write (reply.getBytes()); Thread.sleep (2000); s1.close (); - } - catch (Exception e) { + } catch (Exception e) { System.out.println (e); e.printStackTrace(); + } finally { + try { s.close(); } catch (IOException unused) {} } } @@ -204,15 +205,12 @@ public static void main(String[] args) throws Exception { - int nLoops = 1; - int nSize = 10; - int port, n =0; - byte b[] = new byte[nSize]; + int port; DigestServer server; ServerSocket sock; try { - sock = new ServerSocket (5000); + sock = new ServerSocket (0); port = sock.getLocalPort (); } catch (Exception e) { @@ -225,21 +223,18 @@ boolean passed = false; try { - Authenticator.setDefault (new MyAuthenticator ()); String s = "http://localhost:" + port + DigestServer.uri; URL url = new URL(s); java.net.URLConnection conURL = url.openConnection(); InputStream in = conURL.getInputStream(); - int c; - while ((c = in.read ()) != -1) { - } + while (in.read () != -1) {} in.close (); - } - catch(ProtocolException e) { + } catch(ProtocolException e) { passed = true; } + if (!passed) { throw new RuntimeException ("Expected a ProtocolException from wrong password"); } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/security/krb5/ConfPlusProp.java --- a/jdk/test/sun/security/krb5/ConfPlusProp.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/security/krb5/ConfPlusProp.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2010, 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 @@ -24,6 +24,7 @@ * @test * @bug 6857795 * @bug 6858589 + * @bug 6972005 * @summary krb5.conf ignored if system properties on realm and kdc are provided */ @@ -96,7 +97,8 @@ System.setProperty("java.security.krb5.conf", "i-am-not-a file"); refresh(); - checkDefaultRealm(null); + // Default realm might come from DNS + //checkDefaultRealm(null); check("R1", null); check("R2", null); check("R3", null); diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/security/krb5/confplusprop.conf --- a/jdk/test/sun/security/krb5/confplusprop.conf Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/security/krb5/confplusprop.conf Thu Aug 12 19:55:48 2010 -0700 @@ -1,6 +1,7 @@ [libdefaults] default_realm = R1 forwardable = well +dns_lookup_realm = false [realms] R1 = { diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/security/krb5/confplusprop2.conf --- a/jdk/test/sun/security/krb5/confplusprop2.conf Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/security/krb5/confplusprop2.conf Thu Aug 12 19:55:48 2010 -0700 @@ -1,3 +1,6 @@ +[libdefaults] +dns_lookup_realm = false + [realms] R1 = { kdc = k12 diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/security/util/DerOutputStream/LocaleInTime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/util/DerOutputStream/LocaleInTime.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6670889 + * @summary Keystore created under Hindi Locale causing ArrayIndexOutOfBoundsException + * @run main/othervm -Duser.language=hi -Duser.region=IN LocaleInTime + */ + +import java.util.Date; +import sun.security.util.DerOutputStream; +import sun.security.util.DerValue; + +public class LocaleInTime { + public static void main(String args[]) throws Exception { + DerOutputStream out = new DerOutputStream(); + out.putUTCTime(new Date()); + DerValue val = new DerValue(out.toByteArray()); + System.out.println(val.getUTCTime()); + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/security/x509/AlgorithmId/TurkishRegion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/x509/AlgorithmId/TurkishRegion.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6867345 + * @summary Turkish regional options cause NPE in + * sun.security.x509.AlgorithmId.algOID + * @run main/othervm -Duser.language=tr -Duser.region=TR TurkishRegion + * @author Xuelei Fan + */ + +import sun.security.x509.*; + +public class TurkishRegion { + + public static void main(String[] args) throws Exception { + AlgorithmId algId = AlgorithmId.get("PBEWITHMD5ANDDES"); + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/common/ApplicationSetup.sh --- a/jdk/test/sun/tools/common/ApplicationSetup.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/common/ApplicationSetup.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -24,54 +24,187 @@ # -# Support function to start and stop a given application +# Support functions to start, stop, wait for or kill a given SimpleApplication -# Starts a given application as background process, usage: -# startApplication [args...] +# Starts a given app as background process, usage: +# startApplication port-file [args...] +# +# The following variables are set: # -# Waits for application to print something to indicate it is running -# (and initialized). Output is directed to ${TESTCLASSES}/Application.out. -# Sets $pid to be the process-id of the application. - +# appJavaPid - application's Java pid +# appOtherPid - pid associated with the app other than appJavaPid +# appPidList - all pids associated with the app +# appOutput - file containing stdout and stderr from the app +# +# Waits for at least one line of output from the app to indicate +# that it is up and running. +# startApplication() { - OUTPUTFILE=${TESTCLASSES}/Application.out - ${JAVA} $1 $2 $3 $4 $5 $6 > ${OUTPUTFILE} & - pid="$!" - - # MKS creates an intermediate shell to launch ${JAVA} so - # ${pid} is not the actual pid. We have put in a small sleep - # to give the intermediate shell process time to launch the - # "java" process. - if [ "$OS" = "Windows" ]; then - sleep 2 - if [ "${isCygwin}" = "true" ] ; then - realpid=`ps -p ${pid} | tail -1 | awk '{print $4;}'` - else - realpid=`ps -o pid,ppid,comm|grep ${pid}|grep "java"|cut -c1-6` - fi - pid=${realpid} - fi - - echo "Waiting for Application to initialize..." - attempts=0 + appOutput="${TESTCLASSES}/Application.out" + + ${JAVA} -classpath "${TESTCLASSES}" "$@" > "$appOutput" 2>&1 & + appJavaPid="$!" + appOtherPid= + appPidList="$appJavaPid" + + echo "INFO: waiting for $1 to initialize..." + _cnt=0 while true; do + # if the app doesn't start then the JavaTest/JTREG timeout will + # kick in so this isn't really a endless loop sleep 1 - out=`tail -1 ${OUTPUTFILE}` - if [ ! -z "$out" ]; then + out=`tail -1 "$appOutput"` + if [ -n "$out" ]; then + # we got some output from the app so it's running break fi - attempts=`expr $attempts + 1` - echo "Waiting $attempts second(s) ..." + _cnt=`expr $_cnt + 1` + echo "INFO: waited $_cnt second(s) ..." done + unset _cnt - echo "Application is process $pid" + if $isWindows; then + # Windows requires special handling + appOtherPid="$appJavaPid" + + if $isCygwin; then + appJavaPid=`ps -p "$appOtherPid" \ + | sed -n ' + # See if $appOtherPid is in PID column; there are sometimes + # non-blanks in column 1 (I and S observed so far) + /^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}"'/{ + # strip PID column + s/^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}${PATTERN_WS}"'*// + # strip PPID column + s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// + # strip PGID column + s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*// + # strip everything after WINPID column + s/'"${PATTERN_WS}"'.*// + p + q + } + '` + echo "INFO: Cygwin pid=$appOtherPid maps to Windows pid=$appJavaPid" + else + # show PID, PPID and COMM columns only + appJavaPid=`ps -o pid,ppid,comm \ + | sed -n ' + # see if appOtherPid is in either PID or PPID columns + /'"${PATTERN_WS}${appOtherPid}${PATTERN_WS}"'/{ + # see if this is a java command + /java'"${PATTERN_EOL}"'/{ + # strip leading white space + s/^'"${PATTERN_WS}${PATTERN_WS}"'*// + # strip everything after the first word + s/'"${PATTERN_WS}"'.*// + # print the pid and we are done + p + q + } + } + '` + echo "INFO: MKS shell pid=$appOtherPid; Java pid=$appJavaPid" + fi + + if [ -z "$appJavaPid" ]; then + echo "ERROR: could not find app's Java pid." >&2 + killApplication + exit 2 + fi + appPidList="$appOtherPid $appJavaPid" + fi + + echo "INFO: $1 is process $appJavaPid" + echo "INFO: $1 output is in $appOutput" +} + + +# Stops a simple application by invoking ShutdownSimpleApplication +# class with a specific port-file, usage: +# stopApplication port-file +# +# Note: When this function returns, the SimpleApplication (or a subclass) +# may still be running because the application has not yet reached the +# shutdown check. +# +stopApplication() +{ + $JAVA -classpath "${TESTCLASSES}" ShutdownSimpleApplication $1 } -# Stops an application by invoking the given class and argument, usage: -# stopApplication -stopApplication() -{ - $JAVA -classpath "${TESTCLASSES}" $1 $2 + +# Wait for a simple application to stop running. +# +waitForApplication() { + if [ $isWindows = false ]; then + # non-Windows is easy; just one process + echo "INFO: waiting for $appJavaPid" + set +e + wait "$appJavaPid" + set -e + + elif $isCygwin; then + # Cygwin pid and not the Windows pid + echo "INFO: waiting for $appOtherPid" + set +e + wait "$appOtherPid" + set -e + + else # implied isMKS + # MKS has intermediate shell and Java process + echo "INFO: waiting for $appJavaPid" + + # appJavaPid can be empty if pid search in startApplication() failed + if [ -n "$appJavaPid" ]; then + # only need to wait for the Java process + set +e + wait "$appJavaPid" + set -e + fi + fi } + +# Kills a simple application by sending a SIGTERM to the appropriate +# process(es); on Windows SIGQUIT (-9) is used. +# +killApplication() +{ + if [ $isWindows = false ]; then + # non-Windows is easy; just one process + echo "INFO: killing $appJavaPid" + set +e + kill -TERM "$appJavaPid" # try a polite SIGTERM first + sleep 2 + # send SIGQUIT (-9) just in case SIGTERM didn't do it + # but don't show any complaints + kill -QUIT "$appJavaPid" > /dev/null 2>&1 + wait "$appJavaPid" + set -e + + elif $isCygwin; then + # Cygwin pid and not the Windows pid + echo "INFO: killing $appOtherPid" + set +e + kill -9 "$appOtherPid" + wait "$appOtherPid" + set -e + + else # implied isMKS + # MKS has intermediate shell and Java process + echo "INFO: killing $appPidList" + set +e + kill -9 $appPidList + set -e + + # appJavaPid can be empty if pid search in startApplication() failed + if [ -n "$appJavaPid" ]; then + # only need to wait for the Java process + set +e + wait "$appJavaPid" + set -e + fi + fi +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/common/CommonSetup.sh --- a/jdk/test/sun/tools/common/CommonSetup.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/common/CommonSetup.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -24,56 +24,94 @@ # -# Common setup for tool tests. +# Common setup for tool tests and other tests that use jtools. # Checks that TESTJAVA, TESTSRC, and TESTCLASSES environment variables are set. -# Creates the following for use by the tool tests -# JAVA java launcher -# JSTACK jstack utility -# JMAP jmap utility -# JINFO jinfo utility -# JHAT jhat utility -# PS path separator (";" or ":") -# OS operating system +# +# Creates the following constants for use by the caller: +# JAVA - java launcher +# JHAT - jhat utility +# JINFO - jinfo utility +# JMAP - jmap utility +# JPS - jps utility +# JSTACK - jstack utility +# OS - operating system name +# PATTERN_EOL - grep or sed end-of-line pattern +# PATTERN_WS - grep or sed whitespace pattern +# PS - path separator (";" or ":") +# +# Sets the following variables: +# +# isCygwin - true if environment is Cygwin +# isMKS - true if environment is MKS +# isLinux - true if OS is Linux +# isSolaris - true if OS is Solaris +# isWindows - true if OS is Windows -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." +if [ -z "${TESTJAVA}" ]; then + echo "ERROR: TESTJAVA not set. Test cannot execute. Failed." exit 1 fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." + +if [ -z "${TESTSRC}" ]; then + echo "ERROR: TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi + +if [ -z "${TESTCLASSES}" ]; then + echo "ERROR: TESTCLASSES not set. Test cannot execute. Failed." exit 1 fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - + +# only enable these after checking the expected incoming env variables +set -eu + JAVA="${TESTJAVA}/bin/java" -JSTACK="${TESTJAVA}/bin/jstack" +JHAT="${TESTJAVA}/bin/jhat" +JINFO="${TESTJAVA}/bin/jinfo" JMAP="${TESTJAVA}/bin/jmap" -JINFO="${TESTJAVA}/bin/jinfo" -JHAT="${TESTJAVA}/bin/jhat" +JPS="${TESTJAVA}/bin/jps" +JSTACK="${TESTJAVA}/bin/jstack" + +isCygwin=false +isMKS=false +isLinux=false +isSolaris=false +isUnknownOS=false +isWindows=false OS=`uname -s` +# start with some UNIX like defaults +PATTERN_EOL='$' +# blank and tab +PATTERN_WS='[ ]' +PS=":" + case "$OS" in - Windows* ) - PS=";" + CYGWIN* ) OS="Windows" + PATTERN_EOL='[ ]*$' + # blank and tab + PATTERN_WS='[ \t]' + isCygwin=true + isWindows=true ;; - CYGWIN* ) + Linux ) + OS="Linux" + isLinux=true + ;; + SunOS ) + OS="Solaris" + isSolaris=true + ;; + Windows* ) + OS="Windows" + PATTERN_EOL='[ ]*$' PS=";" - OS="Windows" - isCygwin=true + isWindows=true ;; * ) - PS=":" + isUnknownOS=true ;; esac - diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/common/CommonTests.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/tools/common/CommonTests.sh Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,314 @@ +#!/bin/sh + +# +# Copyright (c) 2010, 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 +# @bug 6964018 +# @summary Unit test for common tools infrastructure. +# +# @build SimpleApplication SleeperApplication ShutdownSimpleApplication +# @run shell CommonTests.sh + +. ${TESTSRC}/CommonSetup.sh +. ${TESTSRC}/ApplicationSetup.sh + +# hope for the best: +status=0 + + +# Test program path constants from CommonSetup.sh: +# +for name in JAVA JHAT JINFO JMAP JPS JSTACK; do + eval value=$`echo $name` + + echo "INFO: $name=$value" + if [ -x "$value" ]; then + echo "INFO: '$value' is executable." + else + echo "ERROR: '$value' is not executable." >&2 + status=1 + fi +done + + +# Display flag values from CommonSetup.sh: +# +for name in isCygwin isMKS isLinux isSolaris isUnknownOS isWindows; do + eval value=$`echo $name` + echo "INFO: flag $name=$value" +done + + +# Test OS constant from CommonSetup.sh: +# +if [ -z "$OS" ]; then + echo "ERROR: OS constant cannot be empty." >&2 + status=1 +fi + + +# Display the PATTERN_EOL value: +# +echo "INFO: PATTERN_EOL="`echo "$PATTERN_EOL" | od -c` + + +# Test PATTERN_EOL with 'grep' for a regular line. +# +TESTOUT="${TESTCLASSES}/testout.grep_reg_line_eol" +set +e +echo 'regular line' | grep "line${PATTERN_EOL}" > "$TESTOUT" +set -e +if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_EOL works for regular line with grep." +else + echo "ERROR: PATTERN_EOL does not work for regular line with grep." >&2 + status=1 +fi + + +if $isWindows; then + # Test PATTERN_EOL with 'grep' for a CR line. + # + TESTOUT="${TESTCLASSES}/testout.grep_cr_line_eol" + set +e + echo 'CR line ' | grep "line${PATTERN_EOL}" > "$TESTOUT" + set -e + if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_EOL works for CR line with grep." + else + echo "ERROR: PATTERN_EOL does not work for CR line with grep." >&2 + status=1 + fi +fi + + +# Test PATTERN_EOL with 'sed' for a regular line. +# +TESTOUT="${TESTCLASSES}/testout.sed_reg_line_eol" +echo 'regular line' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT" +if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_EOL works for regular line with sed." +else + echo "ERROR: PATTERN_EOL does not work for regular line with sed." >&2 + status=1 +fi + + +if $isWindows; then + # Test PATTERN_EOL with 'sed' for a CR line. + # + TESTOUT="${TESTCLASSES}/testout.sed_cr_line_eol" + echo 'CR line ' | sed -n "/line${PATTERN_EOL}/p" > "$TESTOUT" + if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_EOL works for CR line with sed." + else + echo "ERROR: PATTERN_EOL does not work for CR line with sed." >&2 + status=1 + fi +fi + + +# Display the PATTERN_WS value: +# +echo "INFO: PATTERN_WS="`echo "$PATTERN_WS" | od -c` + + +# Test PATTERN_WS with 'grep' for a blank. +# +TESTOUT="${TESTCLASSES}/testout.grep_blank" +set +e +echo 'blank: ' | grep "$PATTERN_WS" > "$TESTOUT" +set -e +if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_WS works for blanks with grep." +else + echo "ERROR: PATTERN_WS does not work for blanks with grep." >&2 + status=1 +fi + + +# Test PATTERN_WS with 'grep' for a tab. +# +TESTOUT="${TESTCLASSES}/testout.grep_tab" +set +e +echo 'tab: ' | grep "$PATTERN_WS" > "$TESTOUT" +set -e +if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_WS works for tabs with grep." +else + echo "ERROR: PATTERN_WS does not work for tabs with grep." >&2 + status=1 +fi + + +# Test PATTERN_WS with 'sed' for a blank. +# +TESTOUT="${TESTCLASSES}/testout.sed_blank" +echo 'blank: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT" +if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_WS works for blanks with sed." +else + echo "ERROR: PATTERN_WS does not work for blanks with sed." >&2 + status=1 +fi + + +# Test PATTERN_WS with 'sed' for a tab. +# +TESTOUT="${TESTCLASSES}/testout.sed_tab" +echo 'tab: ' | sed -n "/$PATTERN_WS/p" > "$TESTOUT" +if [ -s "$TESTOUT" ]; then + echo "INFO: PATTERN_WS works for tabs with sed." +else + echo "ERROR: PATTERN_WS does not work for tabs with sed." >&2 + status=1 +fi + + +# Test startApplication and use PORTFILE for coordination +# The app sleeps for 30 seconds. +# +PORTFILE="${TESTCLASSES}"/shutdown.port +startApplication SleeperApplication "${PORTFILE}" 30 + + +# Test appJavaPid in "ps" cmd output. +# +TESTOUT="${TESTCLASSES}/testout.ps_app" +set +e +if $isCygwin; then + # On Cygwin, appJavaPid is the Windows pid for the Java process + # and appOtherPid is the Cygwin pid for the Java process. + ps -p "$appOtherPid" \ + | grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT" +else + # output only pid and comm columns to avoid mismatches + ps -eo pid,comm \ + | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" +fi +set -e +if [ -s "$TESTOUT" ]; then + echo "INFO: begin appJavaPid=$appJavaPid in 'ps' cmd output:" + cat "$TESTOUT" + echo "INFO: end appJavaPid=$appJavaPid in 'ps' cmd output." +else + echo "ERROR: 'ps' cmd should show appJavaPid=$appJavaPid." >&2 + status=1 +fi + +if [ -n "$appOtherPid" ]; then + # Test appOtherPid in "ps" cmd output, if we have one. + # + TESTOUT="${TESTCLASSES}/testout.ps_other" + set +e + if $isCygwin; then + ps -p "$appOtherPid" \ + | grep "${PATTERN_WS}${appOtherPid}${PATTERN_WS}" > "$TESTOUT" + else + # output only pid and comm columns to avoid mismatches + ps -eo pid,comm \ + | grep "^${PATTERN_WS}*${appOtherPid}${PATTERN_WS}" > "$TESTOUT" + fi + set -e + if [ -s "$TESTOUT" ]; then + echo "INFO: begin appOtherPid=$appOtherPid in 'ps' cmd output:" + cat "$TESTOUT" + echo "INFO: end appOtherPid=$appOtherPid in 'ps' cmd output." + else + echo "ERROR: 'ps' cmd should show appOtherPid=$appOtherPid." >&2 + status=1 + fi +fi + + +# Test stopApplication and PORTFILE for coordination +# +stopApplication "${PORTFILE}" + + +# Test application still running after stopApplication. +# +# stopApplication just lets the app know that it can stop, but the +# app might still be doing work. This test just demonstrates that +# fact and doesn't fail if the app is already done. +# +TESTOUT="${TESTCLASSES}/testout.after_stop" +set +e +if $isCygwin; then + # On Cygwin, appJavaPid is the Windows pid for the Java process + # and appOtherPid is the Cygwin pid for the Java process. + ps -p "$appOtherPid" \ + | grep "${PATTERN_WS}${appJavaPid}${PATTERN_WS}" > "$TESTOUT" +else + # output only pid and comm columns to avoid mismatches + ps -eo pid,comm \ + | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" +fi +set -e +if [ -s "$TESTOUT" ]; then + echo "INFO: it is okay for appJavaPid=$appJavaPid to still be running" \ + "after stopApplication() is called." + echo "INFO: begin 'after_stop' output:" + cat "$TESTOUT" + echo "INFO: end 'after_stop' output." +fi + + +# Test waitForApplication +# +# The app might already be gone so this function shouldn't generate +# a fatal error in either call. +# +waitForApplication + +if [ $isWindows = false ]; then + # Windows can recycle pids quickly so we can't use this test there + TESTOUT="${TESTCLASSES}/testout.after_kill" + set +e + # output only pid and comm columns to avoid mismatches + ps -eo pid,comm \ + | grep "^${PATTERN_WS}*${appJavaPid}${PATTERN_WS}" > "$TESTOUT" + set -e + if [ -s "$TESTOUT" ]; then + echo "ERROR: 'ps' cmd should not show appJavaPid." >&2 + echo "ERROR: begin 'after_kill' output:" >&2 + cat "$TESTOUT" >&2 + echo "ERROR: end 'after_kill' output." >&2 + status=1 + else + echo "INFO: 'ps' cmd does not show appJavaPid after" \ + "waitForApplication() is called." + fi +fi + + +# Test killApplication +# +# The app is already be gone so this function shouldn't generate +# a fatal error. +# +killApplication + +exit $status diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/common/ShutdownSimpleApplication.java --- a/jdk/test/sun/tools/common/ShutdownSimpleApplication.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/common/ShutdownSimpleApplication.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, 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 @@ -22,10 +22,13 @@ */ /* - * + * Used to shutdown SimpleApplication (or a subclass). The argument to + * this class is the name of a file that contains the TCP port number + * on which SimpleApplication (or a subclass) is listening. * - * Used to shutdown SimpleApplication. The argument to this class is - * the TCP port number where SimpleApplication is listening. + * Note: When this program returns, the SimpleApplication (or a subclass) + * may still be running because the application has not yet reached the + * shutdown check. */ import java.net.Socket; import java.net.InetSocketAddress; @@ -35,6 +38,11 @@ public class ShutdownSimpleApplication { public static void main(String args[]) throws Exception { + if (args.length != 1) { + throw new RuntimeException("Usage: ShutdownSimpleApplication" + + " port-file"); + } + // read the (TCP) port number from the given file File f = new File(args[0]); @@ -42,21 +50,27 @@ byte b[] = new byte[8]; int n = fis.read(b); if (n < 1) { - throw new RuntimeException("Empty file"); + throw new RuntimeException("Empty port-file"); } fis.close(); String str = new String(b, 0, n, "UTF-8"); - System.out.println("Port number of application is: " + str); + System.out.println("INFO: Port number of SimpleApplication: " + str); int port = Integer.parseInt(str); // Now connect to the port (which will shutdown application) - System.out.println("Connecting to port " + port + - " to shutdown Application ..."); + System.out.println("INFO: Connecting to port " + port + + " to shutdown SimpleApplication ..."); + System.out.flush(); Socket s = new Socket(); s.connect( new InetSocketAddress(port) ); s.close(); + + System.out.println("INFO: done connecting to SimpleApplication."); + System.out.flush(); + + System.exit(0); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/common/SimpleApplication.java --- a/jdk/test/sun/tools/common/SimpleApplication.java Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/common/SimpleApplication.java Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2010, 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 @@ -22,10 +22,12 @@ */ /* - * + * A simple application used by unit tests. The first argument to this + * class is the name of a file to which a TCP port number can be written. * - * A simple application used for tool unit tests. It does nothing else - * bind to a TCP port and wait for a shutdown message. + * By default, this class does nothing other than bind to a TCP port, + * write the TCP port number to a file, and wait for an incoming connection + * in order to complete the application shutdown protocol. */ import java.net.Socket; import java.net.ServerSocket; @@ -33,25 +35,86 @@ import java.io.FileOutputStream; public class SimpleApplication { - public static void main(String args[]) throws Exception { + private static SimpleApplication myApp; // simple app or a subclass + private static String myAppName; // simple app name + private static int myPort; // coordination port # + private static ServerSocket mySS; // coordination socket + + // protected so a subclass can extend it; not public so creation is + // limited. + protected SimpleApplication() { + // save simple app (or subclass) name for messages + myAppName = getClass().getName(); + } + + // return the simple application (or a subclass) + final public static SimpleApplication getMyApp() { + return myApp; + } + + // set the simple application (for use by a subclass) + final public static void setMyApp(SimpleApplication _myApp) { + myApp = _myApp; + } + + // execute the application finish protocol + final public void doMyAppFinish(String[] args) throws Exception { + System.out.println("INFO: " + myAppName + " is waiting on port: " + + myPort); + System.out.flush(); + + // wait for test harness to connect + Socket s = mySS.accept(); + s.close(); + mySS.close(); + + System.out.println("INFO: " + myAppName + " is shutting down."); + System.out.flush(); + } + + // execute the application start protocol + final public void doMyAppStart(String[] args) throws Exception { + if (args.length < 1) { + throw new RuntimeException("Usage: " + myAppName + + " port-file [arg(s)]"); + } + // bind to a random port - ServerSocket ss = new ServerSocket(0); - int port = ss.getLocalPort(); + mySS = new ServerSocket(0); + myPort = mySS.getLocalPort(); // Write the port number to the given file File f = new File(args[0]); FileOutputStream fos = new FileOutputStream(f); - fos.write( Integer.toString(port).getBytes("UTF-8") ); + fos.write( Integer.toString(myPort).getBytes("UTF-8") ); fos.close(); - System.out.println("Application waiting on port: " + port); + System.out.println("INFO: " + myAppName + " created socket on port: " + + myPort); + System.out.flush(); + } + + // execute the app work (subclass can override this) + public void doMyAppWork(String[] args) throws Exception { + } + + public static void main(String[] args) throws Exception { + if (myApp == null) { + // create myApp since a subclass hasn't done so + myApp = new SimpleApplication(); + } + + myApp.doMyAppStart(args); // do the app start protocol + + System.out.println("INFO: " + myAppName + " is calling doMyAppWork()"); + System.out.flush(); + myApp.doMyAppWork(args); // do the app work + System.out.println("INFO: " + myAppName + " returned from" + + " doMyAppWork()"); System.out.flush(); - // wait for test harness to connect - Socket s = ss.accept(); - s.close(); - ss.close(); + myApp.doMyAppFinish(args); // do the app finish protocol - System.out.println("Application shutdown."); + System.exit(0); } } diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/common/SleeperApplication.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/tools/common/SleeperApplication.java Thu Aug 12 19:55:48 2010 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010, 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. + */ + +/* + * An example subclass of SimpleApplication that illustrates how to + * override the doMyAppWork() method. + */ + +public class SleeperApplication extends SimpleApplication { + public static int DEFAULT_SLEEP_TIME = 60; // time is in seconds + + // execute the sleeper app work + public void doMyAppWork(String[] args) throws Exception { + int sleep_time = DEFAULT_SLEEP_TIME; + + // args[0] is the port-file + if (args.length < 2) { + System.out.println("INFO: using default sleep time of " + + sleep_time + " seconds."); + } else { + try { + sleep_time = Integer.parseInt(args[1]); + } catch (NumberFormatException nfe) { + throw new RuntimeException("Error: '" + args[1] + + "': is not a valid seconds value."); + } + } + + Thread.sleep(sleep_time * 1000); // our "work" is to sleep + } + + public static void main(String[] args) throws Exception { + SleeperApplication myApp = new SleeperApplication(); + + SimpleApplication.setMyApp(myApp); + + SimpleApplication.main(args); + } +} diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jhat/ParseTest.sh --- a/jdk/test/sun/tools/jhat/ParseTest.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jhat/ParseTest.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2010, 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 @@ -32,7 +32,11 @@ # @run shell ParseTest.sh . ${TESTSRC}/../common/CommonSetup.sh -. ${TESTSRC}/../common/ApplicationSetup.sh + +# all return statuses are checked in this test +set +e + +failed=0 DUMPFILE="minimal.bin" diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jinfo/Basic.sh --- a/jdk/test/sun/tools/jinfo/Basic.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jinfo/Basic.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2010, 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 @@ -35,53 +35,57 @@ . ${TESTSRC}/../common/CommonSetup.sh . ${TESTSRC}/../common/ApplicationSetup.sh -# Start application (send output to shutdown.port) +# Start application and use PORTFILE for coordination PORTFILE="${TESTCLASSES}"/shutdown.port -startApplication \ - -classpath "${TESTCLASSES}" SimpleApplication "${PORTFILE}" +startApplication SimpleApplication "${PORTFILE}" + +# all return statuses are checked in this test +set +e failed=0 -if [ "$OS" != "Windows" ]; then +if [ $isWindows = false ]; then # -sysprops option - ${JINFO} -sysprops $pid + ${JINFO} -sysprops $appJavaPid if [ $? != 0 ]; then failed=1; fi # -flags option - ${JINFO} -flags $pid + ${JINFO} -flags $appJavaPid if [ $? != 0 ]; then failed=1; fi # no option - ${JINFO} $pid + ${JINFO} $appJavaPid if [ $? != 0 ]; then failed=1; fi fi # -flag option -${JINFO} -flag +PrintGC $pid +${JINFO} -flag +PrintGC $appJavaPid if [ $? != 0 ]; then failed=1; fi -${JINFO} -flag -PrintGC $pid +${JINFO} -flag -PrintGC $appJavaPid if [ $? != 0 ]; then failed=1; fi -${JINFO} -flag PrintGC $pid +${JINFO} -flag PrintGC $appJavaPid if [ $? != 0 ]; then failed=1; fi -if [ "$OS" = "SunOS" ]; then +if $isSolaris; then - ${JINFO} -flag +ExtendedDTraceProbes $pid + ${JINFO} -flag +ExtendedDTraceProbes $appJavaPid if [ $? != 0 ]; then failed=1; fi - ${JINFO} -flag -ExtendedDTraceProbes $pid + ${JINFO} -flag -ExtendedDTraceProbes $appJavaPid if [ $? != 0 ]; then failed=1; fi - ${JINFO} -flag ExtendedDTraceProbes $pid + ${JINFO} -flag ExtendedDTraceProbes $appJavaPid if [ $? != 0 ]; then failed=1; fi fi -stopApplication ShutdownSimpleApplication "${PORTFILE}" +set -e + +stopApplication "${PORTFILE}" +waitForApplication exit $failed - diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jmap/Basic.sh --- a/jdk/test/sun/tools/jmap/Basic.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jmap/Basic.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -35,24 +35,25 @@ . ${TESTSRC}/../common/CommonSetup.sh . ${TESTSRC}/../common/ApplicationSetup.sh -# Start application (send output to shutdown.port) +# Start application and use PORTFILE for coordination PORTFILE="${TESTCLASSES}"/shutdown.port -startApplication \ - -classpath "${TESTCLASSES}" SimpleApplication "${PORTFILE}" +startApplication SimpleApplication "${PORTFILE}" + +# all return statuses are checked in this test +set +e failed=0 # -histo[:live] option -${JMAP} -histo $pid +${JMAP} -histo $appJavaPid if [ $? != 0 ]; then failed=1; fi -${JMAP} -histo:live $pid +${JMAP} -histo:live $appJavaPid if [ $? != 0 ]; then failed=1; fi # -dump option -p=`expr $pid` -DUMPFILE="java_pid${p}.hprof" -${JMAP} -dump:format=b,file=${DUMPFILE} $pid +DUMPFILE="java_pid${appJavaPid}.hprof" +${JMAP} -dump:format=b,file=${DUMPFILE} $appJavaPid if [ $? != 0 ]; then failed=1; fi # check that heap dump is parsable @@ -63,7 +64,7 @@ rm ${DUMPFILE} # -dump:live option -${JMAP} -dump:live,format=b,file=${DUMPFILE} $pid +${JMAP} -dump:live,format=b,file=${DUMPFILE} $appJavaPid if [ $? != 0 ]; then failed=1; fi # check that heap dump is parsable @@ -71,9 +72,11 @@ if [ $? != 0 ]; then failed=1; fi # dump file is large so remove it -rm ${DUMPFILE} +rm -f ${DUMPFILE} -stopApplication ShutdownSimpleApplication "${PORTFILE}" +set -e + +stopApplication "${PORTFILE}" +waitForApplication exit $failed - diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jrunscript/common.sh --- a/jdk/test/sun/tools/jrunscript/common.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jrunscript/common.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -43,10 +43,20 @@ Windows_*) PS=";" FS="\\" + # MKS diff deals with trailing CRs automatically + golden_diff="diff" + ;; + CYGWIN*) + PS=":" + FS="/" + # Cygwin diff needs to be told to ignore trailing CRs + golden_diff="diff --strip-trailing-cr" ;; *) PS=":" FS="/" + # Assume any other platform doesn't have the trailing CR stuff + golden_diff="diff" ;; esac diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jrunscript/jrunscript-eTest.sh --- a/jdk/test/sun/tools/jrunscript/jrunscript-eTest.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jrunscript/jrunscript-eTest.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -42,7 +42,7 @@ rm -f jrunscript-eTest.out 2>/dev/null ${JRUNSCRIPT} -e "println('hello')" > jrunscript-eTest.out 2>&1 -diff jrunscript-eTest.out ${TESTSRC}/dash-e.out +$golden_diff jrunscript-eTest.out ${TESTSRC}/dash-e.out if [ $? != 0 ] then echo "Output of jrunscript -e differ from expected output. Failed." @@ -55,7 +55,7 @@ rm -f jrunscript-eTest.out 2>/dev/null ${JRUNSCRIPT} -l js -e "println('hello')" > jrunscript-eTest.out 2>&1 -diff jrunscript-eTest.out ${TESTSRC}/dash-e.out +$golden_diff jrunscript-eTest.out ${TESTSRC}/dash-e.out if [ $? != 0 ] then echo "Output of jrunscript -e differ from expected output. Failed." diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jrunscript/jrunscript-fTest.sh --- a/jdk/test/sun/tools/jrunscript/jrunscript-fTest.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jrunscript/jrunscript-fTest.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -42,7 +42,7 @@ rm -f jrunscript-fTest.out 2>/dev/null ${JRUNSCRIPT} -f ${TESTSRC}/hello.js > jrunscript-fTest.out 2>&1 -diff jrunscript-fTest.out ${TESTSRC}/dash-f.out +$golden_diff jrunscript-fTest.out ${TESTSRC}/dash-f.out if [ $? != 0 ] then echo "Output of jrunscript -f differ from expected output. Failed." @@ -56,7 +56,7 @@ rm -f jrunscript-fTest.out 2>/dev/null ${JRUNSCRIPT} -l js -f ${TESTSRC}/hello.js > jrunscript-fTest.out 2>&1 -diff jrunscript-fTest.out ${TESTSRC}/dash-f.out +$golden_diff jrunscript-fTest.out ${TESTSRC}/dash-f.out if [ $? != 0 ] then echo "Output of jrunscript -f differ from expected output. Failed." diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jrunscript/jrunscriptTest.sh --- a/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jrunscript/jrunscriptTest.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -49,7 +49,7 @@ new java.lang.Runnable() { run: function() { println('I am runnable'); }}.run(); EOF -diff jrunscriptTest.out ${TESTSRC}/repl.out +$golden_diff jrunscriptTest.out ${TESTSRC}/repl.out if [ $? != 0 ] then echo "Output of jrunscript session differ from expected output. Failed." @@ -67,7 +67,7 @@ new java.lang.Runnable() { run: function() { println('I am runnable'); }}.run(); EOF -diff jrunscriptTest.out ${TESTSRC}/repl.out +$golden_diff jrunscriptTest.out ${TESTSRC}/repl.out if [ $? != 0 ] then echo "Output of jrunscript -l js differ from expected output. Failed." diff -r 96a57de47def -r 67584b95a0f0 jdk/test/sun/tools/jstack/Basic.sh --- a/jdk/test/sun/tools/jstack/Basic.sh Wed Aug 11 10:05:56 2010 -0400 +++ b/jdk/test/sun/tools/jstack/Basic.sh Thu Aug 12 19:55:48 2010 -0700 @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2010, 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 @@ -35,22 +35,26 @@ . ${TESTSRC}/../common/CommonSetup.sh . ${TESTSRC}/../common/ApplicationSetup.sh -# Start application (send output to shutdown.port) +# Start application and use PORTFILE for coordination PORTFILE="${TESTCLASSES}"/shutdown.port -startApplication \ - -classpath "${TESTCLASSES}" SimpleApplication "${PORTFILE}" +startApplication SimpleApplication "${PORTFILE}" + +# all return statuses are checked in this test +set +e failed=0 # normal -$JSTACK $pid 2>&1 +$JSTACK $appJavaPid 2>&1 if [ $? != 0 ]; then failed=1; fi # long -$JSTACK -l $pid 2>&1 +$JSTACK -l $appJavaPid 2>&1 if [ $? != 0 ]; then failed=1; fi -stopApplication ShutdownSimpleApplication "${PORTFILE}" +set -e + +stopApplication "${PORTFILE}" +waitForApplication exit $failed - diff -r 96a57de47def -r 67584b95a0f0 langtools/.hgtags --- a/langtools/.hgtags Wed Aug 11 10:05:56 2010 -0400 +++ b/langtools/.hgtags Thu Aug 12 19:55:48 2010 -0700 @@ -77,3 +77,5 @@ d1d7595fa824925651f09b8ffcb86c9cf39807be jdk7-b100 20a8fe72ee7b673f59c319a5222fe0eebbd92082 jdk7-b101 ff9c0a0bf7edf637a7dac5062b920924536ed79c jdk7-b102 +bd85271c580ce4600b1b2d5598daa19d02174cf7 jdk7-b103 +fc7219517ec16b28d729d259020a25b05ffdf0b6 jdk7-b104 diff -r 96a57de47def -r 67584b95a0f0 langtools/make/build.properties --- a/langtools/make/build.properties Wed Aug 11 10:05:56 2010 -0400 +++ b/langtools/make/build.properties Thu Aug 12 19:55:48 2010 -0700 @@ -107,7 +107,8 @@ javax/annotation/processing/ \ javax/lang/model/ \ javax/tools/ \ - com/sun/source/ com/sun/tools/javac/ + com/sun/source/ \ + com/sun/tools/javac/ javac.tests = \ tools/javac diff -r 96a57de47def -r 67584b95a0f0 langtools/make/build.xml --- a/langtools/make/build.xml Wed Aug 11 10:05:56 2010 -0400 +++ b/langtools/make/build.xml Thu Aug 12 19:55:48 2010 -0700 @@ -322,6 +322,35 @@ datafile="${build.coverage.dir}/cobertura.ser"/> + + + + + + + + + + + + + + + +