From 70ec72585d401c8dbb1eeca0310935bdba3d3974 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Tue, 4 Dec 2007 16:28:05 -0800 Subject: [PATCH 001/274] Added tag jdk7-b24 for changeset fd16c54261b3 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) create mode 100644 .hgtags-top-repo diff --git a/.hgtags-top-repo b/.hgtags-top-repo new file mode 100644 index 00000000000..ff06c88a2bf --- /dev/null +++ b/.hgtags-top-repo @@ -0,0 +1 @@ +cfeea66a3fa8ca3686a7cfa2d0ce8ab0169f168d jdk7-b24 From 7828a7dee6d967804cb355a8a7c9a0fad3dcc920 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Tue, 4 Dec 2007 16:28:13 -0800 Subject: [PATCH 002/274] Added tag jdk7-b24 for changeset 02bb8761fcce --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) create mode 100644 corba/.hgtags diff --git a/corba/.hgtags b/corba/.hgtags new file mode 100644 index 00000000000..f50e5065b96 --- /dev/null +++ b/corba/.hgtags @@ -0,0 +1 @@ +55540e827aef970ecc010b7e06b912d991c8e3ce jdk7-b24 From dcbf4ea9ee880b926385c29053519e4bb9a41a89 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Tue, 4 Dec 2007 16:28:18 -0800 Subject: [PATCH 003/274] Added tag jdk7-b24 for changeset 489c9b5090e2 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) create mode 100644 hotspot/.hgtags diff --git a/hotspot/.hgtags b/hotspot/.hgtags new file mode 100644 index 00000000000..c3230a6f10b --- /dev/null +++ b/hotspot/.hgtags @@ -0,0 +1 @@ +a61af66fc99eb5ec9d50c05b0c599757b1289ceb jdk7-b24 From 3dde8f95e5834baac1eca32582026d2a35dc1721 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Tue, 4 Dec 2007 16:28:22 -0800 Subject: [PATCH 004/274] Added tag jdk7-b24 for changeset 7f561c08de6b --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) create mode 100644 jaxp/.hgtags diff --git a/jaxp/.hgtags b/jaxp/.hgtags new file mode 100644 index 00000000000..0c27eee3f67 --- /dev/null +++ b/jaxp/.hgtags @@ -0,0 +1 @@ +6ce5f4757bde08f7470cbb9f0b46da8f2f3d4f56 jdk7-b24 From fcc15c26e24ffb7ff91d99084fca13eb9f644e8a Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Tue, 4 Dec 2007 16:28:24 -0800 Subject: [PATCH 005/274] Added tag jdk7-b24 for changeset 474761f14bca --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) create mode 100644 jaxws/.hgtags diff --git a/jaxws/.hgtags b/jaxws/.hgtags new file mode 100644 index 00000000000..f96f9279308 --- /dev/null +++ b/jaxws/.hgtags @@ -0,0 +1 @@ +0961a4a211765fea071b8dac419003ee0c3d5973 jdk7-b24 From 3d9467a9486cab0f73713adb21b7feaade00997e Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Tue, 4 Dec 2007 16:28:45 -0800 Subject: [PATCH 006/274] Added tag jdk7-b24 for changeset 06bc494ca11e --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) create mode 100644 langtools/.hgtags diff --git a/langtools/.hgtags b/langtools/.hgtags new file mode 100644 index 00000000000..92efaa97332 --- /dev/null +++ b/langtools/.hgtags @@ -0,0 +1 @@ +9a66ca7c79fab293c1bb0534e0d208c7e4f58b01 jdk7-b24 From 5fa349cc42405ce58f77d5d946ac39389059b2c7 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 5 Dec 2007 09:00:00 -0800 Subject: [PATCH 007/274] 6664627: Merge changes made only in hotspot 11 forward to jdk 7 Reviewed-by: jcoomes --- .../src/cpu/sparc/vm/stubGenerator_sparc.cpp | 1 + .../src/cpu/sparc/vm/vtableStubs_sparc.cpp | 57 +++++------------ .../src/cpu/x86/vm/stubGenerator_x86_32.cpp | 1 + .../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 7 +++ hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp | 34 +++++------ hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp | 61 +++++++++---------- hotspot/src/share/vm/oops/klassVtable.cpp | 41 ++++++------- hotspot/src/share/vm/oops/klassVtable.hpp | 2 +- .../src/share/vm/runtime/sharedRuntime.cpp | 5 ++ .../src/share/vm/runtime/sharedRuntime.hpp | 1 + hotspot/src/share/vm/runtime/stubRoutines.cpp | 1 + hotspot/src/share/vm/runtime/stubRoutines.hpp | 2 + 12 files changed, 101 insertions(+), 112 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp index 03c74085734..290cedb9bb0 100644 --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -2911,6 +2911,7 @@ class StubGenerator: public StubCodeGenerator { // These entry points require SharedInfo::stack0 to be set up in non-core builds StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError), false); + StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false); StubRoutines::_throw_ArithmeticException_entry = generate_throw_exception("ArithmeticException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_ArithmeticException), true); StubRoutines::_throw_NullPointerException_entry = generate_throw_exception("NullPointerException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true); StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false); diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp index a1a5a82c838..c1ed4b351c5 100644 --- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp @@ -175,17 +175,12 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // %%%% Could load both offset and interface in one ldx, if they were // in the opposite order. This would save a load. __ ld_ptr(L0, base + itableOffsetEntry::interface_offset_in_bytes(), L1); -#ifdef ASSERT - Label ok; - // Check that entry is non-null and an Oop - __ bpr(Assembler::rc_nz, false, Assembler::pt, L1, ok); - __ delayed()->nop(); - __ stop("null entry point found in itable's offset table"); - __ bind(ok); - __ verify_oop(L1); -#endif // ASSERT - __ cmp(G5_interface, L1); + // If the entry is NULL then we've reached the end of the table + // without finding the expected interface, so throw an exception + Label throw_icce; + __ bpr(Assembler::rc_z, false, Assembler::pn, L1, throw_icce); + __ delayed()->cmp(G5_interface, L1); __ brx(Assembler::notEqual, true, Assembler::pn, search); __ delayed()->add(L0, itableOffsetEntry::size() * wordSize, L0); @@ -223,24 +218,30 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ JMP(G3_scratch, 0); __ delayed()->nop(); + __ bind(throw_icce); + Address icce(G3_scratch, StubRoutines::throw_IncompatibleClassChangeError_entry()); + __ jump_to(icce, 0); + __ delayed()->restore(); + masm->flush(); + + guarantee(__ pc() <= s->code_end(), "overflowed buffer"); + s->set_exception_points(npe_addr, ame_addr); return s; } int VtableStub::pd_code_size_limit(bool is_vtable_stub) { - if (TraceJumps || DebugVtables || CountCompiledCalls || VerifyOops) return 999; + if (TraceJumps || DebugVtables || CountCompiledCalls || VerifyOops) return 1000; else { const int slop = 2*BytesPerInstWord; // sethi;add (needed for long offsets) if (is_vtable_stub) { const int basic = 5*BytesPerInstWord; // ld;ld;ld,jmp,nop return basic + slop; } else { -#ifdef ASSERT - return 999; -#endif // ASSERT - const int basic = 17*BytesPerInstWord; // save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, ld, ld, jmp, restore + // save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, ld, ld, jmp, restore, sethi, jmpl, restore + const int basic = (20 LP64_ONLY(+ 6)) * BytesPerInstWord; return (basic + slop); } } @@ -252,29 +253,3 @@ int VtableStub::pd_code_alignment() { const unsigned int icache_line_size = 32; return icache_line_size; } - - -//Reconciliation History -// 1.2 97/12/09 17:13:31 vtableStubs_i486.cpp -// 1.4 98/01/21 19:18:37 vtableStubs_i486.cpp -// 1.5 98/02/13 16:33:55 vtableStubs_i486.cpp -// 1.7 98/03/05 17:17:28 vtableStubs_i486.cpp -// 1.9 98/05/18 09:26:17 vtableStubs_i486.cpp -// 1.10 98/05/26 16:28:13 vtableStubs_i486.cpp -// 1.11 98/05/27 08:51:35 vtableStubs_i486.cpp -// 1.12 98/06/15 15:04:12 vtableStubs_i486.cpp -// 1.13 98/07/28 18:44:22 vtableStubs_i486.cpp -// 1.15 98/08/28 11:31:19 vtableStubs_i486.cpp -// 1.16 98/09/02 12:58:31 vtableStubs_i486.cpp -// 1.17 98/09/04 12:15:52 vtableStubs_i486.cpp -// 1.18 98/11/19 11:55:24 vtableStubs_i486.cpp -// 1.19 99/01/12 14:57:56 vtableStubs_i486.cpp -// 1.20 99/01/19 17:42:52 vtableStubs_i486.cpp -// 1.22 99/01/21 10:29:25 vtableStubs_i486.cpp -// 1.30 99/06/02 15:27:39 vtableStubs_i486.cpp -// 1.26 99/06/24 14:25:07 vtableStubs_i486.cpp -// 1.23 99/02/22 14:37:52 vtableStubs_i486.cpp -// 1.28 99/06/29 18:06:17 vtableStubs_i486.cpp -// 1.29 99/07/22 17:03:44 vtableStubs_i486.cpp -// 1.30 99/08/11 09:33:27 vtableStubs_i486.cpp -//End diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 98c1ce59a60..5ea4177f90b 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -2151,6 +2151,7 @@ class StubGenerator: public StubCodeGenerator { // These entry points require SharedInfo::stack0 to be set up in non-core builds // and need to be relocatable, so they each fabricate a RuntimeStub internally. StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError), false); + StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false); StubRoutines::_throw_ArithmeticException_entry = generate_throw_exception("ArithmeticException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_ArithmeticException), true); StubRoutines::_throw_NullPointerException_entry = generate_throw_exception("NullPointerException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true); StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false); diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 738beafa314..720222b31e9 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -2832,6 +2832,13 @@ class StubGenerator: public StubCodeGenerator { throw_AbstractMethodError), false); + StubRoutines::_throw_IncompatibleClassChangeError_entry = + generate_throw_exception("IncompatibleClassChangeError throw_exception", + CAST_FROM_FN_PTR(address, + SharedRuntime:: + throw_IncompatibleClassChangeError), + false); + StubRoutines::_throw_ArithmeticException_entry = generate_throw_exception("ArithmeticException throw_exception", CAST_FROM_FN_PTR(address, diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp index fcf84f7b494..09d37901e61 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp @@ -138,29 +138,21 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ round_to(rbx, BytesPerLong); } - Label hit, next, entry; + Label hit, next, entry, throw_icce; - __ jmp(entry); + __ jmpb(entry); __ bind(next); __ addl(rbx, itableOffsetEntry::size() * wordSize); __ bind(entry); -#ifdef ASSERT - // Check that the entry is non-null - if (DebugVtables) { - Label L; - __ pushl(rbx); - __ movl(rbx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); - __ testl(rbx, rbx); - __ jcc(Assembler::notZero, L); - __ stop("null entry point found in itable's offset table"); - __ bind(L); - __ popl(rbx); - } -#endif - __ cmpl(rax, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); + // If the entry is NULL then we've reached the end of the table + // without finding the expected interface, so throw an exception + __ movl(rdx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); + __ testl(rdx, rdx); + __ jcc(Assembler::zero, throw_icce); + __ cmpl(rax, rdx); __ jcc(Assembler::notEqual, next); // We found a hit, move offset into rbx, @@ -194,7 +186,15 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { address ame_addr = __ pc(); __ jmp(Address(method, methodOopDesc::from_compiled_offset())); + __ bind(throw_icce); + // Restore saved register + __ popl(rdx); + __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); + masm->flush(); + + guarantee(__ pc() <= s->code_end(), "overflowed buffer"); + s->set_exception_points(npe_addr, ame_addr); return s; } @@ -207,7 +207,7 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) { return (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0); } else { // Itable stub size - return (DebugVtables ? 140 : 55) + (CountCompiledCalls ? 6 : 0); + return (DebugVtables ? 144 : 64) + (CountCompiledCalls ? 6 : 0); } } diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index fb6e87bb796..c68f7f363e9 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -153,7 +153,7 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { // Round up to align_object_offset boundary __ round_to_q(rbx, BytesPerLong); } - Label hit, next, entry; + Label hit, next, entry, throw_icce; __ jmpb(entry); @@ -162,22 +162,13 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { __ bind(entry); -#ifdef ASSERT - // Check that the entry is non-null - if (DebugVtables) { - Label L; - __ pushq(rbx); - __ movq(rbx, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); - __ testq(rbx, rbx); - __ jcc(Assembler::notZero, L); - __ stop("null entry point found in itable's offset table"); - __ bind(L); - __ popq(rbx); - } -#endif - - __ cmpq(rax, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); - __ jcc(Assembler::notEqual, next); + // If the entry is NULL then we've reached the end of the table + // without finding the expected interface, so throw an exception + __ movq(j_rarg1, Address(rbx, itableOffsetEntry::interface_offset_in_bytes())); + __ testq(j_rarg1, j_rarg1); + __ jcc(Assembler::zero, throw_icce); + __ cmpq(rax, j_rarg1); + __ jccb(Assembler::notEqual, next); // We found a hit, move offset into j_rarg1 __ movl(j_rarg1, Address(rbx, itableOffsetEntry::offset_offset_in_bytes())); @@ -203,23 +194,31 @@ VtableStub* VtableStubs::create_itable_stub(int vtable_index) { #ifdef ASSERT - if (DebugVtables) { - Label L2; - __ cmpq(method, (int)NULL); - __ jcc(Assembler::equal, L2); - __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); - __ jcc(Assembler::notZero, L2); - __ stop("compiler entrypoint is null"); - __ bind(L2); - } + if (DebugVtables) { + Label L2; + __ cmpq(method, (int)NULL); + __ jcc(Assembler::equal, L2); + __ cmpq(Address(method, methodOopDesc::from_compiled_offset()), (int)NULL_WORD); + __ jcc(Assembler::notZero, L2); + __ stop("compiler entrypoint is null"); + __ bind(L2); + } #endif // ASSERT - // rbx: methodOop - // j_rarg0: receiver - address ame_addr = __ pc(); - __ jmp(Address(method, methodOopDesc::from_compiled_offset())); + // rbx: methodOop + // j_rarg0: receiver + address ame_addr = __ pc(); + __ jmp(Address(method, methodOopDesc::from_compiled_offset())); + + __ bind(throw_icce); + // Restore saved register + __ popq(j_rarg1); + __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry())); __ flush(); + + guarantee(__ pc() <= s->code_end(), "overflowed buffer"); + s->set_exception_points(npe_addr, ame_addr); return s; } @@ -230,7 +229,7 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) { return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0); } else { // Itable stub size - return (DebugVtables ? 636 : 64) + (CountCompiledCalls ? 13 : 0); + return (DebugVtables ? 636 : 72) + (CountCompiledCalls ? 13 : 0); } } diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index 1b105cd2d87..84ce0c58a62 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -735,7 +735,7 @@ klassItable::klassItable(instanceKlassHandle klass) { } } - // This lenght of the itable was either zero, or it has not yet been initialized. + // The length of the itable was either zero, or it has not yet been initialized. _table_offset = 0; _size_offset_table = 0; _size_method_table = 0; @@ -870,16 +870,19 @@ static int initialize_count = 0; // Initialization void klassItable::initialize_itable(bool checkconstraints, TRAPS) { - // Cannot be setup doing bootstrapping - if (Universe::is_bootstrapping()) return; + // Cannot be setup doing bootstrapping, interfaces don't have + // itables, and klass with only ones entry have empty itables + if (Universe::is_bootstrapping() || + _klass->is_interface() || + _klass->itable_length() == itableOffsetEntry::size()) return; - int num_interfaces = nof_interfaces(); + // There's alway an extra itable entry so we can null-terminate it. + guarantee(size_offset_table() >= 1, "too small"); + int num_interfaces = size_offset_table() - 1; if (num_interfaces > 0) { - if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, _klass->name()->as_C_string()); + if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, + _klass->name()->as_C_string()); - // In debug mode, we got an extra NULL/NULL entry - debug_only(num_interfaces--); - assert(num_interfaces > 0, "to few interfaces in offset itable"); // Interate through all interfaces int i; @@ -890,12 +893,10 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) { initialize_itable_for_interface(ioe->offset(), interf_h, checkconstraints, CHECK); } -#ifdef ASSERT - // Check that the last entry is empty - itableOffsetEntry* ioe = offset_entry(i); - assert(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing"); -#endif } + // Check that the last entry is empty + itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1); + guarantee(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing"); } @@ -972,7 +973,7 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass } } -// Update entry for specic methodOop +// Update entry for specific methodOop void klassItable::initialize_with_method(methodOop m) { itableMethodEntry* ime = method_entry(0); for(int i = 0; i < _size_method_table; i++) { @@ -1085,12 +1086,8 @@ int klassItable::compute_itable_size(objArrayHandle transitive_interfaces) { CountInterfacesClosure cic; visit_all_interfaces(transitive_interfaces(), &cic); - // Add one extra entry in debug mode, so we can null-terminate the table - int nof_methods = cic.nof_methods(); - int nof_interfaces = cic.nof_interfaces(); - debug_only(if (nof_interfaces > 0) nof_interfaces++); - - int itable_size = calc_itable_size(nof_interfaces, nof_methods); + // There's alway an extra itable entry so we can null-terminate it. + int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods()); // Statistics update_stats(itable_size * HeapWordSize); @@ -1110,8 +1107,8 @@ void klassItable::setup_itable_offset_table(instanceKlassHandle klass) { int nof_methods = cic.nof_methods(); int nof_interfaces = cic.nof_interfaces(); - // Add one extra entry in debug mode, so we can null-terminate the table - debug_only(if (nof_interfaces > 0) nof_interfaces++); + // Add one extra entry so we can null-terminate the table + nof_interfaces++; assert(compute_itable_size(objArrayHandle(klass->transitive_interfaces())) == calc_itable_size(nof_interfaces, nof_methods), diff --git a/hotspot/src/share/vm/oops/klassVtable.hpp b/hotspot/src/share/vm/oops/klassVtable.hpp index 221e1d21d66..2ef1848f59e 100644 --- a/hotspot/src/share/vm/oops/klassVtable.hpp +++ b/hotspot/src/share/vm/oops/klassVtable.hpp @@ -259,7 +259,7 @@ class klassItable : public ResourceObj { itableMethodEntry* method_entry(int i) { assert(0 <= i && i <= _size_method_table, "index out of bounds"); return &((itableMethodEntry*)method_start())[i]; } - int nof_interfaces() { return _size_offset_table; } + int size_offset_table() { return _size_offset_table; } // Initialization void initialize_itable(bool checkconstraints, TRAPS); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index e9a5685889d..cda256b74a3 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -467,6 +467,11 @@ JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread)) throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_AbstractMethodError()); JRT_END +JRT_ENTRY(void, SharedRuntime::throw_IncompatibleClassChangeError(JavaThread* thread)) + // These errors occur only at call sites + throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError(), "vtable stub"); +JRT_END + JRT_ENTRY(void, SharedRuntime::throw_ArithmeticException(JavaThread* thread)) throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArithmeticException(), "/ by zero"); JRT_END diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp index b91837f36e4..b2138d0a703 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp @@ -104,6 +104,7 @@ class SharedRuntime: AllStatic { STACK_OVERFLOW }; static void throw_AbstractMethodError(JavaThread* thread); + static void throw_IncompatibleClassChangeError(JavaThread* thread); static void throw_ArithmeticException(JavaThread* thread); static void throw_NullPointerException(JavaThread* thread); static void throw_NullPointerException_at_call(JavaThread* thread); diff --git a/hotspot/src/share/vm/runtime/stubRoutines.cpp b/hotspot/src/share/vm/runtime/stubRoutines.cpp index 63b30d86d7d..bdad678b0cb 100644 --- a/hotspot/src/share/vm/runtime/stubRoutines.cpp +++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp @@ -40,6 +40,7 @@ address StubRoutines::_call_stub_entry = NULL; address StubRoutines::_catch_exception_entry = NULL; address StubRoutines::_forward_exception_entry = NULL; address StubRoutines::_throw_AbstractMethodError_entry = NULL; +address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL; address StubRoutines::_throw_ArithmeticException_entry = NULL; address StubRoutines::_throw_NullPointerException_entry = NULL; address StubRoutines::_throw_NullPointerException_at_call_entry = NULL; diff --git a/hotspot/src/share/vm/runtime/stubRoutines.hpp b/hotspot/src/share/vm/runtime/stubRoutines.hpp index 17246a8bcaa..67741916488 100644 --- a/hotspot/src/share/vm/runtime/stubRoutines.hpp +++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp @@ -84,6 +84,7 @@ class StubRoutines: AllStatic { static address _forward_exception_entry; static address _catch_exception_entry; static address _throw_AbstractMethodError_entry; + static address _throw_IncompatibleClassChangeError_entry; static address _throw_ArithmeticException_entry; static address _throw_NullPointerException_entry; static address _throw_NullPointerException_at_call_entry; @@ -184,6 +185,7 @@ class StubRoutines: AllStatic { static address forward_exception_entry() { return _forward_exception_entry; } // Implicit exceptions static address throw_AbstractMethodError_entry() { return _throw_AbstractMethodError_entry; } + static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; } static address throw_ArithmeticException_entry() { return _throw_ArithmeticException_entry; } static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; } static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; } From 10c473e425fc6f4b4348488984b1013bc955224e Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 5 Dec 2007 09:01:00 -0800 Subject: [PATCH 008/274] 6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long) Reviewed-by: kvn, rasbold --- hotspot/src/share/vm/ci/ciObjArray.cpp | 43 ++++ hotspot/src/share/vm/ci/ciObjArray.hpp | 2 + hotspot/src/share/vm/classfile/vmSymbols.hpp | 6 + hotspot/src/share/vm/includeDB_core | 15 +- hotspot/src/share/vm/opto/addnode.cpp | 22 ++ hotspot/src/share/vm/opto/addnode.hpp | 5 + hotspot/src/share/vm/opto/c2_globals.hpp | 6 + hotspot/src/share/vm/opto/cfgnode.hpp | 6 + hotspot/src/share/vm/opto/ifnode.cpp | 158 +++++++++++++ hotspot/src/share/vm/opto/loopnode.cpp | 55 +---- hotspot/src/share/vm/opto/loopnode.hpp | 1 - hotspot/src/share/vm/opto/memnode.cpp | 224 +++++++++++++++++++ hotspot/src/share/vm/opto/memnode.hpp | 3 + hotspot/src/share/vm/opto/parse2.cpp | 43 +++- hotspot/src/share/vm/opto/type.hpp | 2 + hotspot/src/share/vm/runtime/arguments.cpp | 16 ++ 16 files changed, 540 insertions(+), 67 deletions(-) create mode 100644 hotspot/src/share/vm/ci/ciObjArray.cpp diff --git a/hotspot/src/share/vm/ci/ciObjArray.cpp b/hotspot/src/share/vm/ci/ciObjArray.cpp new file mode 100644 index 00000000000..fe47238625c --- /dev/null +++ b/hotspot/src/share/vm/ci/ciObjArray.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. 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. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_ciObjArray.cpp.incl" + +// ciObjArray +// +// This class represents an objArrayOop in the HotSpot virtual +// machine. + +ciObject* ciObjArray::obj_at(int index) { + VM_ENTRY_MARK; + objArrayOop array = get_objArrayOop(); + if (index < 0 || index >= array->length()) return NULL; + oop o = array->obj_at(index); + if (o == NULL) { + return ciNullObject::make(); + } else { + return CURRENT_ENV->get_object(o); + } +} diff --git a/hotspot/src/share/vm/ci/ciObjArray.hpp b/hotspot/src/share/vm/ci/ciObjArray.hpp index c43700fac23..602ff55e4de 100644 --- a/hotspot/src/share/vm/ci/ciObjArray.hpp +++ b/hotspot/src/share/vm/ci/ciObjArray.hpp @@ -43,4 +43,6 @@ protected: public: // What kind of ciObject is this? bool is_obj_array() { return true; } + + ciObject* obj_at(int index); }; diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index e0119432ddc..9ba9b0c7c10 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -58,12 +58,17 @@ template(java_lang_ThreadDeath, "java/lang/ThreadDeath") \ template(java_lang_Boolean, "java/lang/Boolean") \ template(java_lang_Character, "java/lang/Character") \ + template(java_lang_Character_CharacterCache, "java/lang/Character$CharacterCache") \ template(java_lang_Float, "java/lang/Float") \ template(java_lang_Double, "java/lang/Double") \ template(java_lang_Byte, "java/lang/Byte") \ + template(java_lang_Byte_Cache, "java/lang/Byte$ByteCache") \ template(java_lang_Short, "java/lang/Short") \ + template(java_lang_Short_ShortCache, "java/lang/Short$ShortCache") \ template(java_lang_Integer, "java/lang/Integer") \ + template(java_lang_Integer_IntegerCache, "java/lang/Integer$IntegerCache") \ template(java_lang_Long, "java/lang/Long") \ + template(java_lang_Long_LongCache, "java/lang/Long$LongCache") \ template(java_lang_Shutdown, "java/lang/Shutdown") \ template(java_lang_ref_Reference, "java/lang/ref/Reference") \ template(java_lang_ref_SoftReference, "java/lang/ref/SoftReference") \ @@ -274,6 +279,7 @@ template(exclusive_owner_thread_name, "exclusiveOwnerThread") \ template(park_blocker_name, "parkBlocker") \ template(park_event_name, "nativeParkEventPointer") \ + template(cache_field_name, "cache") \ template(value_name, "value") \ \ /* non-intrinsic name/signature pairs: */ \ diff --git a/hotspot/src/share/vm/includeDB_core b/hotspot/src/share/vm/includeDB_core index cbf8e561a73..aa7e7196523 100644 --- a/hotspot/src/share/vm/includeDB_core +++ b/hotspot/src/share/vm/includeDB_core @@ -19,7 +19,7 @@ // 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. -// +// // // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! @@ -46,13 +46,13 @@ // as dependencies. Header files named H.inline.hpp generally contain // bodies for inline functions declared in H.hpp. // -// NOTE: Files that use the token "generate_platform_dependent_include" +// NOTE: Files that use the token "generate_platform_dependent_include" // are expected to contain macro references like , , ... and // makedeps has a dependency on these platform files looking like: -// foo_.trailing_string +// foo_.trailing_string // (where "trailing_string" can be any legal filename strings but typically // is "hpp" or "inline.hpp"). -// +// // The dependency in makedeps (and enforced) is that an underscore // will precedure the macro invocation. Note that this restriction // is only enforced on filenames that have the dependency token @@ -720,6 +720,11 @@ ciObjArray.hpp ciArray.hpp ciObjArray.hpp ciClassList.hpp ciObjArray.hpp objArrayOop.hpp +ciObjArray.cpp ciObjArray.hpp +ciObjArray.cpp ciNullObject.hpp +ciObjArray.cpp ciUtilities.hpp +ciObjArray.cpp objArrayOop.hpp + ciObjArrayKlass.cpp ciInstanceKlass.hpp ciObjArrayKlass.cpp ciObjArrayKlass.hpp ciObjArrayKlass.cpp ciObjArrayKlassKlass.hpp @@ -1935,7 +1940,7 @@ icache_.hpp generate_platform_dependent_include init.cpp bytecodes.hpp init.cpp collectedHeap.hpp -init.cpp handles.inline.hpp +init.cpp handles.inline.hpp init.cpp icBuffer.hpp init.cpp icache.hpp init.cpp init.hpp diff --git a/hotspot/src/share/vm/opto/addnode.cpp b/hotspot/src/share/vm/opto/addnode.cpp index 42a17c997dc..7b29f422911 100644 --- a/hotspot/src/share/vm/opto/addnode.cpp +++ b/hotspot/src/share/vm/opto/addnode.cpp @@ -608,6 +608,28 @@ Node* AddPNode::Ideal_base_and_offset(Node* ptr, PhaseTransform* phase, return NULL; } +//------------------------------unpack_offsets---------------------------------- +// Collect the AddP offset values into the elements array, giving up +// if there are more than length. +int AddPNode::unpack_offsets(Node* elements[], int length) { + int count = 0; + Node* addr = this; + Node* base = addr->in(AddPNode::Base); + while (addr->is_AddP()) { + if (addr->in(AddPNode::Base) != base) { + // give up + return -1; + } + elements[count++] = addr->in(AddPNode::Offset); + if (count == length) { + // give up + return -1; + } + addr = addr->in(AddPNode::Address); + } + return count; +} + //------------------------------match_edge------------------------------------- // Do we Match on this edge index or not? Do not match base pointer edge uint AddPNode::match_edge(uint idx) const { diff --git a/hotspot/src/share/vm/opto/addnode.hpp b/hotspot/src/share/vm/opto/addnode.hpp index 5170f50e17d..acd210c9333 100644 --- a/hotspot/src/share/vm/opto/addnode.hpp +++ b/hotspot/src/share/vm/opto/addnode.hpp @@ -144,6 +144,11 @@ public: static Node* Ideal_base_and_offset(Node* ptr, PhaseTransform* phase, // second return value: intptr_t& offset); + + // Collect the AddP offset values into the elements array, giving up + // if there are more than length. + int unpack_offsets(Node* elements[], int length); + // Do not match base-ptr edge virtual uint match_edge(uint idx) const; static const Type *mach_bottom_type(const MachNode* n); // used by ad_.hpp diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 360300255d7..4cfbcca2c98 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -367,6 +367,12 @@ notproduct(bool, PrintEliminateLocks, false, \ "Print out when locks are eliminated") \ \ + diagnostic(bool, EliminateAutoBox, false, \ + "Private flag to control optimizations for autobox elimination") \ + \ + product(intx, AutoBoxCacheMax, 128, \ + "Sets max value cached by the java.lang.Integer autobox cache") \ + \ product(bool, DoEscapeAnalysis, false, \ "Perform escape analysis") \ \ diff --git a/hotspot/src/share/vm/opto/cfgnode.hpp b/hotspot/src/share/vm/opto/cfgnode.hpp index e01e25258ec..b198a5bf7ab 100644 --- a/hotspot/src/share/vm/opto/cfgnode.hpp +++ b/hotspot/src/share/vm/opto/cfgnode.hpp @@ -310,8 +310,14 @@ public: virtual const RegMask &out_RegMask() const; void dominated_by(Node* prev_dom, PhaseIterGVN* igvn); int is_range_check(Node* &range, Node* &index, jint &offset); + Node* fold_compares(PhaseGVN* phase); static Node* up_one_dom(Node* curr, bool linear_only = false); + // Takes the type of val and filters it through the test represented + // by if_proj and returns a more refined type if one is produced. + // Returns NULL is it couldn't improve the type. + static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj); + #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 48031ef3d5a..073d4202f68 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -543,6 +543,159 @@ Node* IfNode::up_one_dom(Node *curr, bool linear_only) { return NULL; // Dead loop? Or hit root? } + +//------------------------------filtered_int_type-------------------------------- +// Return a possibly more restrictive type for val based on condition control flow for an if +const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node *val, Node* if_proj) { + assert(if_proj && + (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection"); + if (if_proj->in(0) && if_proj->in(0)->is_If()) { + IfNode* iff = if_proj->in(0)->as_If(); + if (iff->in(1) && iff->in(1)->is_Bool()) { + BoolNode* bol = iff->in(1)->as_Bool(); + if (bol->in(1) && bol->in(1)->is_Cmp()) { + const CmpNode* cmp = bol->in(1)->as_Cmp(); + if (cmp->in(1) == val) { + const TypeInt* cmp2_t = gvn->type(cmp->in(2))->isa_int(); + if (cmp2_t != NULL) { + jint lo = cmp2_t->_lo; + jint hi = cmp2_t->_hi; + BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate(); + switch (msk) { + case BoolTest::ne: + // Can't refine type + return NULL; + case BoolTest::eq: + return cmp2_t; + case BoolTest::lt: + lo = TypeInt::INT->_lo; + if (hi - 1 < hi) { + hi = hi - 1; + } + break; + case BoolTest::le: + lo = TypeInt::INT->_lo; + break; + case BoolTest::gt: + if (lo + 1 > lo) { + lo = lo + 1; + } + hi = TypeInt::INT->_hi; + break; + case BoolTest::ge: + // lo unchanged + hi = TypeInt::INT->_hi; + break; + } + const TypeInt* rtn_t = TypeInt::make(lo, hi, cmp2_t->_widen); + return rtn_t; + } + } + } + } + } + return NULL; +} + +//------------------------------fold_compares---------------------------- +// See if a pair of CmpIs can be converted into a CmpU. In some cases +// the direction of this if is determined by the preciding if so it +// can be eliminate entirely. Given an if testing (CmpI n c) check +// for an immediately control dependent if that is testing (CmpI n c2) +// and has one projection leading to this if and the other projection +// leading to a region that merges one of this ifs control +// projections. +// +// If +// / | +// / | +// / | +// If | +// /\ | +// / \ | +// / \ | +// / Region +// +Node* IfNode::fold_compares(PhaseGVN* phase) { + if (!EliminateAutoBox || Opcode() != Op_If) return NULL; + + Node* this_cmp = in(1)->in(1); + if (this_cmp != NULL && this_cmp->Opcode() == Op_CmpI && + this_cmp->in(2)->is_Con() && this_cmp->in(2) != phase->C->top()) { + Node* ctrl = in(0); + BoolNode* this_bool = in(1)->as_Bool(); + Node* n = this_cmp->in(1); + int hi = this_cmp->in(2)->get_int(); + if (ctrl != NULL && ctrl->is_Proj() && ctrl->outcnt() == 1 && + ctrl->in(0)->is_If() && + ctrl->in(0)->outcnt() == 2 && + ctrl->in(0)->in(1)->is_Bool() && + ctrl->in(0)->in(1)->in(1)->Opcode() == Op_CmpI && + ctrl->in(0)->in(1)->in(1)->in(2)->is_Con() && + ctrl->in(0)->in(1)->in(1)->in(1) == n) { + IfNode* dom_iff = ctrl->in(0)->as_If(); + Node* otherproj = dom_iff->proj_out(!ctrl->as_Proj()->_con); + if (otherproj->outcnt() == 1 && otherproj->unique_out()->is_Region() && + this_bool->_test._test != BoolTest::ne && this_bool->_test._test != BoolTest::eq) { + // Identify which proj goes to the region and which continues on + RegionNode* region = otherproj->unique_out()->as_Region(); + Node* success = NULL; + Node* fail = NULL; + for (int i = 0; i < 2; i++) { + Node* proj = proj_out(i); + if (success == NULL && proj->outcnt() == 1 && proj->unique_out() == region) { + success = proj; + } else if (fail == NULL) { + fail = proj; + } else { + success = fail = NULL; + } + } + if (success != NULL && fail != NULL && !region->has_phi()) { + int lo = dom_iff->in(1)->in(1)->in(2)->get_int(); + BoolNode* dom_bool = dom_iff->in(1)->as_Bool(); + Node* dom_cmp = dom_bool->in(1); + const TypeInt* failtype = filtered_int_type(phase, n, ctrl); + if (failtype != NULL) { + const TypeInt* type2 = filtered_int_type(phase, n, fail); + if (type2 != NULL) { + failtype = failtype->join(type2)->is_int(); + } else { + failtype = NULL; + } + } + + if (failtype != NULL && + dom_bool->_test._test != BoolTest::ne && dom_bool->_test._test != BoolTest::eq) { + int bound = failtype->_hi - failtype->_lo + 1; + if (failtype->_hi != max_jint && failtype->_lo != min_jint && bound > 1) { + // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) hi) + BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge; + Node* adjusted = phase->transform(new (phase->C, 3) SubINode(n, phase->intcon(failtype->_lo))); + Node* newcmp = phase->transform(new (phase->C, 3) CmpUNode(adjusted, phase->intcon(bound))); + Node* newbool = phase->transform(new (phase->C, 2) BoolNode(newcmp, cond)); + phase->hash_delete(dom_iff); + dom_iff->set_req(1, phase->intcon(ctrl->as_Proj()->_con)); + phase->is_IterGVN()->_worklist.push(dom_iff); + phase->hash_delete(this); + set_req(1, newbool); + return this; + } + if (failtype->_lo > failtype->_hi) { + // previous if determines the result of this if so + // replace Bool with constant + phase->hash_delete(this); + set_req(1, phase->intcon(success->as_Proj()->_con)); + return this; + } + } + } + } + } + } + return NULL; +} + //------------------------------remove_useless_bool---------------------------- // Check for people making a useless boolean: things like // if( (x < y ? true : false) ) { ... } @@ -744,6 +897,11 @@ Node *IfNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Normal equivalent-test check. if( !dom ) return NULL; // Dead loop? + Node* result = fold_compares(phase); + if (result != NULL) { + return result; + } + // Search up the dominator tree for an If with an identical test while( dom->Opcode() != op || // Not same opcode? dom->in(1) != in(1) || // Not same input 1? diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index 938862f0fa4..96140fae598 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -651,7 +651,7 @@ const TypeInt* PhaseIdealLoop::filtered_type_from_dominators( Node* val, Node *u while (if_cnt < if_limit) { if ((pred->Opcode() == Op_IfTrue || pred->Opcode() == Op_IfFalse)) { if_cnt++; - const TypeInt* if_t = filtered_type_at_if(val, pred); + const TypeInt* if_t = IfNode::filtered_int_type(&_igvn, val, pred); if (if_t != NULL) { if (rtn_t == NULL) { rtn_t = if_t; @@ -674,59 +674,6 @@ const TypeInt* PhaseIdealLoop::filtered_type_from_dominators( Node* val, Node *u } -//------------------------------filtered_type_at_if-------------------------------- -// Return a possibly more restrictive type for val based on condition control flow for an if -const TypeInt* PhaseIdealLoop::filtered_type_at_if( Node* val, Node *if_proj) { - assert(if_proj && - (if_proj->Opcode() == Op_IfTrue || if_proj->Opcode() == Op_IfFalse), "expecting an if projection"); - if (if_proj->in(0) && if_proj->in(0)->is_If()) { - IfNode* iff = if_proj->in(0)->as_If(); - if (iff->in(1) && iff->in(1)->is_Bool()) { - BoolNode* bol = iff->in(1)->as_Bool(); - if (bol->in(1) && bol->in(1)->is_Cmp()) { - const CmpNode* cmp = bol->in(1)->as_Cmp(); - if (cmp->in(1) == val) { - const TypeInt* cmp2_t = _igvn.type(cmp->in(2))->isa_int(); - if (cmp2_t != NULL) { - jint lo = cmp2_t->_lo; - jint hi = cmp2_t->_hi; - BoolTest::mask msk = if_proj->Opcode() == Op_IfTrue ? bol->_test._test : bol->_test.negate(); - switch (msk) { - case BoolTest::ne: - // Can't refine type - return NULL; - case BoolTest::eq: - return cmp2_t; - case BoolTest::lt: - lo = TypeInt::INT->_lo; - if (hi - 1 < hi) { - hi = hi - 1; - } - break; - case BoolTest::le: - lo = TypeInt::INT->_lo; - break; - case BoolTest::gt: - if (lo + 1 > lo) { - lo = lo + 1; - } - hi = TypeInt::INT->_hi; - break; - case BoolTest::ge: - // lo unchanged - hi = TypeInt::INT->_hi; - break; - } - const TypeInt* rtn_t = TypeInt::make(lo, hi, cmp2_t->_widen); - return rtn_t; - } - } - } - } - } - return NULL; -} - //------------------------------dump_spec-------------------------------------- // Dump special per-node info #ifndef PRODUCT diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp index 21ddf801586..60944afeee8 100644 --- a/hotspot/src/share/vm/opto/loopnode.hpp +++ b/hotspot/src/share/vm/opto/loopnode.hpp @@ -850,7 +850,6 @@ private: const TypeInt* filtered_type( Node *n ) { return filtered_type(n, NULL); } // Helpers for filtered type const TypeInt* filtered_type_from_dominators( Node* val, Node *val_ctrl); - const TypeInt* filtered_type_at_if( Node* val, Node *if_proj); // Helper functions void register_new_node( Node *n, Node *blk ); diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 26904be5853..b65a03bbf3b 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -634,6 +634,46 @@ uint LoadNode::hash() const { Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { Node* ld_adr = in(MemNode::Address); + const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr(); + Compile::AliasType* atp = tp != NULL ? phase->C->alias_type(tp) : NULL; + if (EliminateAutoBox && atp != NULL && atp->index() >= Compile::AliasIdxRaw && + atp->field() != NULL && !atp->field()->is_volatile()) { + uint alias_idx = atp->index(); + bool final = atp->field()->is_final(); + Node* result = NULL; + Node* current = st; + // Skip through chains of MemBarNodes checking the MergeMems for + // new states for the slice of this load. Stop once any other + // kind of node is encountered. Loads from final memory can skip + // through any kind of MemBar but normal loads shouldn't skip + // through MemBarAcquire since the could allow them to move out of + // a synchronized region. + while (current->is_Proj()) { + int opc = current->in(0)->Opcode(); + if ((final && opc == Op_MemBarAcquire) || + opc == Op_MemBarRelease || opc == Op_MemBarCPUOrder) { + Node* mem = current->in(0)->in(TypeFunc::Memory); + if (mem->is_MergeMem()) { + MergeMemNode* merge = mem->as_MergeMem(); + Node* new_st = merge->memory_at(alias_idx); + if (new_st == merge->base_memory()) { + // Keep searching + current = merge->base_memory(); + continue; + } + // Save the new memory state for the slice and fall through + // to exit. + result = new_st; + } + } + break; + } + if (result != NULL) { + st = result; + } + } + + // Loop around twice in the case Load -> Initialize -> Store. // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.) for (int trip = 0; trip <= 1; trip++) { @@ -723,6 +763,168 @@ Node *LoadNode::Identity( PhaseTransform *phase ) { return this; } + +// Returns true if the AliasType refers to the field that holds the +// cached box array. Currently only handles the IntegerCache case. +static bool is_autobox_cache(Compile::AliasType* atp) { + if (atp != NULL && atp->field() != NULL) { + ciField* field = atp->field(); + ciSymbol* klass = field->holder()->name(); + if (field->name() == ciSymbol::cache_field_name() && + field->holder()->uses_default_loader() && + klass == ciSymbol::java_lang_Integer_IntegerCache()) { + return true; + } + } + return false; +} + +// Fetch the base value in the autobox array +static bool fetch_autobox_base(Compile::AliasType* atp, int& cache_offset) { + if (atp != NULL && atp->field() != NULL) { + ciField* field = atp->field(); + ciSymbol* klass = field->holder()->name(); + if (field->name() == ciSymbol::cache_field_name() && + field->holder()->uses_default_loader() && + klass == ciSymbol::java_lang_Integer_IntegerCache()) { + assert(field->is_constant(), "what?"); + ciObjArray* array = field->constant_value().as_object()->as_obj_array(); + // Fetch the box object at the base of the array and get its value + ciInstance* box = array->obj_at(0)->as_instance(); + ciInstanceKlass* ik = box->klass()->as_instance_klass(); + if (ik->nof_nonstatic_fields() == 1) { + // This should be true nonstatic_field_at requires calling + // nof_nonstatic_fields so check it anyway + ciConstant c = box->field_value(ik->nonstatic_field_at(0)); + cache_offset = c.as_int(); + } + return true; + } + } + return false; +} + +// Returns true if the AliasType refers to the value field of an +// autobox object. Currently only handles Integer. +static bool is_autobox_object(Compile::AliasType* atp) { + if (atp != NULL && atp->field() != NULL) { + ciField* field = atp->field(); + ciSymbol* klass = field->holder()->name(); + if (field->name() == ciSymbol::value_name() && + field->holder()->uses_default_loader() && + klass == ciSymbol::java_lang_Integer()) { + return true; + } + } + return false; +} + + +// We're loading from an object which has autobox behaviour. +// If this object is result of a valueOf call we'll have a phi +// merging a newly allocated object and a load from the cache. +// We want to replace this load with the original incoming +// argument to the valueOf call. +Node* LoadNode::eliminate_autobox(PhaseGVN* phase) { + Node* base = in(Address)->in(AddPNode::Base); + if (base->is_Phi() && base->req() == 3) { + AllocateNode* allocation = NULL; + int allocation_index = -1; + int load_index = -1; + for (uint i = 1; i < base->req(); i++) { + allocation = AllocateNode::Ideal_allocation(base->in(i), phase); + if (allocation != NULL) { + allocation_index = i; + load_index = 3 - allocation_index; + break; + } + } + LoadNode* load = NULL; + if (allocation != NULL && base->in(load_index)->is_Load()) { + load = base->in(load_index)->as_Load(); + } + if (load != NULL && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) { + // Push the loads from the phi that comes from valueOf up + // through it to allow elimination of the loads and the recovery + // of the original value. + Node* mem_phi = in(Memory); + Node* offset = in(Address)->in(AddPNode::Offset); + + Node* in1 = clone(); + Node* in1_addr = in1->in(Address)->clone(); + in1_addr->set_req(AddPNode::Base, base->in(allocation_index)); + in1_addr->set_req(AddPNode::Address, base->in(allocation_index)); + in1_addr->set_req(AddPNode::Offset, offset); + in1->set_req(0, base->in(allocation_index)); + in1->set_req(Address, in1_addr); + in1->set_req(Memory, mem_phi->in(allocation_index)); + + Node* in2 = clone(); + Node* in2_addr = in2->in(Address)->clone(); + in2_addr->set_req(AddPNode::Base, base->in(load_index)); + in2_addr->set_req(AddPNode::Address, base->in(load_index)); + in2_addr->set_req(AddPNode::Offset, offset); + in2->set_req(0, base->in(load_index)); + in2->set_req(Address, in2_addr); + in2->set_req(Memory, mem_phi->in(load_index)); + + in1_addr = phase->transform(in1_addr); + in1 = phase->transform(in1); + in2_addr = phase->transform(in2_addr); + in2 = phase->transform(in2); + + PhiNode* result = PhiNode::make_blank(base->in(0), this); + result->set_req(allocation_index, in1); + result->set_req(load_index, in2); + return result; + } + } else if (base->is_Load()) { + // Eliminate the load of Integer.value for integers from the cache + // array by deriving the value from the index into the array. + // Capture the offset of the load and then reverse the computation. + Node* load_base = base->in(Address)->in(AddPNode::Base); + if (load_base != NULL) { + Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type()); + intptr_t cache_offset; + int shift = -1; + Node* cache = NULL; + if (is_autobox_cache(atp)) { + shift = exact_log2(type2aelembytes[T_OBJECT]); + cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset); + } + if (cache != NULL && base->in(Address)->is_AddP()) { + Node* elements[4]; + int count = base->in(Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements)); + int cache_low; + if (count > 0 && fetch_autobox_base(atp, cache_low)) { + int offset = arrayOopDesc::base_offset_in_bytes(memory_type()) - (cache_low << shift); + // Add up all the offsets making of the address of the load + Node* result = elements[0]; + for (int i = 1; i < count; i++) { + result = phase->transform(new (phase->C, 3) AddXNode(result, elements[i])); + } + // Remove the constant offset from the address and then + // remove the scaling of the offset to recover the original index. + result = phase->transform(new (phase->C, 3) AddXNode(result, phase->MakeConX(-offset))); + if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) { + // Peel the shift off directly but wrap it in a dummy node + // since Ideal can't return existing nodes + result = new (phase->C, 3) RShiftXNode(result->in(1), phase->intcon(0)); + } else { + result = new (phase->C, 3) RShiftXNode(result, phase->intcon(shift)); + } +#ifdef _LP64 + result = new (phase->C, 2) ConvL2INode(phase->transform(result)); +#endif + return result; + } + } + } + } + return NULL; +} + + //------------------------------Ideal------------------------------------------ // If the load is from Field memory and the pointer is non-null, we can // zero out the control input. @@ -755,6 +957,17 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { } } + if (EliminateAutoBox && can_reshape && in(Address)->is_AddP()) { + Node* base = in(Address)->in(AddPNode::Base); + if (base != NULL) { + Compile::AliasType* atp = phase->C->alias_type(adr_type()); + if (is_autobox_object(atp)) { + Node* result = eliminate_autobox(phase); + if (result != NULL) return result; + } + } + } + // Check for prior store with a different base or offset; make Load // independent. Skip through any number of them. Bail out if the stores // are in an endless dead cycle and report no progress. This is a key @@ -858,6 +1071,17 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { // This can happen if a interface-typed array narrows to a class type. jt = _type; } + + if (EliminateAutoBox) { + // The pointers in the autobox arrays are always non-null + Node* base = in(Address)->in(AddPNode::Base); + if (base != NULL) { + Compile::AliasType* atp = phase->C->alias_type(base->adr_type()); + if (is_autobox_cache(atp)) { + return jt->join(TypePtr::NOTNULL)->is_ptr(); + } + } + } return jt; } } diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index 989e255a9b2..34f36a27118 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -141,6 +141,9 @@ public: // zero out the control input. virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + // Recover original value from boxed values + Node *eliminate_autobox(PhaseGVN *phase); + // Compute a new Type for this node. Basically we just do the pre-check, // then call the virtual add() to set the type. virtual const Type *Value( PhaseTransform *phase ) const; diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index 2a5b0da07e8..ae8615d0152 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -885,6 +885,9 @@ inline void Parse::repush_if_args() { void Parse::do_ifnull(BoolTest::mask btest) { int target_bci = iter().get_dest(); + Block* branch_block = successor_for_bci(target_bci); + Block* next_block = successor_for_bci(iter().next_bci()); + float cnt; float prob = branch_prediction(cnt, btest, target_bci); if (prob == PROB_UNKNOWN) { @@ -902,13 +905,16 @@ void Parse::do_ifnull(BoolTest::mask btest) { uncommon_trap(Deoptimization::Reason_unreached, Deoptimization::Action_reinterpret, NULL, "cold"); + if (EliminateAutoBox) { + // Mark the successor blocks as parsed + branch_block->next_path_num(); + next_block->next_path_num(); + } return; } // If this is a backwards branch in the bytecodes, add Safepoint maybe_add_safepoint(target_bci); - Block* branch_block = successor_for_bci(target_bci); - Block* next_block = successor_for_bci(iter().next_bci()); explicit_null_checks_inserted++; Node* a = null(); @@ -935,6 +941,10 @@ void Parse::do_ifnull(BoolTest::mask btest) { if (stopped()) { // Path is dead? explicit_null_checks_elided++; + if (EliminateAutoBox) { + // Mark the successor block as parsed + branch_block->next_path_num(); + } } else { // Path is live. // Update method data profile_taken_branch(target_bci); @@ -950,6 +960,10 @@ void Parse::do_ifnull(BoolTest::mask btest) { if (stopped()) { // Path is dead? explicit_null_checks_elided++; + if (EliminateAutoBox) { + // Mark the successor block as parsed + next_block->next_path_num(); + } } else { // Path is live. // Update method data profile_not_taken_branch(); @@ -962,6 +976,9 @@ void Parse::do_ifnull(BoolTest::mask btest) { void Parse::do_if(BoolTest::mask btest, Node* c) { int target_bci = iter().get_dest(); + Block* branch_block = successor_for_bci(target_bci); + Block* next_block = successor_for_bci(iter().next_bci()); + float cnt; float prob = branch_prediction(cnt, btest, target_bci); float untaken_prob = 1.0 - prob; @@ -980,6 +997,11 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { uncommon_trap(Deoptimization::Reason_unreached, Deoptimization::Action_reinterpret, NULL, "cold"); + if (EliminateAutoBox) { + // Mark the successor blocks as parsed + branch_block->next_path_num(); + next_block->next_path_num(); + } return; } @@ -1018,15 +1040,17 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { untaken_branch = tmp; } - Block* branch_block = successor_for_bci(target_bci); - Block* next_block = successor_for_bci(iter().next_bci()); - // Branch is taken: { PreserveJVMState pjvms(this); taken_branch = _gvn.transform(taken_branch); set_control(taken_branch); - if (!stopped()) { + if (stopped()) { + if (EliminateAutoBox) { + // Mark the successor block as parsed + branch_block->next_path_num(); + } + } else { // Update method data profile_taken_branch(target_bci); adjust_map_after_if(taken_btest, c, prob, branch_block, next_block); @@ -1039,7 +1063,12 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { set_control(untaken_branch); // Branch not taken. - if (!stopped()) { + if (stopped()) { + if (EliminateAutoBox) { + // Mark the successor block as parsed + next_block->next_path_num(); + } + } else { // Update method data profile_not_taken_branch(); adjust_map_after_if(untaken_btest, c, untaken_prob, diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index cca1e6404bd..4a697311f61 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -1070,6 +1070,7 @@ inline bool Type::is_floatingpoint() const { #define LShiftXNode LShiftLNode // For object size computation: #define AddXNode AddLNode +#define RShiftXNode RShiftLNode // For card marks and hashcodes #define URShiftXNode URShiftLNode // Opcodes @@ -1108,6 +1109,7 @@ inline bool Type::is_floatingpoint() const { #define LShiftXNode LShiftINode // For object size computation: #define AddXNode AddINode +#define RShiftXNode RShiftINode // For card marks and hashcodes #define URShiftXNode URShiftINode // Opcodes diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 5d0329ad046..ae4711132c2 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1254,6 +1254,22 @@ void Arguments::set_bytecode_flags() { // Aggressive optimization flags -XX:+AggressiveOpts void Arguments::set_aggressive_opts_flags() { +#ifdef COMPILER2 + if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) { + if (FLAG_IS_DEFAULT(EliminateAutoBox)) { + FLAG_SET_DEFAULT(EliminateAutoBox, true); + } + if (FLAG_IS_DEFAULT(AutoBoxCacheMax)) { + FLAG_SET_DEFAULT(AutoBoxCacheMax, 20000); + } + + // Feed the cache size setting into the JDK + char buffer[1024]; + sprintf(buffer, "java.lang.Integer.IntegerCache.high=%d", AutoBoxCacheMax); + add_property(buffer); + } +#endif + if (AggressiveOpts) { NOT_WINDOWS( // No measured benefit on Windows From 4abbae1fc2bcaf506b450d0acd0bcc4099c59763 Mon Sep 17 00:00:00 2001 From: Paul Hohensee Date: Wed, 5 Dec 2007 09:02:00 -0800 Subject: [PATCH 009/274] 6621621: HashMap front cache should be enabled only with AggressiveOpts Reviewed-by: sbohne, xlu --- hotspot/src/share/vm/classfile/vmSymbols.hpp | 4 +++- hotspot/src/share/vm/runtime/thread.cpp | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 9ba9b0c7c10..75e7f1860d6 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -96,10 +96,11 @@ template(java_util_Vector, "java/util/Vector") \ template(java_util_AbstractList, "java/util/AbstractList") \ template(java_util_Hashtable, "java/util/Hashtable") \ + template(java_util_HashMap, "java/util/HashMap") \ template(java_lang_Compiler, "java/lang/Compiler") \ template(sun_misc_Signal, "sun/misc/Signal") \ template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \ - template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \ + template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \ template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \ \ /* class file format tags */ \ @@ -281,6 +282,7 @@ template(park_event_name, "nativeParkEventPointer") \ template(cache_field_name, "cache") \ template(value_name, "value") \ + template(frontCacheEnabled_name, "frontCacheEnabled") \ \ /* non-intrinsic name/signature pairs: */ \ template(register_method_name, "register") \ diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 607772a0242..ee8daea5e5d 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -2925,6 +2925,25 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { warning("java.lang.String not initialized"); } + if (AggressiveOpts) { + // Forcibly initialize java/util/HashMap and mutate the private + // static final "frontCacheEnabled" field before we start creating instances +#ifdef ASSERT + klassOop tmp_k = SystemDictionary::find(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0); + assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet"); +#endif + klassOop k_o = SystemDictionary::resolve_or_null(vmSymbolHandles::java_util_HashMap(), Handle(), Handle(), CHECK_0); + KlassHandle k = KlassHandle(THREAD, k_o); + guarantee(k.not_null(), "Must find java/util/HashMap"); + instanceKlassHandle ik = instanceKlassHandle(THREAD, k()); + ik->initialize(CHECK_0); + fieldDescriptor fd; + // Possible we might not find this field; if so, don't break + if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) { + k()->bool_field_put(fd.offset(), true); + } + } + // Initialize java_lang.System (needed before creating the thread) if (InitializeJavaLangSystem) { initialize_class(vmSymbolHandles::java_lang_System(), CHECK_0); From b3b837074b789df6229626d953e7d78d48a9a4a4 Mon Sep 17 00:00:00 2001 From: Chuck Rasbold Date: Wed, 5 Dec 2007 09:03:00 -0800 Subject: [PATCH 010/274] 6614036: REGRESSION: Java server x86 VM intermittently crash with SIGSEGV (0xb) Restore destination address in x86 32-bit checkcast_arraycopy stub Reviewed-by: jrose, kvn, never --- hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 5ea4177f90b..9d17fce5ff3 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -1416,8 +1416,8 @@ class StubGenerator: public StubCodeGenerator { // ======== end loop ======== // It was a real error; we must depend on the caller to finish the job. - // Register rdx = -1 * number of *remaining* oops, r14 = *total* oops. - // Emit GC store barriers for the oops we have copied (r14 + rdx), + // Register "count" = -1 * number of *remaining* oops, length_arg = *total* oops. + // Emit GC store barriers for the oops we have copied (length_arg + count), // and report their number to the caller. __ addl(count, length_arg); // transfers = (length - remaining) __ movl(rax, count); // save the value @@ -1430,6 +1430,7 @@ class StubGenerator: public StubCodeGenerator { // Come here on success only. __ BIND(L_do_card_marks); __ movl(count, length_arg); + __ movl(to, to_arg); // reload gen_write_ref_array_post_barrier(to, count); __ xorl(rax, rax); // return 0 on success From 4576d7abf7f4441c37ed9f96497ee8b63c67b422 Mon Sep 17 00:00:00 2001 From: Paul Hohensee Date: Wed, 5 Dec 2007 09:04:00 -0800 Subject: [PATCH 011/274] 6629887: 64-bit windows should not restrict default heap size to 1400m Reviewed-by: jmasa, sbohne, ikrylov, xlu --- hotspot/src/os/linux/vm/os_linux.cpp | 14 ++++++++++++++ hotspot/src/os/windows/vm/os_windows.cpp | 5 +++++ hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 15 --------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index a327fd91592..6d793d895fb 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -116,6 +116,20 @@ julong os::physical_memory() { return Linux::physical_memory(); } +julong os::allocatable_physical_memory(julong size) { +#ifdef _LP64 + return size; +#else + julong result = MIN2(size, (julong)3800*M); + if (!is_allocatable(result)) { + // See comments under solaris for alignment considerations + julong reasonable_size = (julong)2*G - 2 * os::vm_page_size(); + result = MIN2(size, reasonable_size); + } + return result; +#endif // _LP64 +} + //////////////////////////////////////////////////////////////////////////////// // environment support diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 7f229338590..54e802a9d85 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -621,7 +621,12 @@ julong os::physical_memory() { } julong os::allocatable_physical_memory(julong size) { +#ifdef _LP64 + return size; +#else + // Limit to 1400m because of the 2gb address space wall return MIN2(size, (julong)1400*M); +#endif } // VC6 lacks DWORD_PTR diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index 972ee017c40..57631b5cde5 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -157,23 +157,8 @@ frame os::current_frame() { } } - // Utility functions -julong os::allocatable_physical_memory(julong size) { -#ifdef AMD64 - return size; -#else - julong result = MIN2(size, (julong)3800*M); - if (!is_allocatable(result)) { - // See comments under solaris for alignment considerations - julong reasonable_size = (julong)2*G - 2 * os::vm_page_size(); - result = MIN2(size, reasonable_size); - } - return result; -#endif // AMD64 -} - // From IA32 System Programming Guide enum { trap_page_fault = 0xE From 1bfa153ebe8db7bf90e2054e9d00d282036f9568 Mon Sep 17 00:00:00 2001 From: John Coomes Date: Thu, 6 Dec 2007 13:59:28 -0800 Subject: [PATCH 012/274] 6635560: segv in reference processor on t1000 Revert back to using the default page size for the card table Reviewed-by: pbk, phh --- hotspot/src/share/vm/memory/cardTableModRefBS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index db7ffffc74e..d06cd8bf7c2 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -51,7 +51,7 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, _whole_heap(whole_heap), _guard_index(cards_required(whole_heap.word_size()) - 1), _last_valid_index(_guard_index - 1), - _page_size(os::page_size_for_region(_guard_index + 1, _guard_index + 1, 1)), + _page_size(os::vm_page_size()), _byte_map_size(compute_byte_map_size()) { _kind = BarrierSet::CardTableModRef; From 218615259df442a1f5dd232383ca3701421c09e5 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 17 Jan 2008 13:38:17 -0800 Subject: [PATCH 013/274] 6646946: Kernel installation failed on Japanese and Chinese XP SP2 (VM part) Convert strings from Download Manager into native encoding in the VM Reviewed-by: sbohne, never, phh, kamg, xlu --- .../src/share/vm/classfile/javaClasses.cpp | 32 ++++++++++++++++++- .../src/share/vm/classfile/javaClasses.hpp | 1 + .../share/vm/classfile/systemDictionary.cpp | 4 ++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 115f45231e7..f2f3cb5869d 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -143,13 +143,43 @@ Handle java_lang_String::create_from_platform_dependent_str(const char* str, TRA jstring js = NULL; { JavaThread* thread = (JavaThread*)THREAD; assert(thread->is_Java_thread(), "must be java thread"); - ThreadToNativeFromVM ttn(thread); HandleMark hm(thread); + ThreadToNativeFromVM ttn(thread); js = (_to_java_string_fn)(thread->jni_environment(), str); } return Handle(THREAD, JNIHandles::resolve(js)); } +// Converts a Java String to a native C string that can be used for +// native OS calls. +char* java_lang_String::as_platform_dependent_str(Handle java_string, TRAPS) { + + typedef char* (*to_platform_string_fn_t)(JNIEnv*, jstring, bool*); + static to_platform_string_fn_t _to_platform_string_fn = NULL; + + if (_to_platform_string_fn == NULL) { + void *lib_handle = os::native_java_library(); + _to_platform_string_fn = CAST_TO_FN_PTR(to_platform_string_fn_t, hpi::dll_lookup(lib_handle, "GetStringPlatformChars")); + if (_to_platform_string_fn == NULL) { + fatal("GetStringPlatformChars missing"); + } + } + + char *native_platform_string; + { JavaThread* thread = (JavaThread*)THREAD; + assert(thread->is_Java_thread(), "must be java thread"); + JNIEnv *env = thread->jni_environment(); + jstring js = (jstring) JNIHandles::make_local(env, java_string()); + bool is_copy; + HandleMark hm(thread); + ThreadToNativeFromVM ttn(thread); + native_platform_string = (_to_platform_string_fn)(env, js, &is_copy); + assert(is_copy == JNI_TRUE, "is_copy value changed"); + JNIHandles::destroy_local(js); + } + return native_platform_string; +} + Handle java_lang_String::char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS) { oop obj = java_string(); // Typical usage is to convert all '/' to '.' in string. diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 45acae2bd98..8ac7cf883fd 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -96,6 +96,7 @@ class java_lang_String : AllStatic { // String converters static char* as_utf8_string(oop java_string); static char* as_utf8_string(oop java_string, int start, int len); + static char* as_platform_dependent_str(Handle java_string, TRAPS); static jchar* as_unicode_string(oop java_string, int& length); static bool equals(oop java_string, jchar* chars, int len); diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp index d71f63a6c12..a714ef583a6 100644 --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp @@ -1242,7 +1242,9 @@ static instanceKlassHandle download_and_retry_class_load( oop obj = (oop) result.get_jobject(); if (obj == NULL) { return nk; } - char* new_class_name = java_lang_String::as_utf8_string(obj); + Handle h_obj(THREAD, obj); + char* new_class_name = java_lang_String::as_platform_dependent_str(h_obj, + CHECK_(nk)); // lock the loader // we use this lock because JVMTI does. From f54eceace37cfe71701b1276cc5836245c73751b Mon Sep 17 00:00:00 2001 From: Keith McGuigan Date: Thu, 31 Jan 2008 09:41:34 -0500 Subject: [PATCH 014/274] 6631248: Memory problem when doing invalid type cast Changed memory allocation method for exception method Reviewed-by: ysr, never --- hotspot/src/share/vm/runtime/sharedRuntime.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index e9a5685889d..5d507d165fd 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1481,11 +1481,9 @@ char* SharedRuntime::generate_class_cast_message( const char* desc = " cannot be cast to "; size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1; - char* message = NEW_C_HEAP_ARRAY(char, msglen); + char* message = NEW_RESOURCE_ARRAY(char, msglen); if (NULL == message) { - // out of memory - can't use a detailed message. Since caller is - // using a resource mark to free memory, returning this should be - // safe (caller won't explicitly delete it). + // Shouldn't happen, but don't cause even more problems if it does message = const_cast(objName); } else { jio_snprintf(message, msglen, "%s%s%s", objName, desc, targetKlassName); From f7eb4517190504f13f900048fb0c5dfc9cc93902 Mon Sep 17 00:00:00 2001 From: Steve Bohne Date: Thu, 31 Jan 2008 14:56:50 -0500 Subject: [PATCH 015/274] 6598190: JPRT tests fail when run with -XX:+CheckUnhandledOops Work around Sun Studio C++ compiler bug 6629277 in dependencies.cpp Reviewed-by: kamg, sgoldman, pbk --- hotspot/src/share/vm/code/dependencies.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp index 75d0546642e..8d9d70d4207 100644 --- a/hotspot/src/share/vm/code/dependencies.cpp +++ b/hotspot/src/share/vm/code/dependencies.cpp @@ -1491,9 +1491,12 @@ bool DepChange::ContextStream::next() { // fall through: _change_type = Change_new_sub; case Change_new_sub: - _klass = instanceKlass::cast(_klass)->super(); - if (_klass != NULL) { - return true; + // 6598190: brackets workaround Sun Studio C++ compiler bug 6629277 + { + _klass = instanceKlass::cast(_klass)->super(); + if (_klass != NULL) { + return true; + } } // else set up _ti_limit and fall through: _ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length(); From f804a7e9f9ba6f5dac4fc2f10b464f98cd319874 Mon Sep 17 00:00:00 2001 From: Xiaobin Lu Date: Tue, 5 Feb 2008 23:21:57 -0800 Subject: [PATCH 016/274] 6610420: Debug VM crashes during monitor lock rank checking Make SerializePage lock as raw lock and add name for mutex locks Reviewed-by: never, dice, dholmes --- hotspot/src/share/vm/runtime/mutex.cpp | 13 ++++++++---- hotspot/src/share/vm/runtime/mutex.hpp | 8 ++++--- hotspot/src/share/vm/runtime/mutexLocker.cpp | 4 ---- hotspot/src/share/vm/runtime/mutexLocker.hpp | 1 - hotspot/src/share/vm/runtime/os.cpp | 22 +++++++++----------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp index a4d341b9637..c8751c2121c 100644 --- a/hotspot/src/share/vm/runtime/mutex.cpp +++ b/hotspot/src/share/vm/runtime/mutex.cpp @@ -1119,10 +1119,15 @@ Monitor::~Monitor() { assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ; } -void Monitor::ClearMonitor (Monitor * m) { +void Monitor::ClearMonitor (Monitor * m, const char *name) { m->_owner = NULL ; m->_snuck = false ; - m->_name = "UNKNOWN" ; + if (name == NULL) { + strcpy(m->_name, "UNKNOWN") ; + } else { + strncpy(m->_name, name, MONITOR_NAME_LEN - 1); + m->_name[MONITOR_NAME_LEN - 1] = '\0'; + } m->_LockWord.FullWord = 0 ; m->_EntryList = NULL ; m->_OnDeck = NULL ; @@ -1133,7 +1138,7 @@ void Monitor::ClearMonitor (Monitor * m) { Monitor::Monitor() { ClearMonitor(this); } Monitor::Monitor (int Rank, const char * name, bool allow_vm_block) { - ClearMonitor (this) ; + ClearMonitor (this, name) ; #ifdef ASSERT _allow_vm_block = allow_vm_block; _rank = Rank ; @@ -1145,7 +1150,7 @@ Mutex::~Mutex() { } Mutex::Mutex (int Rank, const char * name, bool allow_vm_block) { - ClearMonitor ((Monitor *) this) ; + ClearMonitor ((Monitor *) this, name) ; #ifdef ASSERT _allow_vm_block = allow_vm_block; _rank = Rank ; diff --git a/hotspot/src/share/vm/runtime/mutex.hpp b/hotspot/src/share/vm/runtime/mutex.hpp index 761cebb2ba4..56988e20e79 100644 --- a/hotspot/src/share/vm/runtime/mutex.hpp +++ b/hotspot/src/share/vm/runtime/mutex.hpp @@ -82,6 +82,9 @@ class ParkEvent ; // *in that order*. If their implementations change such that these // assumptions are violated, a whole lot of code will break. +// The default length of monitor name is choosen to be 64 to avoid false sharing. +static const int MONITOR_NAME_LEN = 64; + class Monitor : public CHeapObj { public: @@ -126,9 +129,8 @@ class Monitor : public CHeapObj { volatile intptr_t _WaitLock [1] ; // Protects _WaitSet ParkEvent * volatile _WaitSet ; // LL of ParkEvents volatile bool _snuck; // Used for sneaky locking (evil). - const char * _name; // Name of mutex int NotifyCount ; // diagnostic assist - double pad [8] ; // avoid false sharing + char _name[MONITOR_NAME_LEN]; // Name of mutex // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode) #ifndef PRODUCT @@ -170,7 +172,7 @@ class Monitor : public CHeapObj { int ILocked () ; protected: - static void ClearMonitor (Monitor * m) ; + static void ClearMonitor (Monitor * m, const char* name = NULL) ; Monitor() ; public: diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp index 317e24ee535..a639519d26d 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp @@ -188,10 +188,6 @@ void mutex_init() { def(Safepoint_lock , Monitor, safepoint, true ); // locks SnippetCache_lock/Threads_lock - if (!UseMembar) { - def(SerializePage_lock , Monitor, leaf, true ); - } - def(Threads_lock , Monitor, barrier, true ); def(VMOperationQueue_lock , Monitor, nonleaf, true ); // VM_thread allowed to block on these diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp index 59f145fcfb6..e21367cb960 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.hpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp @@ -52,7 +52,6 @@ extern Mutex* DerivedPointerTableGC_lock; // a lock to protect the derive extern Monitor* VMOperationQueue_lock; // a lock on queue of vm_operations waiting to execute extern Monitor* VMOperationRequest_lock; // a lock on Threads waiting for a vm_operation to terminate extern Monitor* Safepoint_lock; // a lock used by the safepoint abstraction -extern Monitor* SerializePage_lock; // a lock used when VMThread changing serialize memory page permission during safepoint extern Monitor* Threads_lock; // a lock on the Threads table of active Java threads // (also used by Safepoints too to block threads creation/destruction) extern Monitor* CGC_lock; // used for coordination between diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 72dfb2265ff..980c1179340 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -956,7 +956,6 @@ bool os::set_boot_path(char fileSep, char pathSep) { return true; } - void os::set_memory_serialize_page(address page) { int count = log2_intptr(sizeof(class JavaThread)) - log2_intptr(64); _mem_serialize_page = (volatile int32_t *)page; @@ -967,6 +966,8 @@ void os::set_memory_serialize_page(address page) { set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t))); } +static volatile intptr_t SerializePageLock = 0; + // This method is called from signal handler when SIGSEGV occurs while the current // thread tries to store to the "read-only" memory serialize page during state // transition. @@ -974,15 +975,14 @@ void os::block_on_serialize_page_trap() { if (TraceSafepoint) { tty->print_cr("Block until the serialize page permission restored"); } - // When VMThread is holding the SerializePage_lock during modifying the + // When VMThread is holding the SerializePageLock during modifying the // access permission of the memory serialize page, the following call // will block until the permission of that page is restored to rw. // Generally, it is unsafe to manipulate locks in signal handlers, but in // this case, it's OK as the signal is synchronous and we know precisely when - // it can occur. SerializePage_lock is a transiently-held leaf lock, so - // lock_without_safepoint_check should be safe. - SerializePage_lock->lock_without_safepoint_check(); - SerializePage_lock->unlock(); + // it can occur. + Thread::muxAcquire(&SerializePageLock, "set_memory_serialize_page"); + Thread::muxRelease(&SerializePageLock); } // Serialize all thread state variables @@ -990,14 +990,12 @@ void os::serialize_thread_states() { // On some platforms such as Solaris & Linux, the time duration of the page // permission restoration is observed to be much longer than expected due to // scheduler starvation problem etc. To avoid the long synchronization - // time and expensive page trap spinning, 'SerializePage_lock' is used to block - // the mutator thread if such case is encountered. Since this method is always - // called by VMThread during safepoint, lock_without_safepoint_check is used - // instead. See bug 6546278. - SerializePage_lock->lock_without_safepoint_check(); + // time and expensive page trap spinning, 'SerializePageLock' is used to block + // the mutator thread if such case is encountered. See bug 6546278 for details. + Thread::muxAcquire(&SerializePageLock, "serialize_thread_states"); os::protect_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() ); os::unguard_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() ); - SerializePage_lock->unlock(); + Thread::muxRelease(&SerializePageLock); } // Returns true if the current stack pointer is above the stack shadow From 527390207c78c2ab03991f03fd3a585775ee497f Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Mon, 11 Feb 2008 15:40:07 -0800 Subject: [PATCH 017/274] 6624782: Bigapps crashes during CMS precleaning Lowered optimization level for files instanceKlass.cpp and objArrayKlass.cpp Reviewed-by: ysr --- hotspot/build/solaris/makefiles/amd64.make | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hotspot/build/solaris/makefiles/amd64.make b/hotspot/build/solaris/makefiles/amd64.make index d4a09b7b778..9b229e83b79 100644 --- a/hotspot/build/solaris/makefiles/amd64.make +++ b/hotspot/build/solaris/makefiles/amd64.make @@ -19,7 +19,7 @@ # 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. -# +# # # Must also specify if CPU is little endian @@ -45,6 +45,10 @@ OPT_CFLAGS/os_solaris_x86_64.o = -xO1 OPT_CFLAGS/generateOptoStub.o = -xO2 OPT_CFLAGS/thread.o = -xO2 +# Work around for 6624782 +OPT_CFLAGS/instanceKlass.o = -Qoption ube -no_a2lf +OPT_CFLAGS/objArrayKlass.o = -Qoption ube -no_a2lf + else ifeq ("${Platform_compiler}", "gcc") @@ -58,6 +62,6 @@ else # error _JUNK2_ := $(shell echo >&2 \ "*** ERROR: this compiler is not yet supported by this code base!") - @exit 1 + @exit 1 endif endif From 41895dc06d21a7bc20eb4bb838400e30046a92df Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Tue, 12 Feb 2008 16:07:46 -0800 Subject: [PATCH 018/274] 6659981: +ParallelRefProcEnabled crashes on single core platform Disable parallel reference processing when there are no worker threads Reviewed-by: apetrusenko, pbk, jmasa, tonyp --- hotspot/src/share/vm/memory/referenceProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/memory/referenceProcessor.cpp b/hotspot/src/share/vm/memory/referenceProcessor.cpp index 24793bb4152..6aeeecd3e15 100644 --- a/hotspot/src/share/vm/memory/referenceProcessor.cpp +++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp @@ -85,7 +85,7 @@ ReferenceProcessor* ReferenceProcessor::create_ref_processor( ReferenceProcessor* rp = new ReferenceProcessor(span, atomic_discovery, mt_discovery, mt_degree, - mt_processing); + mt_processing && (parallel_gc_threads > 0)); if (rp == NULL) { vm_exit_during_initialization("Could not allocate ReferenceProcessor object"); } From 90815abd517a1e64cd0719d70222b384a37dfbdd Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 12 Feb 2008 18:37:50 -0800 Subject: [PATCH 019/274] 6621098: "* HeapWordSize" for TrackedInitializationLimit is missing '* HeapWordSize' is missing in GraphKit::set_output_for_allocation() Reviewed-by: rasbold, jrose, never --- hotspot/src/share/vm/opto/graphKit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 8df5f4272f4..642883ad64b 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -2808,7 +2808,7 @@ Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, ciInstanceKlass* ik = oop_type->klass()->as_instance_klass(); for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) { ciField* field = ik->nonstatic_field_at(i); - if (field->offset() >= TrackedInitializationLimit) + if (field->offset() >= TrackedInitializationLimit * HeapWordSize) continue; // do not bother to track really large numbers of fields // Find (or create) the alias category for this field: int fieldidx = C->alias_type(field)->index(); From 38fdc8ab98ef3f47aa5f80ff05d049694ceb3dc7 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Fri, 15 Feb 2008 07:01:10 -0800 Subject: [PATCH 020/274] 6624765: Guarantee failure "Unexpected dirty card found" In verification take into account partial coverage of a region by a card and expansion of the card table. Reviewed-by: ysr, apetrusenko --- .../parNew/parNewGeneration.cpp | 3 +++ .../src/share/vm/memory/cardTableModRefBS.cpp | 20 +++++++++---------- hotspot/src/share/vm/memory/cardTableRS.cpp | 8 +++++++- hotspot/src/share/vm/memory/cardTableRS.hpp | 2 +- hotspot/src/share/vm/memory/genRemSet.hpp | 11 ++++++++-- .../src/share/vm/memory/tenuredGeneration.cpp | 3 ++- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 603d6493fef..2bcd31138ff 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -785,6 +785,9 @@ void ParNewGeneration::collect(bool full, swap_spaces(); // Make life simpler for CMS || rescan; see 6483690. from()->set_next_compaction_space(to()); gch->set_incremental_collection_will_fail(); + + // Reset the PromotionFailureALot counters. + NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) } // set new iteration safe limit for the survivor spaces from()->set_concurrent_iteration_safe_limit(from()->top()); diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index db7ffffc74e..df330e6c0b9 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -196,8 +196,8 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) { assert(_whole_heap.contains(new_region), "attempt to cover area not in reserved area"); debug_only(verify_guard();) - int ind = find_covering_region_by_base(new_region.start()); - MemRegion old_region = _covered[ind]; + int const ind = find_covering_region_by_base(new_region.start()); + MemRegion const old_region = _covered[ind]; assert(old_region.start() == new_region.start(), "just checking"); if (new_region.word_size() != old_region.word_size()) { // Commit new or uncommit old pages, if necessary. @@ -205,21 +205,21 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) { // Extend the end of this _commited region // to cover the end of any lower _committed regions. // This forms overlapping regions, but never interior regions. - HeapWord* max_prev_end = largest_prev_committed_end(ind); + HeapWord* const max_prev_end = largest_prev_committed_end(ind); if (max_prev_end > cur_committed.end()) { cur_committed.set_end(max_prev_end); } // Align the end up to a page size (starts are already aligned). - jbyte* new_end = byte_after(new_region.last()); - HeapWord* new_end_aligned = - (HeapWord*)align_size_up((uintptr_t)new_end, _page_size); + jbyte* const new_end = byte_after(new_region.last()); + HeapWord* const new_end_aligned = + (HeapWord*) align_size_up((uintptr_t)new_end, _page_size); assert(new_end_aligned >= (HeapWord*) new_end, "align up, but less"); // The guard page is always committed and should not be committed over. - HeapWord* new_end_for_commit = MIN2(new_end_aligned, _guard_region.start()); + HeapWord* const new_end_for_commit = MIN2(new_end_aligned, _guard_region.start()); if (new_end_for_commit > cur_committed.end()) { // Must commit new pages. - MemRegion new_committed = + MemRegion const new_committed = MemRegion(cur_committed.end(), new_end_for_commit); assert(!new_committed.is_empty(), "Region should not be empty here"); @@ -233,7 +233,7 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) { // the cur_committed region may include the guard region. } else if (new_end_aligned < cur_committed.end()) { // Must uncommit pages. - MemRegion uncommit_region = + MemRegion const uncommit_region = committed_unique_to_self(ind, MemRegion(new_end_aligned, cur_committed.end())); if (!uncommit_region.is_empty()) { @@ -257,7 +257,7 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) { } assert(index_for(new_region.last()) < (int) _guard_index, "The guard card will be overwritten"); - jbyte* end = byte_after(new_region.last()); + jbyte* const end = (jbyte*) new_end_for_commit; // do nothing if we resized downward. if (entry < end) { memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte))); diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp index 6c762941be2..f389a70a40a 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.cpp +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp @@ -556,10 +556,16 @@ void CardTableRS::verify() { } -void CardTableRS::verify_empty(MemRegion mr) { +void CardTableRS::verify_aligned_region_empty(MemRegion mr) { if (!mr.is_empty()) { jbyte* cur_entry = byte_for(mr.start()); jbyte* limit = byte_after(mr.last()); + // The region mr may not start on a card boundary so + // the first card may reflect a write to the space + // just prior to mr. + if (!is_aligned(mr.start())) { + cur_entry++; + } for (;cur_entry < limit; cur_entry++) { guarantee(*cur_entry == CardTableModRefBS::clean_card, "Unexpected dirty card found"); diff --git a/hotspot/src/share/vm/memory/cardTableRS.hpp b/hotspot/src/share/vm/memory/cardTableRS.hpp index fa973aee45f..5d92067aa43 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.hpp +++ b/hotspot/src/share/vm/memory/cardTableRS.hpp @@ -126,7 +126,7 @@ public: } void verify(); - void verify_empty(MemRegion mr); + void verify_aligned_region_empty(MemRegion mr); void clear(MemRegion mr) { _ct_bs.clear(mr); } void clear_into_younger(Generation* gen, bool clear_perm); diff --git a/hotspot/src/share/vm/memory/genRemSet.hpp b/hotspot/src/share/vm/memory/genRemSet.hpp index 5de388cda52..006eab3ebb6 100644 --- a/hotspot/src/share/vm/memory/genRemSet.hpp +++ b/hotspot/src/share/vm/memory/genRemSet.hpp @@ -91,8 +91,15 @@ public: virtual void verify() = 0; // Verify that the remembered set has no entries for - // the heap interval denoted by mr. - virtual void verify_empty(MemRegion mr) = 0; + // the heap interval denoted by mr. If there are any + // alignment constraints on the remembered set, only the + // part of the region that is aligned is checked. + // + // alignment boundaries + // +--------+-------+--------+-------+ + // [ region mr ) + // [ part checked ) + virtual void verify_aligned_region_empty(MemRegion mr) = 0; // If appropriate, print some information about the remset on "tty". virtual void print() {} diff --git a/hotspot/src/share/vm/memory/tenuredGeneration.cpp b/hotspot/src/share/vm/memory/tenuredGeneration.cpp index 8c46169b7fe..8e04fd38814 100644 --- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp +++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp @@ -409,10 +409,11 @@ void TenuredGeneration::retire_alloc_buffers_before_full_gc() { void TenuredGeneration::verify_alloc_buffers_clean() { if (UseParNewGC) { for (uint i = 0; i < ParallelGCThreads; i++) { - _rs->verify_empty(_alloc_buffers[i]->range()); + _rs->verify_aligned_region_empty(_alloc_buffers[i]->range()); } } } + #else // SERIALGC void TenuredGeneration::retire_alloc_buffers_before_full_gc() {} void TenuredGeneration::verify_alloc_buffers_clean() {} From ae065e629037a6560e694d5332bc57286dddb75f Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Sat, 16 Feb 2008 22:41:20 -0800 Subject: [PATCH 021/274] 6621144: CMS: assertion failure "is_cms_thread == Thread::current()->is_ConcurrentGC_thread()" Take lock conditionally (in asynchronous mode only) when updating the dead-object map. Reviewed-by: jmasa --- .../concurrentMarkSweepGeneration.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index f8355d945e6..3fbed8f3cbe 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -5732,13 +5732,19 @@ void CMSCollector::sweep(bool asynch) { // in the perm_gen_verify_bit_map. In order to do that we traverse // all blocks in perm gen and mark all dead objects. if (verifying() && !cms_should_unload_classes()) { - CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(), - bitMapLock()); assert(perm_gen_verify_bit_map()->sizeInBits() != 0, "Should have already been allocated"); MarkDeadObjectsClosure mdo(this, _permGen->cmsSpace(), markBitMap(), perm_gen_verify_bit_map()); - _permGen->cmsSpace()->blk_iterate(&mdo); + if (asynch) { + CMSTokenSyncWithLocks ts(true, _permGen->freelistLock(), + bitMapLock()); + _permGen->cmsSpace()->blk_iterate(&mdo); + } else { + // In the case of synchronous sweep, we already have + // the requisite locks/tokens. + _permGen->cmsSpace()->blk_iterate(&mdo); + } } if (asynch) { From 9c36dab8c45513cb35868adef9df7b0ffc058a58 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Wed, 20 Feb 2008 08:40:31 -0800 Subject: [PATCH 022/274] 6665445: Backout change to CardTableModRefBS::resize_covered_region() Backed out part of cahnge for 6624765 because of nightly testing regressions. Reviewers below were for 6624765. Reviewed-by: ysr, apetrusenko --- hotspot/src/share/vm/memory/cardTableModRefBS.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index df330e6c0b9..6de1366952d 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -257,7 +257,7 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) { } assert(index_for(new_region.last()) < (int) _guard_index, "The guard card will be overwritten"); - jbyte* const end = (jbyte*) new_end_for_commit; + jbyte* const end = byte_after(new_region.last()); // do nothing if we resized downward. if (entry < end) { memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte))); From 5ade869e8cbf3ff04f55aa99824d8ae79f45915c Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 20 Feb 2008 16:19:43 -0800 Subject: [PATCH 023/274] 6614330: Node::dump(n) does not print full graph for specified depth A node is not processed in dump_nodes() if it was visited during processing previous inputs. Reviewed-by: rasbold --- hotspot/src/share/vm/opto/node.cpp | 77 ++++++++++++++++-------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index d7563d611ea..14e112e2101 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1486,70 +1486,75 @@ static void dump_nodes(const Node* start, int d, bool only_ctrl) { Node* s = (Node*)start; // remove const if (NotANode(s)) return; + uint depth = (uint)ABS(d); + int direction = d; Compile* C = Compile::current(); ResourceArea *area = Thread::current()->resource_area(); - Node_Stack stack(area, MIN2((uint)ABS(d), C->unique() >> 1)); - OldNewVectorSet visited(C->node_arena(), area); + Node_Stack stack(area, MIN2(depth, C->unique() >> 1)); + OldNewVectorSet dumped(C->node_arena(), area); OldNewVectorSet on_stack(C->node_arena(), area); - visited.set(s); on_stack.set(s); stack.push(s, 0); - if (d < 0) s->dump(); + if (direction < 0) { + dumped.set(s); + s->dump(); + } // Do a depth first walk over edges while (stack.is_nonempty()) { Node* tp = stack.node(); uint idx = stack.index(); - uint limit = d > 0 ? tp->len() : tp->outcnt(); + uint limit; + // Limit depth + if (stack.size() < depth) { + limit = direction > 0 ? tp->len() : tp->outcnt(); + } else { + limit = 0; // reached depth limit. + } if (idx >= limit) { // no more arcs to visit - if (d > 0) tp->dump(); + if (direction > 0 && !dumped.test_set(tp)) tp->dump(); on_stack.del(tp); stack.pop(); } else { // process the "idx"th arc stack.set_index(idx + 1); - Node* n = d > 0 ? tp->in(idx) : tp->raw_out(idx); + Node* n = direction > 0 ? tp->in(idx) : tp->raw_out(idx); if (NotANode(n)) continue; // do not recurse through top or the root (would reach unrelated stuff) if (n->is_Root() || n->is_top()) continue; if (only_ctrl && !n->is_CFG()) continue; - if (!visited.test_set(n)) { // forward arc - // Limit depth - if (stack.size() < (uint)ABS(d)) { - if (d < 0) n->dump(); - stack.push(n, 0); - on_stack.set(n); - } + if (!on_stack.test(n)) { // forward arc + if (direction < 0 && !dumped.test_set(n)) n->dump(); + stack.push(n, 0); + on_stack.set(n); } else { // back or cross arc - if (on_stack.test(n)) { // back arc - // print loop if there are no phis or regions in the mix - bool found_loop_breaker = false; - int k; - for (k = stack.size() - 1; k >= 0; k--) { - Node* m = stack.node_at(k); - if (m->is_Phi() || m->is_Region() || m->is_Root() || m->is_Start()) { - found_loop_breaker = true; - break; - } - if (m == n) // Found loop head - break; + // print loop if there are no phis or regions in the mix + bool found_loop_breaker = false; + int k; + for (k = stack.size() - 1; k >= 0; k--) { + Node* m = stack.node_at(k); + if (m->is_Phi() || m->is_Region() || m->is_Root() || m->is_Start()) { + found_loop_breaker = true; + break; } - assert(k >= 0, "n must be on stack"); + if (m == n) // Found loop head + break; + } + assert(k >= 0, "n must be on stack"); - if (!found_loop_breaker) { - tty->print("# %s LOOP FOUND:", only_ctrl ? "CONTROL" : "DATA"); - for (int i = stack.size() - 1; i >= k; i--) { - Node* m = stack.node_at(i); - bool mnew = C->node_arena()->contains(m); - tty->print(" %s%d:%s", (mnew? "": "o"), m->_idx, m->Name()); - if (i != 0) tty->print(d > 0? " <-": " ->"); - } - tty->cr(); + if (!found_loop_breaker) { + tty->print("# %s LOOP FOUND:", only_ctrl ? "CONTROL" : "DATA"); + for (int i = stack.size() - 1; i >= k; i--) { + Node* m = stack.node_at(i); + bool mnew = C->node_arena()->contains(m); + tty->print(" %s%d:%s", (mnew? "": "o"), m->_idx, m->Name()); + if (i != 0) tty->print(direction > 0? " <-": " ->"); } + tty->cr(); } } } From 26097e9848a3655dc2b4e7664639e4e56f1c135c Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 20 Feb 2008 17:23:43 -0800 Subject: [PATCH 024/274] 6621094: PrintOptoAssembly is broken for oops information in DebugInfo OopMapValue and VMRegImpl classes miss the virtual method print_on(st). Reviewed-by: rasbold, jrose, never --- hotspot/src/share/vm/code/vmreg.cpp | 10 ++++----- hotspot/src/share/vm/code/vmreg.hpp | 9 ++++---- hotspot/src/share/vm/compiler/oopMap.cpp | 28 ++++++++++++------------ hotspot/src/share/vm/compiler/oopMap.hpp | 3 ++- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/hotspot/src/share/vm/code/vmreg.cpp b/hotspot/src/share/vm/code/vmreg.cpp index 32e70f8cda4..22be4b2f390 100644 --- a/hotspot/src/share/vm/code/vmreg.cpp +++ b/hotspot/src/share/vm/code/vmreg.cpp @@ -36,16 +36,16 @@ const int VMRegImpl::register_count = ConcreteRegisterImpl::number_of_registers; // Register names const char *VMRegImpl::regName[ConcreteRegisterImpl::number_of_registers]; -void VMRegImpl::print() { #ifndef PRODUCT +void VMRegImpl::print_on(outputStream* st) const { if( is_reg() ) { assert( VMRegImpl::regName[value()], "" ); - tty->print("%s",VMRegImpl::regName[value()]); + st->print("%s",VMRegImpl::regName[value()]); } else if (is_stack()) { int stk = value() - stack0->value(); - tty->print("[%d]", stk*4); + st->print("[%d]", stk*4); } else { - tty->print("BAD!"); + st->print("BAD!"); } -#endif // PRODUCT } +#endif // PRODUCT diff --git a/hotspot/src/share/vm/code/vmreg.hpp b/hotspot/src/share/vm/code/vmreg.hpp index 66b3540789f..ab77b265fe3 100644 --- a/hotspot/src/share/vm/code/vmreg.hpp +++ b/hotspot/src/share/vm/code/vmreg.hpp @@ -66,9 +66,9 @@ public: } } static VMReg Bad() { return (VMReg) (intptr_t) BAD; } - bool is_valid() { return ((intptr_t) this) != BAD; } - bool is_stack() { return (intptr_t) this >= (intptr_t) stack0; } - bool is_reg() { return is_valid() && !is_stack(); } + bool is_valid() const { return ((intptr_t) this) != BAD; } + bool is_stack() const { return (intptr_t) this >= (intptr_t) stack0; } + bool is_reg() const { return is_valid() && !is_stack(); } // A concrete register is a value that returns true for is_reg() and is // also a register you could use in the assembler. On machines with @@ -96,7 +96,8 @@ public: intptr_t value() const {return (intptr_t) this; } - void print(); + void print_on(outputStream* st) const PRODUCT_RETURN; + void print() const { print_on(tty); } // bias a stack slot. // Typically used to adjust a virtual frame slots by amounts that are offset by diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp index bd6dc80132e..b4a85f787f8 100644 --- a/hotspot/src/share/vm/compiler/oopMap.cpp +++ b/hotspot/src/share/vm/compiler/oopMap.cpp @@ -506,27 +506,27 @@ bool OopMap::has_derived_pointer() const { } -void print_register_type(OopMapValue::oop_types x, VMReg optional) { +static void print_register_type(OopMapValue::oop_types x, VMReg optional, outputStream* st) { switch( x ) { case OopMapValue::oop_value: - tty->print("Oop"); + st->print("Oop"); break; case OopMapValue::value_value: - tty->print("Value" ); + st->print("Value" ); break; case OopMapValue::dead_value: - tty->print("Dead" ); + st->print("Dead" ); break; case OopMapValue::callee_saved_value: - tty->print("Callers_" ); - optional->print(); + st->print("Callers_" ); + optional->print_on(st); break; case OopMapValue::derived_oop_value: - tty->print("Derived_oop_" ); - optional->print(); + st->print("Derived_oop_" ); + optional->print_on(st); break; case OopMapValue::stack_obj: - tty->print("Stack"); + st->print("Stack"); break; default: ShouldNotReachHere(); @@ -534,11 +534,11 @@ void print_register_type(OopMapValue::oop_types x, VMReg optional) { } -void OopMapValue::print() const { - reg()->print(); - tty->print("="); - print_register_type(type(),content_reg()); - tty->print(" "); +void OopMapValue::print_on(outputStream* st) const { + reg()->print_on(st); + st->print("="); + print_register_type(type(),content_reg(),st); + st->print(" "); } diff --git a/hotspot/src/share/vm/compiler/oopMap.hpp b/hotspot/src/share/vm/compiler/oopMap.hpp index dec8afe5789..8b678368247 100644 --- a/hotspot/src/share/vm/compiler/oopMap.hpp +++ b/hotspot/src/share/vm/compiler/oopMap.hpp @@ -129,7 +129,8 @@ public: return reg()->reg2stack(); } - void print( ) const PRODUCT_RETURN; + void print_on(outputStream* st) const PRODUCT_RETURN; + void print() const { print_on(tty); } }; From 74f243990ce624512f791cddc8b32abf3f021944 Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Thu, 21 Feb 2008 11:03:54 -0800 Subject: [PATCH 025/274] 6642634: Test nsk/regression/b6186200 crashed with SIGSEGV Use correct allocation path in expand_and_allocate() so object's mark and p-bits are set as appropriate. Reviewed-by: jmasa, pbk --- .../concurrentMarkSweep/concurrentMarkSweepGeneration.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 3fbed8f3cbe..eff7a042e95 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -3121,12 +3121,7 @@ ConcurrentMarkSweepGeneration::expand_and_allocate(size_t word_size, if (GCExpandToAllocateDelayMillis > 0) { os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false); } - size_t adj_word_sz = CompactibleFreeListSpace::adjustObjectSize(word_size); - if (parallel) { - return cmsSpace()->par_allocate(adj_word_sz); - } else { - return cmsSpace()->allocate(adj_word_sz); - } + return have_lock_and_allocate(word_size, tlab); } // YSR: All of this generation expansion/shrinking stuff is an exact copy of From b8789d9c9af593b423495c9be35b857aca38984b Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 21 Feb 2008 14:03:41 -0800 Subject: [PATCH 026/274] 6621084: ciMethodBlocks::split_block_at() is broken for methods with exception handler After an exception handler block is split the exception information is not moved to the new block which starts in exception handler BCI. Reviewed-by: jrose --- hotspot/src/share/vm/ci/ciMethodBlocks.cpp | 39 ++++++++++++++++++++-- hotspot/src/share/vm/ci/ciMethodBlocks.hpp | 3 +- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp index d2b93186d9d..4c596bbc4fb 100644 --- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp +++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp @@ -67,6 +67,14 @@ ciBlock *ciMethodBlocks::split_block_at(int bci) { break; } } + // Move an exception handler information if needed. + if (former_block->is_handler()) { + int ex_start = former_block->ex_start_bci(); + int ex_end = former_block->ex_limit_bci(); + new_block->set_exception_range(ex_start, ex_end); + // Clear information in former_block. + former_block->clear_exception_handler(); + } return former_block; } @@ -102,7 +110,7 @@ void ciMethodBlocks::do_analysis() { // one and end the old one. assert(cur_block != NULL, "must always have a current block"); ciBlock *new_block = block_containing(bci); - if (new_block == NULL) { + if (new_block == NULL || new_block == cur_block) { // We have not marked this bci as the start of a new block. // Keep interpreting the current_range. _bci_to_block[bci] = cur_block; @@ -254,9 +262,33 @@ ciMethodBlocks::ciMethodBlocks(Arena *arena, ciMethod *meth): _method(meth), for(ciExceptionHandlerStream str(meth); !str.is_done(); str.next()) { ciExceptionHandler* handler = str.handler(); ciBlock *eb = make_block_at(handler->handler_bci()); - eb->set_handler(); + // + // Several exception handlers can have the same handler_bci: + // + // try { + // if (a.foo(b) < 0) { + // return a.error(); + // } + // return CoderResult.UNDERFLOW; + // } finally { + // a.position(b); + // } + // + // The try block above is divided into 2 exception blocks + // separated by 'areturn' bci. + // int ex_start = handler->start(); int ex_end = handler->limit(); + if (eb->is_handler()) { + // Extend old handler exception range to cover additional range. + int old_ex_start = eb->ex_start_bci(); + int old_ex_end = eb->ex_limit_bci(); + if (ex_start > old_ex_start) + ex_start = old_ex_start; + if (ex_end < old_ex_end) + ex_end = old_ex_end; + eb->clear_exception_handler(); // Reset exception information + } eb->set_exception_range(ex_start, ex_end); // ensure a block at the start of exception range and start of following code (void) make_block_at(ex_start); @@ -312,9 +344,10 @@ ciBlock::ciBlock(ciMethod *method, int index, ciMethodBlocks *mb, int start_bci) void ciBlock::set_exception_range(int start_bci, int limit_bci) { assert(limit_bci >= start_bci, "valid range"); - assert(is_handler(), "must be handler"); + assert(!is_handler() && _ex_start_bci == -1 && _ex_limit_bci == -1, "must not be handler"); _ex_start_bci = start_bci; _ex_limit_bci = limit_bci; + set_handler(); } #ifndef PRODUCT diff --git a/hotspot/src/share/vm/ci/ciMethodBlocks.hpp b/hotspot/src/share/vm/ci/ciMethodBlocks.hpp index a0db4bb6dcd..b4398f39f4a 100644 --- a/hotspot/src/share/vm/ci/ciMethodBlocks.hpp +++ b/hotspot/src/share/vm/ci/ciMethodBlocks.hpp @@ -110,9 +110,10 @@ public: void set_does_jsr() { _flags |= DoesJsr; } void clear_does_jsr() { _flags &= ~DoesJsr; } void set_does_ret() { _flags |= DoesRet; } - void clear_does_ret() { _flags |= DoesRet; } + void clear_does_ret() { _flags &= ~DoesRet; } void set_is_ret_target() { _flags |= RetTarget; } void set_has_handler() { _flags |= HasHandler; } + void clear_exception_handler() { _flags &= ~Handler; _ex_start_bci = -1; _ex_limit_bci = -1; } #ifndef PRODUCT ciMethod *method() const { return _method; } void dump(); From e06dedd2f1d176b64b44ec363ee00b5d9dbc821a Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 21 Feb 2008 19:03:44 -0800 Subject: [PATCH 027/274] 6498878: client compiler crashes on windows when dealing with breakpoint instructions _is_compilable check prevents breakpoint bytecodes reversion when loading bytecodes for ciMethod. Reviewed-by: never --- hotspot/src/share/vm/ci/ciMethod.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index f527b1fd6e6..2c6c5aa272d 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -146,7 +146,7 @@ void ciMethod::load_code() { memcpy(_code, me->code_base(), code_size()); // Revert any breakpoint bytecodes in ci's copy - if (_is_compilable && me->number_of_breakpoints() > 0) { + if (me->number_of_breakpoints() > 0) { BreakpointInfo* bp = instanceKlass::cast(me->method_holder())->breakpoints(); for (; bp != NULL; bp = bp->next()) { if (bp->match(me)) { From 63f1de52fc66114c4fbda6a2b4632b94b336be55 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Fri, 22 Feb 2008 17:17:14 -0800 Subject: [PATCH 028/274] 6362677: Change parallel GC collector default number of parallel GC threads Use the same default number of GC threads as used by ParNewGC and ConcMarkSweepGC (i.e., the 5/8th rule). Reviewed-by: ysr, tonyp --- hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp | 16 ++ hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp | 8 + .../parallelScavenge/generationSizer.hpp | 8 +- hotspot/src/share/vm/runtime/arguments.cpp | 159 +++++++++--------- hotspot/src/share/vm/runtime/arguments.hpp | 4 +- hotspot/src/share/vm/runtime/globals.hpp | 3 + hotspot/src/share/vm/runtime/vm_version.cpp | 42 +++++ hotspot/src/share/vm/runtime/vm_version.hpp | 15 ++ 8 files changed, 174 insertions(+), 81 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp index 3d43a1b51a2..755df962f5d 100644 --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp @@ -28,6 +28,12 @@ int VM_Version::_features = VM_Version::unknown_m; const char* VM_Version::_features_str = ""; +bool VM_Version::is_niagara1_plus() { + // This is a placeholder until the real test is determined. + return is_niagara1() && + (os::processor_count() > maximum_niagara1_processor_count()); +} + void VM_Version::initialize() { _features = determine_features(); PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes(); @@ -160,3 +166,13 @@ void VM_Version::allow_all() { void VM_Version::revert() { _features = saved_features; } + +unsigned int VM_Version::calc_parallel_worker_threads() { + unsigned int result; + if (is_niagara1_plus()) { + result = nof_parallel_worker_threads(5, 16, 8); + } else { + result = nof_parallel_worker_threads(5, 8, 8); + } + return result; +} diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp index 8eda5c3108d..d10845d0659 100644 --- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp @@ -64,6 +64,11 @@ protected: static bool is_niagara1(int features) { return (features & niagara1_m) == niagara1_m; } + static int maximum_niagara1_processor_count() { return 32; } + // Returns true if the platform is in the niagara line and + // newer than the niagara1. + static bool is_niagara1_plus(); + public: // Initialization static void initialize(); @@ -129,4 +134,7 @@ public: // Override the Abstract_VM_Version implementation. static uint page_size_count() { return is_sun4v() ? 4 : 2; } + + // Calculates the number of parallel threads + static unsigned int calc_parallel_worker_threads(); }; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp index 9ca614c4823..4f284a5d572 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp @@ -39,10 +39,10 @@ class GenerationSizer : public TwoGenerationCollectorPolicy { // If the user hasn't explicitly set the number of worker // threads, set the count. - if (ParallelGCThreads == 0) { - assert(UseParallelGC, "Setting ParallelGCThreads without UseParallelGC"); - ParallelGCThreads = os::active_processor_count(); - } + assert(UseSerialGC || + !FLAG_IS_DEFAULT(ParallelGCThreads) || + (ParallelGCThreads > 0), + "ParallelGCThreads should be set before flag initialization"); // The survivor ratio's are calculated "raw", unlike the // default gc, which adds 2 to the ratio value. We need to diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 5d0329ad046..0e631006212 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -924,10 +924,18 @@ static void no_shared_spaces() { void Arguments::set_parnew_gc_flags() { assert(!UseSerialGC && !UseParallelGC, "control point invariant"); + // Turn off AdaptiveSizePolicy by default for parnew until it is + // complete. + if (UseParNewGC && + FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) { + FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false); + } + if (FLAG_IS_DEFAULT(UseParNewGC) && ParallelGCThreads > 1) { FLAG_SET_DEFAULT(UseParNewGC, true); } else if (UseParNewGC && ParallelGCThreads == 0) { - FLAG_SET_DEFAULT(ParallelGCThreads, nof_parallel_gc_threads()); + FLAG_SET_DEFAULT(ParallelGCThreads, + Abstract_VM_Version::parallel_worker_threads()); if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) { FLAG_SET_DEFAULT(UseParNewGC, false); } @@ -956,25 +964,6 @@ void Arguments::set_parnew_gc_flags() { } } -// CAUTION: this code is currently shared by UseParallelGC, UseParNewGC and -// UseconcMarkSweepGC. Further tuning of individual collectors might -// dictate refinement on a per-collector basis. -int Arguments::nof_parallel_gc_threads() { - if (FLAG_IS_DEFAULT(ParallelGCThreads)) { - // For very large machines, there are diminishing returns - // for large numbers of worker threads. Instead of - // hogging the whole system, use 5/8ths of a worker for every - // processor after the first 8. For example, on a 72 cpu - // machine use 8 + (72 - 8) * (5/8) == 48 worker threads. - // This is just a start and needs further tuning and study in - // Tiger. - int ncpus = os::active_processor_count(); - return (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8); - } else { - return ParallelGCThreads; - } -} - // Adjust some sizes to suit CMS and/or ParNew needs; these work well on // sparc/solaris for certain applications, but would gain from // further optimization and tuning efforts, and would almost @@ -984,26 +973,24 @@ void Arguments::set_cms_and_parnew_gc_flags() { return; } + assert(UseConcMarkSweepGC, "CMS is expected to be on here"); + // If we are using CMS, we prefer to UseParNewGC, // unless explicitly forbidden. - if (UseConcMarkSweepGC && !UseParNewGC && FLAG_IS_DEFAULT(UseParNewGC)) { - FLAG_SET_DEFAULT(UseParNewGC, true); + if (!UseParNewGC && FLAG_IS_DEFAULT(UseParNewGC)) { + FLAG_SET_ERGO(bool, UseParNewGC, true); } // Turn off AdaptiveSizePolicy by default for cms until it is - // complete. Also turn it off in general if the - // parnew collector has been selected. - if ((UseConcMarkSweepGC || UseParNewGC) && - FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) { + // complete. + if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) { FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false); } // In either case, adjust ParallelGCThreads and/or UseParNewGC // as needed. - set_parnew_gc_flags(); - - if (!UseConcMarkSweepGC) { - return; + if (UseParNewGC) { + set_parnew_gc_flags(); } // Now make adjustments for CMS @@ -1147,17 +1134,11 @@ void Arguments::set_ergonomics_flags() { FLAG_IS_DEFAULT(UseParallelGC)) { if (should_auto_select_low_pause_collector()) { FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true); - set_cms_and_parnew_gc_flags(); } else { FLAG_SET_ERGO(bool, UseParallelGC, true); } no_shared_spaces(); } - - // This is here because the parallel collector could - // have been selected so this initialization should - // still be done. - set_parallel_gc_flags(); } } @@ -1170,6 +1151,9 @@ void Arguments::set_parallel_gc_flags() { // If no heap maximum was requested explicitly, use some reasonable fraction // of the physical memory, up to a maximum of 1GB. if (UseParallelGC) { + FLAG_SET_ERGO(uintx, ParallelGCThreads, + Abstract_VM_Version::parallel_worker_threads()); + if (FLAG_IS_DEFAULT(MaxHeapSize)) { const uint64_t reasonable_fraction = os::physical_memory() / DefaultMaxRAMFraction; @@ -1312,6 +1296,31 @@ static bool verify_serial_gc_flags() { UseParallelOldGC)); } +// Check consistency of GC selection +bool Arguments::check_gc_consistency() { + bool status = true; + // Ensure that the user has not selected conflicting sets + // of collectors. [Note: this check is merely a user convenience; + // collectors over-ride each other so that only a non-conflicting + // set is selected; however what the user gets is not what they + // may have expected from the combination they asked for. It's + // better to reduce user confusion by not allowing them to + // select conflicting combinations. + uint i = 0; + if (UseSerialGC) i++; + if (UseConcMarkSweepGC || UseParNewGC) i++; + if (UseParallelGC || UseParallelOldGC) i++; + if (i > 1) { + jio_fprintf(defaultStream::error_stream(), + "Conflicting collector combinations in option list; " + "please refer to the release notes for the combinations " + "allowed\n"); + status = false; + } + + return status; +} + // Check the consistency of vm_init_args bool Arguments::check_vm_args_consistency() { // Method for adding checks for flag consistency. @@ -1354,14 +1363,14 @@ bool Arguments::check_vm_args_consistency() { status = false; } - status &= verify_percentage(MaxLiveObjectEvacuationRatio, + status = status && verify_percentage(MaxLiveObjectEvacuationRatio, "MaxLiveObjectEvacuationRatio"); - status &= verify_percentage(AdaptiveSizePolicyWeight, + status = status && verify_percentage(AdaptiveSizePolicyWeight, "AdaptiveSizePolicyWeight"); - status &= verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight"); - status &= verify_percentage(ThresholdTolerance, "ThresholdTolerance"); - status &= verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio"); - status &= verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio"); + status = status && verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight"); + status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance"); + status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio"); + status = status && verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio"); if (MinHeapFreeRatio > MaxHeapFreeRatio) { jio_fprintf(defaultStream::error_stream(), @@ -1377,14 +1386,14 @@ bool Arguments::check_vm_args_consistency() { MarkSweepAlwaysCompactCount = 1; // Move objects every gc. } - status &= verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); - status &= verify_percentage(GCTimeLimit, "GCTimeLimit"); + status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); + status = status && verify_percentage(GCTimeLimit, "GCTimeLimit"); if (GCTimeLimit == 100) { // Turn off gc-overhead-limit-exceeded checks FLAG_SET_DEFAULT(UseGCOverheadLimit, false); } - status &= verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); + status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); // Check user specified sharing option conflict with Parallel GC bool cannot_share = (UseConcMarkSweepGC || UseParallelGC || @@ -1402,24 +1411,7 @@ bool Arguments::check_vm_args_consistency() { } } - // Ensure that the user has not selected conflicting sets - // of collectors. [Note: this check is merely a user convenience; - // collectors over-ride each other so that only a non-conflicting - // set is selected; however what the user gets is not what they - // may have expected from the combination they asked for. It's - // better to reduce user confusion by not allowing them to - // select conflicting combinations. - uint i = 0; - if (UseSerialGC) i++; - if (UseConcMarkSweepGC || UseParNewGC) i++; - if (UseParallelGC || UseParallelOldGC) i++; - if (i > 1) { - jio_fprintf(defaultStream::error_stream(), - "Conflicting collector combinations in option list; " - "please refer to the release notes for the combinations " - "allowed\n"); - status = false; - } + status = status && check_gc_consistency(); if (_has_alloc_profile) { if (UseParallelGC || UseParallelOldGC) { @@ -1451,15 +1443,15 @@ bool Arguments::check_vm_args_consistency() { "allocation buffers\n(-XX:+UseTLAB).\n"); status = false; } else { - status &= verify_percentage(CMSIncrementalDutyCycle, + status = status && verify_percentage(CMSIncrementalDutyCycle, "CMSIncrementalDutyCycle"); - status &= verify_percentage(CMSIncrementalDutyCycleMin, + status = status && verify_percentage(CMSIncrementalDutyCycleMin, "CMSIncrementalDutyCycleMin"); - status &= verify_percentage(CMSIncrementalSafetyFactor, + status = status && verify_percentage(CMSIncrementalSafetyFactor, "CMSIncrementalSafetyFactor"); - status &= verify_percentage(CMSIncrementalOffset, + status = status && verify_percentage(CMSIncrementalOffset, "CMSIncrementalOffset"); - status &= verify_percentage(CMSExpAvgFactor, + status = status && verify_percentage(CMSExpAvgFactor, "CMSExpAvgFactor"); // If it was not set on the command line, set // CMSInitiatingOccupancyFraction to 1 so icms can initiate cycles early. @@ -2064,7 +2056,8 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, // Enable parallel GC and adaptive generation sizing FLAG_SET_CMDLINE(bool, UseParallelGC, true); - FLAG_SET_DEFAULT(ParallelGCThreads, nof_parallel_gc_threads()); + FLAG_SET_DEFAULT(ParallelGCThreads, + Abstract_VM_Version::parallel_worker_threads()); // Encourage steady state memory management FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100); @@ -2451,15 +2444,25 @@ jint Arguments::parse(const JavaVMInitArgs* args) { no_shared_spaces(); #endif // KERNEL - // Set some flags for ParallelGC if needed. - set_parallel_gc_flags(); - - // Set some flags for CMS and/or ParNew collectors, as needed. - set_cms_and_parnew_gc_flags(); - // Set flags based on ergonomics. set_ergonomics_flags(); + // Check the GC selections again. + if (!check_gc_consistency()) { + return JNI_EINVAL; + } + + if (UseParallelGC) { + // Set some flags for ParallelGC if needed. + set_parallel_gc_flags(); + } else if (UseConcMarkSweepGC) { + // Set some flags for CMS + set_cms_and_parnew_gc_flags(); + } else if (UseParNewGC) { + // Set some flags for ParNew + set_parnew_gc_flags(); + } + #ifdef SERIALGC assert(verify_serial_gc_flags(), "SerialGC unset"); #endif // SERIALGC @@ -2479,6 +2482,12 @@ jint Arguments::parse(const JavaVMInitArgs* args) { CommandLineFlags::printSetFlags(); } +#ifdef ASSERT + if (PrintFlagsFinal) { + CommandLineFlags::printFlags(); + } +#endif + return JNI_OK; } diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index fc373c41dd0..b806f4800f8 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -291,8 +291,6 @@ class Arguments : AllStatic { static bool _CIDynamicCompilePriority; static intx _Tier2CompileThreshold; - // GC processing - static int nof_parallel_gc_threads(); // CMS/ParNew garbage collectors static void set_parnew_gc_flags(); static void set_cms_and_parnew_gc_flags(); @@ -385,6 +383,8 @@ class Arguments : AllStatic { public: // Parses the arguments static jint parse(const JavaVMInitArgs* args); + // Check for consistency in the selection of the garbage collector. + static bool check_gc_consistency(); // Check consistecy or otherwise of VM argument settings static bool check_vm_args_consistency(); // Used by os_solaris diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index c1e8fefeba9..80f9541bc39 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -1794,6 +1794,9 @@ class CommandLineFlags { "number of times a GC thread (minus the coordinator) " \ "will sleep while yielding before giving up and resuming GC") \ \ + notproduct(bool, PrintFlagsFinal, false, \ + "Print all command line flags after argument processing") \ + \ /* gc tracing */ \ manageable(bool, PrintGC, false, \ "Print message at garbage collect") \ diff --git a/hotspot/src/share/vm/runtime/vm_version.cpp b/hotspot/src/share/vm/runtime/vm_version.cpp index f5ee15ade86..9c335eb44b3 100644 --- a/hotspot/src/share/vm/runtime/vm_version.cpp +++ b/hotspot/src/share/vm/runtime/vm_version.cpp @@ -52,6 +52,8 @@ int Abstract_VM_Version::_vm_major_version = 0; int Abstract_VM_Version::_vm_minor_version = 0; int Abstract_VM_Version::_vm_build_number = 0; bool Abstract_VM_Version::_initialized = false; +int Abstract_VM_Version::_parallel_worker_threads = 0; +bool Abstract_VM_Version::_parallel_worker_threads_initialized = false; void Abstract_VM_Version::initialize() { if (_initialized) { @@ -210,3 +212,43 @@ void VM_Version_init() { } #endif } + +unsigned int Abstract_VM_Version::nof_parallel_worker_threads( + unsigned int num, + unsigned int den, + unsigned int switch_pt) { + if (FLAG_IS_DEFAULT(ParallelGCThreads)) { + assert(ParallelGCThreads == 0, "Default ParallelGCThreads is not 0"); + // For very large machines, there are diminishing returns + // for large numbers of worker threads. Instead of + // hogging the whole system, use a fraction of the workers for every + // processor after the first 8. For example, on a 72 cpu machine + // and a chosen fraction of 5/8 + // use 8 + (72 - 8) * (5/8) == 48 worker threads. + unsigned int ncpus = (unsigned int) os::active_processor_count(); + return (ncpus <= switch_pt) ? + ncpus : + (switch_pt + ((ncpus - switch_pt) * num) / den); + } else { + return ParallelGCThreads; + } +} + +unsigned int Abstract_VM_Version::calc_parallel_worker_threads() { + return nof_parallel_worker_threads(5, 8, 8); +} + + +// Does not set the _initialized flag since it is +// a global flag. +unsigned int Abstract_VM_Version::parallel_worker_threads() { + if (!_parallel_worker_threads_initialized) { + if (FLAG_IS_DEFAULT(ParallelGCThreads)) { + _parallel_worker_threads = VM_Version::calc_parallel_worker_threads(); + } else { + _parallel_worker_threads = ParallelGCThreads; + } + _parallel_worker_threads_initialized = true; + } + return _parallel_worker_threads; +} diff --git a/hotspot/src/share/vm/runtime/vm_version.hpp b/hotspot/src/share/vm/runtime/vm_version.hpp index 2f708e39db8..5a46f04fb1d 100644 --- a/hotspot/src/share/vm/runtime/vm_version.hpp +++ b/hotspot/src/share/vm/runtime/vm_version.hpp @@ -36,6 +36,12 @@ class Abstract_VM_Version: AllStatic { static int _vm_minor_version; static int _vm_build_number; static bool _initialized; + static int _parallel_worker_threads; + static bool _parallel_worker_threads_initialized; + + static unsigned int nof_parallel_worker_threads(unsigned int num, + unsigned int dem, + unsigned int switch_pt); public: static void initialize(); @@ -69,4 +75,13 @@ class Abstract_VM_Version: AllStatic { // subclasses should define new versions to hide this one as needed. Note // that the O/S may support more sizes, but at most this many are used. static uint page_size_count() { return 2; } + + // Returns the number of parallel threads to be used for VM + // work. If that number has not been calculated, do so and + // save it. Returns ParallelGCThreads if it is set on the + // command line. + static unsigned int parallel_worker_threads(); + // Calculates and returns the number of parallel threads. May + // be VM version specific. + static unsigned int calc_parallel_worker_threads(); }; From 0dd8f3e8c01bfe0c6550ebaa97b44b6e01aeac6c Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 22 Feb 2008 17:55:13 -0800 Subject: [PATCH 029/274] 6650373: Assert in methodOopDesc::make_adapters() AdapterHandlerLibrary::get_create_adapter_index() returns incorrect value (-2) when CodeCache is full. Reviewed-by: sgoldman --- hotspot/src/share/vm/opto/output.cpp | 5 +---- .../src/share/vm/runtime/sharedRuntime.cpp | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index 7868ec2378f..690459e5f0b 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -921,11 +921,8 @@ static void turn_off_compiler(Compile* C) { // blown the code cache size. C->record_failure("excessive request to CodeCache"); } else { - UseInterpreter = true; - UseCompiler = false; - AlwaysCompileLoopMethods = false; + // Let CompilerBroker disable further compilations. C->record_failure("CodeCache is full"); - warning("CodeCache is full. Compiling has been disabled"); } } diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index cda256b74a3..4ae00d9556a 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1839,7 +1839,25 @@ int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) { regs); B = BufferBlob::create(AdapterHandlerEntry::name, &buffer); - if (B == NULL) return -2; // Out of CodeCache space + if (B == NULL) { + // CodeCache is full, disable compilation + // Ought to log this but compile log is only per compile thread + // and we're some non descript Java thread. + UseInterpreter = true; + if (UseCompiler || AlwaysCompileLoopMethods ) { +#ifndef PRODUCT + warning("CodeCache is full. Compiler has been disabled"); + if (CompileTheWorld || ExitOnFullCodeCache) { + before_exit(JavaThread::current()); + exit_globals(); // will delete tty + vm_direct_exit(CompileTheWorld ? 0 : 1); + } +#endif + UseCompiler = false; + AlwaysCompileLoopMethods = false; + } + return 0; // Out of CodeCache space (_handlers[0] == NULL) + } entry->relocate(B->instructions_begin()); #ifndef PRODUCT // debugging suppport From 9f1a8ede80bc83d81c160cf9f598e2637ca56449 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Mon, 25 Feb 2008 15:05:44 -0800 Subject: [PATCH 030/274] 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM T_ADDRESS size is defined as 'int' size (4 bytes) but C2 use it for raw pointers and as memory type for StoreP and LoadP nodes. Reviewed-by: jrose --- hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 4 ++-- hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp | 2 +- hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 8 ++++---- hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 2 +- hotspot/src/share/vm/c1/c1_LIR.cpp | 2 +- hotspot/src/share/vm/ci/ciField.hpp | 2 +- hotspot/src/share/vm/oops/arrayOop.hpp | 4 ++-- hotspot/src/share/vm/oops/klass.cpp | 2 +- hotspot/src/share/vm/opto/graphKit.cpp | 2 +- hotspot/src/share/vm/opto/library_call.cpp | 10 +++++----- hotspot/src/share/vm/opto/memnode.cpp | 2 +- hotspot/src/share/vm/opto/memnode.hpp | 8 +++++++- hotspot/src/share/vm/opto/superword.cpp | 5 +++-- hotspot/src/share/vm/opto/vectornode.cpp | 2 +- hotspot/src/share/vm/opto/vectornode.hpp | 6 +++--- hotspot/src/share/vm/services/heapDumper.cpp | 2 +- hotspot/src/share/vm/utilities/globalDefinitions.cpp | 10 ++++++++-- hotspot/src/share/vm/utilities/globalDefinitions.hpp | 11 ++++++++++- 18 files changed, 53 insertions(+), 31 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index e594085505b..8436fb8561b 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -2037,7 +2037,7 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr int LIR_Assembler::shift_amount(BasicType t) { - int elem_size = type2aelembytes[t]; + int elem_size = type2aelembytes(t); switch (elem_size) { case 1 : return 0; case 2 : return 1; @@ -2360,7 +2360,7 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) { op->tmp2()->as_register(), op->tmp3()->as_register(), arrayOopDesc::header_size(op->type()), - type2aelembytes[op->type()], + type2aelembytes(op->type()), op->klass()->as_register(), *op->stub()->entry()); } diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index 443551871fe..74bc5ecf3b4 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -179,7 +179,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index, LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark) { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); int shift = exact_log2(elem_size); LIR_Opr base_opr; diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index e87d55ce228..7c632cbabcd 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -546,8 +546,8 @@ void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, // set rsi.edi to the end of the arrays (arrays have same length) // negate the index - __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes[T_CHAR])); - __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes[T_CHAR])); + __ leal(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR))); + __ leal(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR))); __ negl(rax); // compare the strings in a loop @@ -1232,7 +1232,7 @@ void LIR_Assembler::prefetchw(LIR_Opr src) { NEEDS_CLEANUP; // This could be static? Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); switch (elem_size) { case 1: return Address::times_1; case 2: return Address::times_2; @@ -2739,7 +2739,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point"); - int elem_size = type2aelembytes[basic_type]; + int elem_size = type2aelembytes(basic_type); int shift_amount; Address::ScaleFactor scale; diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index a98d1b95416..7c4861d614e 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -151,7 +151,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o LIR_Address* addr; if (index_opr->is_constant()) { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); addr = new LIR_Address(array_opr, offset_in_bytes + index_opr->as_jint() * elem_size, type); } else { diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index 60e25387a71..46e725b5a14 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -105,7 +105,7 @@ LIR_Opr LIR_OprFact::dummy_value_type(ValueType* type) { LIR_Address::Scale LIR_Address::scale(BasicType type) { - int elem_size = type2aelembytes[type]; + int elem_size = type2aelembytes(type); switch (elem_size) { case 1: return LIR_Address::times_1; case 2: return LIR_Address::times_2; diff --git a/hotspot/src/share/vm/ci/ciField.hpp b/hotspot/src/share/vm/ci/ciField.hpp index 2498007f506..72a64c03a63 100644 --- a/hotspot/src/share/vm/ci/ciField.hpp +++ b/hotspot/src/share/vm/ci/ciField.hpp @@ -102,7 +102,7 @@ public: BasicType layout_type() { return type2field[(_type == NULL) ? T_OBJECT : _type->basic_type()]; } // How big is this field in memory? - int size_in_bytes() { return type2aelembytes[layout_type()]; } + int size_in_bytes() { return type2aelembytes(layout_type()); } // What is the offset of this field? int offset() { diff --git a/hotspot/src/share/vm/oops/arrayOop.hpp b/hotspot/src/share/vm/oops/arrayOop.hpp index e9bde1d6c8e..49fc566a90e 100644 --- a/hotspot/src/share/vm/oops/arrayOop.hpp +++ b/hotspot/src/share/vm/oops/arrayOop.hpp @@ -58,11 +58,11 @@ class arrayOopDesc : public oopDesc { // alignments. It gets the scale from the type2aelembytes array. static int32_t max_array_length(BasicType type) { assert(type >= 0 && type < T_CONFLICT, "wrong type"); - assert(type2aelembytes[type] != 0, "wrong type"); + assert(type2aelembytes(type) != 0, "wrong type"); // We use max_jint, since object_size is internally represented by an 'int' // This gives us an upper bound of max_jint words for the size of the oop. int32_t max_words = (max_jint - header_size(type) - 2); - int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes[type]; + int elembytes = (type == T_OBJECT) ? T_OBJECT_aelem_bytes : type2aelembytes(type); jlong len = ((jlong)max_words * HeapWordSize) / elembytes; return (len > max_jint) ? max_jint : (int32_t)len; } diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index c21393ce5a0..33e800a3cd5 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -182,7 +182,7 @@ jint Klass::array_layout_helper(BasicType etype) { assert(etype >= T_BOOLEAN && etype <= T_OBJECT, "valid etype"); // Note that T_ARRAY is not allowed here. int hsize = arrayOopDesc::base_offset_in_bytes(etype); - int esize = type2aelembytes[etype]; + int esize = type2aelembytes(etype); bool isobj = (etype == T_OBJECT); int tag = isobj ? _lh_array_tag_obj_value : _lh_array_tag_type_value; int lh = array_layout_helper(tag, hsize, etype, exact_log2(esize)); diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 642883ad64b..45471f29fde 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -1447,7 +1447,7 @@ Node* GraphKit::store_oop_to_unknown(Node* ctl, //-------------------------array_element_address------------------------- Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt, const TypeInt* sizetype) { - uint shift = exact_log2(type2aelembytes[elembt]); + uint shift = exact_log2(type2aelembytes(elembt)); uint header = arrayOopDesc::base_offset_in_bytes(elembt); // short-circuit a common case (saves lots of confusing waste motion) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index d78f62d4038..e69e2d9e68b 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -2097,7 +2097,7 @@ bool LibraryCallKit::inline_unsafe_CAS(BasicType type) { int type_words = type2size[type]; // Cannot inline wide CAS on machines that don't support it natively - if (type2aelembytes[type] > BytesPerInt && !VM_Version::supports_cx8()) + if (type2aelembytes(type) > BytesPerInt && !VM_Version::supports_cx8()) return false; C->set_has_unsafe_access(true); // Mark eventual nmethod as "unsafe". @@ -3975,7 +3975,7 @@ address LibraryCallKit::basictype2arraycopy(BasicType t, // both indices are constants int s_offs = src_offset_inttype->get_con(); int d_offs = dest_offset_inttype->get_con(); - int element_size = type2aelembytes[t]; + int element_size = type2aelembytes(t); aligned = ((arrayOopDesc::base_offset_in_bytes(t) + s_offs * element_size) % HeapWordSize == 0) && ((arrayOopDesc::base_offset_in_bytes(t) + d_offs * element_size) % HeapWordSize == 0); if (s_offs >= d_offs) disjoint = true; @@ -4389,7 +4389,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, if (alloc != NULL && use_ReduceInitialCardMarks()) { // If we do not need card marks, copy using the jint or jlong stub. copy_type = LP64_ONLY(T_LONG) NOT_LP64(T_INT); - assert(type2aelembytes[basic_elem_type] == type2aelembytes[copy_type], + assert(type2aelembytes(basic_elem_type) == type2aelembytes(copy_type), "sizes agree"); } } @@ -4659,7 +4659,7 @@ LibraryCallKit::generate_clear_array(const TypePtr* adr_type, Node* mem = memory(adr_type); // memory slice to operate on // scaling and rounding of indexes: - int scale = exact_log2(type2aelembytes[basic_elem_type]); + int scale = exact_log2(type2aelembytes(basic_elem_type)); int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type); int clear_low = (-1 << scale) & (BytesPerInt - 1); int bump_bit = (-1 << scale) & BytesPerInt; @@ -4753,7 +4753,7 @@ LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type, Node* dest, Node* dest_offset, Node* dest_size) { // See if there is an advantage from block transfer. - int scale = exact_log2(type2aelembytes[basic_elem_type]); + int scale = exact_log2(type2aelembytes(basic_elem_type)); if (scale >= LogBytesPerLong) return false; // it is already a block transfer diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index b65a03bbf3b..28f37d9a8a5 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -889,7 +889,7 @@ Node* LoadNode::eliminate_autobox(PhaseGVN* phase) { int shift = -1; Node* cache = NULL; if (is_autobox_cache(atp)) { - shift = exact_log2(type2aelembytes[T_OBJECT]); + shift = exact_log2(type2aelembytes(T_OBJECT)); cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset); } if (cache != NULL && base->in(Address)->is_AddP()) { diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index 34f36a27118..505cbdf979f 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -97,7 +97,13 @@ public: // What is the type of the value in memory? (T_VOID mean "unspecified".) virtual BasicType memory_type() const = 0; - virtual int memory_size() const { return type2aelembytes[memory_type()]; } + virtual int memory_size() const { +#ifdef ASSERT + return type2aelembytes(memory_type(), true); +#else + return type2aelembytes(memory_type()); +#endif + } // Search through memory states which precede this node (load or store). // Look for an exact match for the address, with no intervening diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp index b1467fc9e05..9b9ffdd0241 100644 --- a/hotspot/src/share/vm/opto/superword.cpp +++ b/hotspot/src/share/vm/opto/superword.cpp @@ -159,7 +159,8 @@ void SuperWord::find_adjacent_refs() { Node_List memops; for (int i = 0; i < _block.length(); i++) { Node* n = _block.at(i); - if (n->is_Mem() && in_bb(n)) { + if (n->is_Mem() && in_bb(n) && + is_java_primitive(n->as_Mem()->memory_type())) { int align = memory_alignment(n->as_Mem(), 0); if (align != bottom_align) { memops.push(n); @@ -570,7 +571,7 @@ void SuperWord::set_alignment(Node* s1, Node* s2, int align) { int SuperWord::data_size(Node* s) { const Type* t = velt_type(s); BasicType bt = t->array_element_basic_type(); - int bsize = type2aelembytes[bt]; + int bsize = type2aelembytes(bt); assert(bsize != 0, "valid size"); return bsize; } diff --git a/hotspot/src/share/vm/opto/vectornode.cpp b/hotspot/src/share/vm/opto/vectornode.cpp index f137516052d..7a581282d9c 100644 --- a/hotspot/src/share/vm/opto/vectornode.cpp +++ b/hotspot/src/share/vm/opto/vectornode.cpp @@ -135,7 +135,7 @@ Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) { int mid = lo + ct/2; Node* n1 = ct == 2 ? in(lo) : binaryTreePack(C, lo, mid); Node* n2 = ct == 2 ? in(lo+1) : binaryTreePack(C, mid, hi ); - int rslt_bsize = ct * type2aelembytes[elt_basic_type()]; + int rslt_bsize = ct * type2aelembytes(elt_basic_type()); if (bottom_type()->is_floatingpoint()) { switch (rslt_bsize) { case 8: return new (C, 3) PackFNode(n1, n2); diff --git a/hotspot/src/share/vm/opto/vectornode.hpp b/hotspot/src/share/vm/opto/vectornode.hpp index c0638677780..ed442b973ba 100644 --- a/hotspot/src/share/vm/opto/vectornode.hpp +++ b/hotspot/src/share/vm/opto/vectornode.hpp @@ -48,7 +48,7 @@ class VectorNode : public Node { uint length() const { return _length; } // Vector length static uint max_vlen(BasicType bt) { // max vector length - return (uint)(Matcher::vector_width_in_bytes() / type2aelembytes[bt]); + return (uint)(Matcher::vector_width_in_bytes() / type2aelembytes(bt)); } // Element and vector type @@ -392,7 +392,7 @@ class VectorLoadNode : public LoadNode { virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(); } virtual BasicType memory_type() const { return T_VOID; } - virtual int memory_size() const { return length()*type2aelembytes[elt_basic_type()]; } + virtual int memory_size() const { return length()*type2aelembytes(elt_basic_type()); } // Vector opcode from scalar opcode static int opcode(int sopc, uint vlen); @@ -620,7 +620,7 @@ class VectorStoreNode : public StoreNode { virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(); } virtual BasicType memory_type() const { return T_VOID; } - virtual int memory_size() const { return length()*type2aelembytes[elt_basic_type()]; } + virtual int memory_size() const { return length()*type2aelembytes(elt_basic_type()); } // Vector opcode from scalar opcode static int opcode(int sopc, uint vlen); diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp index cdd79a61817..afb7d9cbb14 100644 --- a/hotspot/src/share/vm/services/heapDumper.cpp +++ b/hotspot/src/share/vm/services/heapDumper.cpp @@ -997,7 +997,7 @@ void DumperSupport::dump_prim_array(DumpWriter* writer, typeArrayOop array) { } // If the byte ordering is big endian then we can copy most types directly - int length_in_bytes = array->length() * type2aelembytes[type]; + int length_in_bytes = array->length() * type2aelembytes(type); assert(length_in_bytes > 0, "nothing to copy"); switch (type) { diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.cpp b/hotspot/src/share/vm/utilities/globalDefinitions.cpp index 12edbeff792..89373ef2894 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.cpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.cpp @@ -214,7 +214,7 @@ BasicType type2wfield[T_CONFLICT+1] = { }; -int type2aelembytes[T_CONFLICT+1] = { +int _type2aelembytes[T_CONFLICT+1] = { 0, // 0 0, // 1 0, // 2 @@ -230,10 +230,16 @@ int type2aelembytes[T_CONFLICT+1] = { T_OBJECT_aelem_bytes, // T_OBJECT = 12, T_ARRAY_aelem_bytes, // T_ARRAY = 13, 0, // T_VOID = 14, - T_INT_aelem_bytes, // T_ADDRESS = 15, + T_OBJECT_aelem_bytes, // T_ADDRESS = 15, 0 // T_CONFLICT = 16, }; +#ifdef ASSERT +int type2aelembytes(BasicType t, bool allow_address) { + assert(allow_address || t != T_ADDRESS, " "); + return _type2aelembytes[t]; +} +#endif // Support for 64-bit integer arithmetic diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index 460cd1f345e..0feceb5deee 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -392,6 +392,10 @@ enum BasicType { T_ILLEGAL = 99 }; +inline bool is_java_primitive(BasicType t) { + return T_BOOLEAN <= t && t <= T_LONG; +} + // Convert a char from a classfile signature to a BasicType inline BasicType char2type(char c) { switch( c ) { @@ -464,7 +468,12 @@ enum ArrayElementSize { T_VOID_aelem_bytes = 0 }; -extern int type2aelembytes[T_CONFLICT+1]; // maps a BasicType to nof bytes used by its array element +extern int _type2aelembytes[T_CONFLICT+1]; // maps a BasicType to nof bytes used by its array element +#ifdef ASSERT +extern int type2aelembytes(BasicType t, bool allow_address = false); // asserts +#else +inline int type2aelembytes(BasicType t) { return _type2aelembytes[t]; } +#endif // JavaValue serves as a container for arbitrary Java values. From 51bf19209d6a425cd0a0ef2046df7282636e57d3 Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Tue, 26 Feb 2008 15:57:49 -0800 Subject: [PATCH 031/274] 6621728: Heap inspection should not crash in the face of C-heap exhaustion Deal more gracefully with situations where C-heap scratch space cannot be had Reviewed-by: jmasa --- .../src/share/vm/memory/heapInspection.cpp | 99 +++++++++++++------ .../src/share/vm/memory/heapInspection.hpp | 3 +- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/hotspot/src/share/vm/memory/heapInspection.cpp b/hotspot/src/share/vm/memory/heapInspection.cpp index ac8aa641fc2..9fc47755608 100644 --- a/hotspot/src/share/vm/memory/heapInspection.cpp +++ b/hotspot/src/share/vm/memory/heapInspection.cpp @@ -65,7 +65,7 @@ void KlassInfoEntry::print_on(outputStream* st) const { name = ""; } // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit - st->print_cr("%13" FORMAT64_MODIFIER "d %13" FORMAT64_MODIFIER "u %s", + st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s", (jlong) _instance_count, (julong) _instance_words * HeapWordSize, name); @@ -80,7 +80,10 @@ KlassInfoEntry* KlassInfoBucket::lookup(const klassOop k) { elt = elt->next(); } elt = new KlassInfoEntry(k, list()); - set_list(elt); + // We may be out of space to allocate the new entry. + if (elt != NULL) { + set_list(elt); + } return elt; } @@ -103,21 +106,25 @@ void KlassInfoBucket::empty() { } KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) { - _size = size; + _size = 0; _ref = ref; - _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, _size); - - for (int index = 0; index < _size; index++) { - _buckets[index].initialize(); + _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size); + if (_buckets != NULL) { + _size = size; + for (int index = 0; index < _size; index++) { + _buckets[index].initialize(); + } } } KlassInfoTable::~KlassInfoTable() { - for (int index = 0; index < _size; index++) { - _buckets[index].empty(); + if (_buckets != NULL) { + for (int index = 0; index < _size; index++) { + _buckets[index].empty(); + } + FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets); + _size = 0; } - FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets); - _size = 0; } uint KlassInfoTable::hash(klassOop p) { @@ -127,19 +134,32 @@ uint KlassInfoTable::hash(klassOop p) { KlassInfoEntry* KlassInfoTable::lookup(const klassOop k) { uint idx = hash(k) % _size; + assert(_buckets != NULL, "Allocation failure should have been caught"); KlassInfoEntry* e = _buckets[idx].lookup(k); - assert(k == e->klass(), "must be equal"); + // Lookup may fail if this is a new klass for which we + // could not allocate space for an new entry. + assert(e == NULL || k == e->klass(), "must be equal"); return e; } -void KlassInfoTable::record_instance(const oop obj) { +// Return false if the entry could not be recorded on account +// of running out of space required to create a new entry. +bool KlassInfoTable::record_instance(const oop obj) { klassOop k = obj->klass(); KlassInfoEntry* elt = lookup(k); - elt->set_count(elt->count() + 1); - elt->set_words(elt->words() + obj->size()); + // elt may be NULL if it's a new klass for which we + // could not allocate space for a new entry in the hashtable. + if (elt != NULL) { + elt->set_count(elt->count() + 1); + elt->set_words(elt->words() + obj->size()); + return true; + } else { + return false; + } } void KlassInfoTable::iterate(KlassInfoClosure* cic) { + assert(_size == 0 || _buckets != NULL, "Allocation failure should have been caught"); for (int index = 0; index < _size; index++) { _buckets[index].iterate(cic); } @@ -176,7 +196,7 @@ void KlassInfoHisto::print_elements(outputStream* st) const { total += elements()->at(i)->count(); totalw += elements()->at(i)->words(); } - st->print_cr("Total %13" FORMAT64_MODIFIER "d %13" FORMAT64_MODIFIER "u", + st->print_cr("Total " INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13), total, totalw * HeapWordSize); } @@ -199,12 +219,18 @@ class HistoClosure : public KlassInfoClosure { class RecordInstanceClosure : public ObjectClosure { private: KlassInfoTable* _cit; + size_t _missed_count; public: - RecordInstanceClosure(KlassInfoTable* cit) : _cit(cit) {} + RecordInstanceClosure(KlassInfoTable* cit) : + _cit(cit), _missed_count(0) {} void do_object(oop obj) { - _cit->record_instance(obj); + if (!_cit->record_instance(obj)) { + _missed_count++; + } } + + size_t missed_count() { return _missed_count; } }; void HeapInspection::heap_inspection(outputStream* st) { @@ -230,21 +256,32 @@ void HeapInspection::heap_inspection(outputStream* st) { ShouldNotReachHere(); // Unexpected heap kind for this op } // Collect klass instance info - - // Iterate over objects in the heap KlassInfoTable cit(KlassInfoTable::cit_size, ref); - RecordInstanceClosure ric(&cit); - Universe::heap()->object_iterate(&ric); + if (!cit.allocation_failed()) { + // Iterate over objects in the heap + RecordInstanceClosure ric(&cit); + Universe::heap()->object_iterate(&ric); - // Sort and print klass instance info - KlassInfoHisto histo("\n" - " num #instances #bytes class name\n" - "----------------------------------------------", - KlassInfoHisto::histo_initial_size); - HistoClosure hc(&histo); - cit.iterate(&hc); - histo.sort(); - histo.print_on(st); + // Report if certain classes are not counted because of + // running out of C-heap for the histogram. + size_t missed_count = ric.missed_count(); + if (missed_count != 0) { + st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT + " total instances in data below", + missed_count); + } + // Sort and print klass instance info + KlassInfoHisto histo("\n" + " num #instances #bytes class name\n" + "----------------------------------------------", + KlassInfoHisto::histo_initial_size); + HistoClosure hc(&histo); + cit.iterate(&hc); + histo.sort(); + histo.print_on(st); + } else { + st->print_cr("WARNING: Ran out of C-heap; histogram not generated"); + } st->flush(); if (Universe::heap()->kind() == CollectedHeap::GenCollectedHeap) { diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp index d56f8518c5f..f235d510b06 100644 --- a/hotspot/src/share/vm/memory/heapInspection.hpp +++ b/hotspot/src/share/vm/memory/heapInspection.hpp @@ -98,8 +98,9 @@ class KlassInfoTable: public StackObj { }; KlassInfoTable(int size, HeapWord* ref); ~KlassInfoTable(); - void record_instance(const oop obj); + bool record_instance(const oop obj); void iterate(KlassInfoClosure* cic); + bool allocation_failed() { return _buckets == NULL; } }; class KlassInfoHisto : public StackObj { From 73fa03eafcf9f01c6497091425c92a9975c20860 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Wed, 27 Feb 2008 00:23:37 -0800 Subject: [PATCH 032/274] 6610906: inexplicable IncompatibleClassChangeError Dependency check must treat polymorphic interfaces consistently Reviewed-by: kvn, never, sgoldman --- hotspot/src/share/vm/code/dependencies.cpp | 8 ++++++++ hotspot/src/share/vm/code/nmethod.cpp | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp index 75d0546642e..3ca91958270 100644 --- a/hotspot/src/share/vm/code/dependencies.cpp +++ b/hotspot/src/share/vm/code/dependencies.cpp @@ -882,6 +882,14 @@ klassOop ClassHierarchyWalker::find_witness_in(DepChange& changes, // Must not move the class hierarchy during this check: assert_locked_or_safepoint(Compile_lock); + int nof_impls = instanceKlass::cast(context_type)->nof_implementors(); + if (nof_impls > 1) { + // Avoid this case: *I.m > { A.m, C }; B.m > C + // %%% Until this is fixed more systematically, bail out. + // See corresponding comment in find_witness_anywhere. + return context_type; + } + assert(!is_participant(new_type), "only old classes are participants"); if (participants_hide_witnesses) { // If the new type is a subtype of a participant, we are done. diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index 89a3f0d1612..518c0ce717d 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -1971,7 +1971,7 @@ void nmethod::print_dependencies() { if (ctxk != NULL) { Klass* k = Klass::cast(ctxk); if (k->oop_is_instance() && ((instanceKlass*)k)->is_dependent_nmethod(this)) { - tty->print(" [nmethod<=klass]%s", k->external_name()); + tty->print_cr(" [nmethod<=klass]%s", k->external_name()); } } deps.log_dependency(); // put it into the xml log also From f235d989d0bd983448c1ecdda9196a0711b70e43 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 27 Feb 2008 13:55:58 -0500 Subject: [PATCH 033/274] 6549844: Wording problems in "An unexpected error ..." Changed wording to "A fatal error.." also don't claim it's not VM bug if in hotspot compilers (Java thread in native). Reviewed-by: jjh, sbohne, jrose, never --- hotspot/src/share/vm/utilities/vmError.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index 17dfb6b0c65..81b95462553 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -170,7 +170,8 @@ static void print_bug_submit_message(outputStream *out, Thread *thread) { out->print_raw_cr(Arguments::java_vendor_url_bug()); // If the crash is in native code, encourage user to submit a bug to the // provider of that code. - if (thread && thread->is_Java_thread()) { + if (thread && thread->is_Java_thread() && + !thread->is_hidden_from_external_view()) { JavaThread* jt = (JavaThread*)thread; if (jt->thread_state() == _thread_in_native) { out->print_cr("# The crash happened outside the Java Virtual Machine in native code.\n# See problematic frame for where to report the bug."); @@ -249,10 +250,10 @@ void VMError::report(outputStream* st) { BEGIN - STEP(10, "(printing unexpected error message)") + STEP(10, "(printing fatal error message)") st->print_cr("#"); - st->print_cr("# An unexpected error has been detected by Java Runtime Environment:"); + st->print_cr("# A fatal error has been detected by the Java Runtime Environment:"); STEP(15, "(printing type of error)") From 7be6246821e3297a1d0b59b3144e81429e15a896 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 28 Feb 2008 10:45:15 -0800 Subject: [PATCH 034/274] 6590177: jck60019 test assert(!repeated,"do not walk merges twice") A mergemem node could be not in worklist_store but in should_not_repeat vectorset since it was processed and removed from worklist_store before. Reviewed-by: jrose, never --- hotspot/src/share/vm/opto/gcm.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp index 88af191a1a3..c02989e04d0 100644 --- a/hotspot/src/share/vm/opto/gcm.cpp +++ b/hotspot/src/share/vm/opto/gcm.cpp @@ -448,9 +448,9 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { ResourceArea *area = Thread::current()->resource_area(); Node_List worklist_mem(area); // prior memory state to store Node_List worklist_store(area); // possible-def to explore + Node_List worklist_visited(area); // visited mergemem nodes Node_List non_early_stores(area); // all relevant stores outside of early bool must_raise_LCA = false; - DEBUG_ONLY(VectorSet should_not_repeat(area)); #ifdef TRACK_PHI_INPUTS // %%% This extra checking fails because MergeMem nodes are not GVNed. @@ -479,8 +479,8 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { Node* initial_mem = load->in(MemNode::Memory); worklist_store.push(initial_mem); + worklist_visited.push(initial_mem); worklist_mem.push(NULL); - DEBUG_ONLY(should_not_repeat.test_set(initial_mem->_idx)); while (worklist_store.size() > 0) { // Examine a nearby store to see if it might interfere with our load. Node* mem = worklist_mem.pop(); @@ -494,18 +494,20 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) { || op == Op_MergeMem // internal node of tree we are searching ) { mem = store; // It's not a possibly interfering store. + if (store == initial_mem) + initial_mem = NULL; // only process initial memory once + for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { store = mem->fast_out(i); if (store->is_MergeMem()) { // Be sure we don't get into combinatorial problems. // (Allow phis to be repeated; they can merge two relevant states.) - uint i = worklist_store.size(); - for (; i > 0; i--) { - if (worklist_store.at(i-1) == store) break; + uint j = worklist_visited.size(); + for (; j > 0; j--) { + if (worklist_visited.at(j-1) == store) break; } - if (i > 0) continue; // already on work list; do not repeat - DEBUG_ONLY(int repeated = should_not_repeat.test_set(store->_idx)); - assert(!repeated, "do not walk merges twice"); + if (j > 0) continue; // already on work list; do not repeat + worklist_visited.push(store); } worklist_mem.push(mem); worklist_store.push(store); From 9a4ccf8a064b4273de35e7c5bf2e4681599a85ed Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 28 Feb 2008 15:40:09 -0800 Subject: [PATCH 035/274] 6667573: Use set_req_X() in AddPNode::Ideal() for Iterative GVN Set_req_X() puts dependent nodes on IGVN worklist which allows to improve graph and gives more opportunities for EA scalar replacement. Reviewed-by: jrose, never --- hotspot/src/share/vm/opto/addnode.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/opto/addnode.cpp b/hotspot/src/share/vm/opto/addnode.cpp index 7b29f422911..2369792a1bf 100644 --- a/hotspot/src/share/vm/opto/addnode.cpp +++ b/hotspot/src/share/vm/opto/addnode.cpp @@ -505,15 +505,25 @@ Node *AddPNode::Ideal(PhaseGVN *phase, bool can_reshape) { const Type *temp_t2 = phase->type( in(Offset) ); if( temp_t2 == Type::TOP ) return NULL; const TypeX *t2 = temp_t2->is_intptr_t(); + Node* address; + Node* offset; if( t2->is_con() ) { // The Add of the flattened expression - set_req(Address, addp->in(Address)); - set_req(Offset , phase->MakeConX(t2->get_con() + t12->get_con())); - return this; // Made progress + address = addp->in(Address); + offset = phase->MakeConX(t2->get_con() + t12->get_con()); + } else { + // Else move the constant to the right. ((A+con)+B) into ((A+B)+con) + address = phase->transform(new (phase->C, 4) AddPNode(in(Base),addp->in(Address),in(Offset))); + offset = addp->in(Offset); + } + PhaseIterGVN *igvn = phase->is_IterGVN(); + if( igvn ) { + set_req_X(Address,address,igvn); + set_req_X(Offset,offset,igvn); + } else { + set_req(Address,address); + set_req(Offset,offset); } - // Else move the constant to the right. ((A+con)+B) into ((A+B)+con) - set_req(Address, phase->transform(new (phase->C, 4) AddPNode(in(Base),addp->in(Address),in(Offset)))); - set_req(Offset , addp->in(Offset)); return this; } } From c223fed0840265d0d638faa6465418f3f0594fc0 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 29 Feb 2008 09:57:18 -0800 Subject: [PATCH 036/274] 6667580: Optimize CmpP for allocations CmpP could be optimized out if it compares new allocated objects. Reviewed-by: jrose, never, rasbold --- hotspot/src/share/vm/includeDB_compiler2 | 7 ++++--- hotspot/src/share/vm/opto/callnode.hpp | 6 ++++-- hotspot/src/share/vm/opto/memnode.hpp | 2 +- hotspot/src/share/vm/opto/node.hpp | 3 +++ hotspot/src/share/vm/opto/subnode.cpp | 7 +++++++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/includeDB_compiler2 b/hotspot/src/share/vm/includeDB_compiler2 index 0138cc664f6..01a6b9c94ce 100644 --- a/hotspot/src/share/vm/includeDB_compiler2 +++ b/hotspot/src/share/vm/includeDB_compiler2 @@ -19,7 +19,7 @@ // 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. -// +// // ad_.cpp adGlobals_.hpp @@ -990,6 +990,7 @@ stubRoutines.cpp runtime.hpp subnode.cpp addnode.hpp subnode.cpp allocation.inline.hpp +subnode.cpp callnode.hpp subnode.cpp cfgnode.hpp subnode.cpp compileLog.hpp subnode.cpp connode.hpp @@ -1086,7 +1087,7 @@ idealGraphPrinter.hpp growableArray.hpp idealGraphPrinter.hpp ostream.hpp idealGraphPrinter.cpp idealGraphPrinter.hpp -idealGraphPrinter.cpp chaitin.hpp +idealGraphPrinter.cpp chaitin.hpp idealGraphPrinter.cpp machnode.hpp idealGraphPrinter.cpp parse.hpp idealGraphPrinter.cpp threadCritical.hpp @@ -1098,4 +1099,4 @@ parse2.cpp idealGraphPrinter.hpp parse1.cpp idealGraphPrinter.hpp matcher.cpp idealGraphPrinter.hpp loopnode.cpp idealGraphPrinter.hpp -chaitin.cpp idealGraphPrinter.hpp +chaitin.cpp idealGraphPrinter.hpp diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index e1e6116b689..c8315f94c96 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -38,7 +38,7 @@ class CallRuntimeNode; class CallLeafNode; class CallLeafNoFPNode; class AllocateNode; -class AllocateArrayNode; +class AllocateArrayNode; class LockNode; class UnlockNode; class JVMState; @@ -91,7 +91,9 @@ public: class ParmNode : public ProjNode { static const char * const names[TypeFunc::Parms+1]; public: - ParmNode( StartNode *src, uint con ) : ProjNode(src,con) {} + ParmNode( StartNode *src, uint con ) : ProjNode(src,con) { + init_class_id(Class_Parm); + } virtual int Opcode() const; virtual bool is_CFG() const { return (_con == TypeFunc::Control); } virtual uint ideal_reg() const; diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index 505cbdf979f..8c8676b4d36 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -60,13 +60,13 @@ protected: debug_only(_adr_type=at; adr_type();) } +public: // Helpers for the optimizer. Documented in memnode.cpp. static bool detect_ptr_independence(Node* p1, AllocateNode* a1, Node* p2, AllocateNode* a2, PhaseTransform* phase); static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast); -public: // This one should probably be a phase-specific function: static bool detect_dominating_control(Node* dom, Node* sub); diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index f93562c09e7..8066da703ba 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -91,6 +91,7 @@ class Node_List; class Node_Stack; class NullCheckNode; class OopMap; +class ParmNode; class PCTableNode; class PhaseCCP; class PhaseGVN; @@ -557,6 +558,7 @@ public: DEFINE_CLASS_ID(JumpProj, Proj, 1) DEFINE_CLASS_ID(IfTrue, Proj, 2) DEFINE_CLASS_ID(IfFalse, Proj, 3) + DEFINE_CLASS_ID(Parm, Proj, 4) DEFINE_CLASS_ID(Region, Node, 3) DEFINE_CLASS_ID(Loop, Region, 0) @@ -712,6 +714,7 @@ public: DEFINE_CLASS_QUERY(Mul) DEFINE_CLASS_QUERY(Multi) DEFINE_CLASS_QUERY(MultiBranch) + DEFINE_CLASS_QUERY(Parm) DEFINE_CLASS_QUERY(PCTable) DEFINE_CLASS_QUERY(Phi) DEFINE_CLASS_QUERY(Proj) diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 1344197ca22..2fc00289233 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -614,6 +614,13 @@ const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const { const TypeOopPtr* p0 = r0->isa_oopptr(); const TypeOopPtr* p1 = r1->isa_oopptr(); if (p0 && p1) { + Node* in1 = in(1)->uncast(); + Node* in2 = in(2)->uncast(); + AllocateNode* alloc1 = AllocateNode::Ideal_allocation(in1, NULL); + AllocateNode* alloc2 = AllocateNode::Ideal_allocation(in2, NULL); + if (MemNode::detect_ptr_independence(in1, alloc1, in2, alloc2, NULL)) { + return TypeInt::CC_GT; // different pointers + } ciKlass* klass0 = p0->klass(); bool xklass0 = p0->klass_is_exact(); ciKlass* klass1 = p1->klass(); From 7ec44373b51141fa3fff9336636923f42a4140b8 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 29 Feb 2008 11:22:27 -0800 Subject: [PATCH 037/274] 6667581: Don't generate initialization (by 0) code for arrays with size 0 Generate_arraycopy() does not check the size of allocated array. Reviewed-by: jrose, never --- hotspot/src/share/vm/opto/library_call.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index e69e2d9e68b..b0587edfc3b 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -4170,6 +4170,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, && !_gvn.eqv_uncast(src, dest) && ((alloc = tightly_coupled_allocation(dest, slow_region)) != NULL) + && _gvn.find_int_con(alloc->in(AllocateNode::ALength), 1) > 0 && alloc->maybe_set_complete(&_gvn)) { // "You break it, you buy it." InitializeNode* init = alloc->initialization(); From a6d8fca8768972ae0f1ce72e06677e5dc3260e09 Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Fri, 29 Feb 2008 14:42:56 -0800 Subject: [PATCH 038/274] 6668743: CMS: Consolidate block statistics reporting code Reduce the amount of related code replication and improve pretty printing. Reviewed-by: jmasa --- .../binaryTreeDictionary.cpp | 91 +++++++------------ .../compactibleFreeListSpace.cpp | 85 +++++++---------- .../compactibleFreeListSpace.hpp | 12 ++- .../concurrentMarkSweep/freeList.cpp | 26 ++++++ .../concurrentMarkSweep/freeList.hpp | 14 ++- .../vm/gc_implementation/includeDB_gc_shared | 17 +++- .../shared}/allocationStats.cpp | 0 .../shared}/allocationStats.hpp | 2 + hotspot/src/share/vm/includeDB_core | 16 +--- 9 files changed, 130 insertions(+), 133 deletions(-) rename hotspot/src/share/vm/{memory => gc_implementation/shared}/allocationStats.cpp (100%) rename hotspot/src/share/vm/{memory => gc_implementation/shared}/allocationStats.hpp (99%) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp index 09e0b282b06..91d381d5501 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp @@ -1071,85 +1071,56 @@ void BinaryTreeDictionary::reportStatistics() const { // for each list in the tree. Also print some summary // information. class printTreeCensusClosure : public AscendTreeCensusClosure { + int _print_line; size_t _totalFree; - AllocationStats _totals; - size_t _count; + FreeList _total; public: printTreeCensusClosure() { + _print_line = 0; _totalFree = 0; - _count = 0; - _totals.initialize(); } - AllocationStats* totals() { return &_totals; } - size_t count() { return _count; } - void increment_count_by(size_t v) { _count += v; } + FreeList* total() { return &_total; } size_t totalFree() { return _totalFree; } - void increment_totalFree_by(size_t v) { _totalFree += v; } void do_list(FreeList* fl) { - bool nl = false; // "maybe this is not needed" isNearLargestChunk(fl->head()); - - gclog_or_tty->print("%c %4d\t\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "\n", - " n"[nl], fl->size(), fl->bfrSurp(), fl->surplus(), - fl->desired(), fl->prevSweep(), fl->beforeSweep(), fl->count(), - fl->coalBirths(), fl->coalDeaths(), fl->splitBirths(), - fl->splitDeaths()); - - increment_totalFree_by(fl->count() * fl->size()); - increment_count_by(fl->count()); - totals()->set_bfrSurp(totals()->bfrSurp() + fl->bfrSurp()); - totals()->set_surplus(totals()->splitDeaths() + fl->surplus()); - totals()->set_prevSweep(totals()->prevSweep() + fl->prevSweep()); - totals()->set_beforeSweep(totals()->beforeSweep() + fl->beforeSweep()); - totals()->set_coalBirths(totals()->coalBirths() + fl->coalBirths()); - totals()->set_coalDeaths(totals()->coalDeaths() + fl->coalDeaths()); - totals()->set_splitBirths(totals()->splitBirths() + fl->splitBirths()); - totals()->set_splitDeaths(totals()->splitDeaths() + fl->splitDeaths()); + if (++_print_line >= 40) { + FreeList::print_labels_on(gclog_or_tty, "size"); + _print_line = 0; + } + fl->print_on(gclog_or_tty); + _totalFree += fl->count() * fl->size() ; + total()->set_count( total()->count() + fl->count() ); + total()->set_bfrSurp( total()->bfrSurp() + fl->bfrSurp() ); + total()->set_surplus( total()->splitDeaths() + fl->surplus() ); + total()->set_desired( total()->desired() + fl->desired() ); + total()->set_prevSweep( total()->prevSweep() + fl->prevSweep() ); + total()->set_beforeSweep(total()->beforeSweep() + fl->beforeSweep()); + total()->set_coalBirths( total()->coalBirths() + fl->coalBirths() ); + total()->set_coalDeaths( total()->coalDeaths() + fl->coalDeaths() ); + total()->set_splitBirths(total()->splitBirths() + fl->splitBirths()); + total()->set_splitDeaths(total()->splitDeaths() + fl->splitDeaths()); } }; void BinaryTreeDictionary::printDictCensus(void) const { gclog_or_tty->print("\nBinaryTree\n"); - gclog_or_tty->print( - "%4s\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", - "size", "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep", - "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); - + FreeList::print_labels_on(gclog_or_tty, "size"); printTreeCensusClosure ptc; ptc.do_tree(root()); + FreeList* total = ptc.total(); + FreeList::print_labels_on(gclog_or_tty, " "); + total->print_on(gclog_or_tty, "TOTAL\t"); gclog_or_tty->print( - "\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", - "bfrsurp", "surplus", "prvSwep", "bfrSwep", - "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); - gclog_or_tty->print( - "%s\t\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" "\n", - "totl", - ptc.totals()->bfrSurp(), - ptc.totals()->surplus(), - ptc.totals()->prevSweep(), - ptc.totals()->beforeSweep(), - ptc.count(), - ptc.totals()->coalBirths(), - ptc.totals()->coalDeaths(), - ptc.totals()->splitBirths(), - ptc.totals()->splitDeaths()); - gclog_or_tty->print("totalFree(words): %7d growth: %8.5f deficit: %8.5f\n", + "totalFree(words): " SIZE_FORMAT_W(16) + " growth: %8.5f deficit: %8.5f\n", ptc.totalFree(), - (double)(ptc.totals()->splitBirths()+ptc.totals()->coalBirths() - -ptc.totals()->splitDeaths()-ptc.totals()->coalDeaths()) - /(ptc.totals()->prevSweep() != 0 ? - (double)ptc.totals()->prevSweep() : 1.0), - (double)(ptc.totals()->desired() - ptc.count()) - /(ptc.totals()->desired() != 0 ? - (double)ptc.totals()->desired() : 1.0)); + (double)(total->splitBirths() + total->coalBirths() + - total->splitDeaths() - total->coalDeaths()) + /(total->prevSweep() != 0 ? (double)total->prevSweep() : 1.0), + (double)(total->desired() - total->count()) + /(total->desired() != 0 ? (double)total->desired() : 1.0)); } // Verify the following tree invariants: diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 27b5c08100c..de5611ddb7b 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -1835,7 +1835,7 @@ void CompactibleFreeListSpace::object_iterate_since_last_GC(ObjectClosure* cl) { guarantee(false, "NYI"); } -bool CompactibleFreeListSpace::linearAllocationWouldFail() { +bool CompactibleFreeListSpace::linearAllocationWouldFail() const { return _smallLinearAllocBlock._word_size == 0; } @@ -1906,6 +1906,13 @@ CompactibleFreeListSpace::refillLinearAllocBlock(LinearAllocBlock* blk) { } } +// Support for concurrent collection policy decisions. +bool CompactibleFreeListSpace::should_concurrent_collect() const { + // In the future we might want to add in frgamentation stats -- + // including erosion of the "mountain" into this decision as well. + return !adaptive_freelists() && linearAllocationWouldFail(); +} + // Support for compaction void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) { @@ -2013,11 +2020,11 @@ void CompactibleFreeListSpace::clearFLCensus() { } } -void CompactibleFreeListSpace::endSweepFLCensus(int sweepCt) { +void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { setFLSurplus(); setFLHints(); if (PrintGC && PrintFLSCensus > 0) { - printFLCensus(sweepCt); + printFLCensus(sweep_count); } clearFLCensus(); assert_locked(); @@ -2293,59 +2300,37 @@ void CompactibleFreeListSpace::checkFreeListConsistency() const { } #endif -void CompactibleFreeListSpace::printFLCensus(int sweepCt) const { +void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { assert_lock_strong(&_freelistLock); - ssize_t bfrSurp = 0; - ssize_t surplus = 0; - ssize_t desired = 0; - ssize_t prevSweep = 0; - ssize_t beforeSweep = 0; - ssize_t count = 0; - ssize_t coalBirths = 0; - ssize_t coalDeaths = 0; - ssize_t splitBirths = 0; - ssize_t splitDeaths = 0; - gclog_or_tty->print("end sweep# %d\n", sweepCt); - gclog_or_tty->print("%4s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "\n", - "size", "bfrsurp", "surplus", "desired", "prvSwep", - "bfrSwep", "count", "cBirths", "cDeaths", "sBirths", - "sDeaths"); - + FreeList total; + gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); + FreeList::print_labels_on(gclog_or_tty, "size"); size_t totalFree = 0; for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { const FreeList *fl = &_indexedFreeList[i]; - totalFree += fl->count() * fl->size(); - - gclog_or_tty->print("%4d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "\n", - fl->size(), fl->bfrSurp(), fl->surplus(), fl->desired(), - fl->prevSweep(), fl->beforeSweep(), fl->count(), fl->coalBirths(), - fl->coalDeaths(), fl->splitBirths(), fl->splitDeaths()); - bfrSurp += fl->bfrSurp(); - surplus += fl->surplus(); - desired += fl->desired(); - prevSweep += fl->prevSweep(); - beforeSweep += fl->beforeSweep(); - count += fl->count(); - coalBirths += fl->coalBirths(); - coalDeaths += fl->coalDeaths(); - splitBirths += fl->splitBirths(); - splitDeaths += fl->splitDeaths(); + totalFree += fl->count() * fl->size(); + if (i % (40*IndexSetStride) == 0) { + FreeList::print_labels_on(gclog_or_tty, "size"); + } + fl->print_on(gclog_or_tty); + total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() ); + total.set_surplus( total.surplus() + fl->surplus() ); + total.set_desired( total.desired() + fl->desired() ); + total.set_prevSweep( total.prevSweep() + fl->prevSweep() ); + total.set_beforeSweep(total.beforeSweep() + fl->beforeSweep()); + total.set_count( total.count() + fl->count() ); + total.set_coalBirths( total.coalBirths() + fl->coalBirths() ); + total.set_coalDeaths( total.coalDeaths() + fl->coalDeaths() ); + total.set_splitBirths(total.splitBirths() + fl->splitBirths()); + total.set_splitDeaths(total.splitDeaths() + fl->splitDeaths()); } - gclog_or_tty->print("%4s\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" "\n", - "totl", - bfrSurp, surplus, desired, prevSweep, beforeSweep, - count, coalBirths, coalDeaths, splitBirths, splitDeaths); - gclog_or_tty->print_cr("Total free in indexed lists %d words", totalFree); + total.print_on(gclog_or_tty, "TOTAL"); + gclog_or_tty->print_cr("Total free in indexed lists " + SIZE_FORMAT " words", totalFree); gclog_or_tty->print("growth: %8.5f deficit: %8.5f\n", - (double)(splitBirths+coalBirths-splitDeaths-coalDeaths)/ - (prevSweep != 0 ? (double)prevSweep : 1.0), - (double)(desired - count)/(desired != 0 ? (double)desired : 1.0)); + (double)(total.splitBirths()+total.coalBirths()-total.splitDeaths()-total.coalDeaths())/ + (total.prevSweep() != 0 ? (double)total.prevSweep() : 1.0), + (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0)); _dictionary->printDictCensus(); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp index ef5d12a6cac..5eb0f41b6a1 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp @@ -418,7 +418,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { // chunk exists, return NULL. FreeChunk* find_chunk_at_end(); - bool adaptive_freelists() { return _adaptive_freelists; } + bool adaptive_freelists() const { return _adaptive_freelists; } void set_collector(CMSCollector* collector) { _collector = collector; } @@ -566,7 +566,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { FreeChunk* allocateScratch(size_t size); // returns true if either the small or large linear allocation buffer is empty. - bool linearAllocationWouldFail(); + bool linearAllocationWouldFail() const; // Adjust the chunk for the minimum size. This version is called in // most cases in CompactibleFreeListSpace methods. @@ -585,6 +585,9 @@ class CompactibleFreeListSpace: public CompactibleSpace { void addChunkAndRepairOffsetTable(HeapWord* chunk, size_t size, bool coalesced); + // Support for decisions regarding concurrent collection policy + bool should_concurrent_collect() const; + // Support for compaction void prepare_for_compaction(CompactPoint* cp); void adjust_pointers(); @@ -622,7 +625,7 @@ class CompactibleFreeListSpace: public CompactibleSpace { // coalescing of chunks during the sweep of garbage. // Print the statistics for the free lists. - void printFLCensus(int sweepCt) const; + void printFLCensus(size_t sweep_count) const; // Statistics functions // Initialize census for lists before the sweep. @@ -635,12 +638,11 @@ class CompactibleFreeListSpace: public CompactibleSpace { // Clear the census for each of the free lists. void clearFLCensus(); // Perform functions for the census after the end of the sweep. - void endSweepFLCensus(int sweepCt); + void endSweepFLCensus(size_t sweep_count); // Return true if the count of free chunks is greater // than the desired number of free chunks. bool coalOverPopulated(size_t size); - // Record (for each size): // // split-births = #chunks added due to splits in (prev-sweep-end, diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp index 1d1024e5057..e7b1b3aae8d 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp @@ -302,3 +302,29 @@ void FreeList::assert_proper_lock_protection_work() const { #endif } #endif + +// Print the "label line" for free list stats. +void FreeList::print_labels_on(outputStream* st, const char* c) { + st->print("%16s\t", c); + st->print("%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" + "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "\n", + "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep", + "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); +} + +// Print the AllocationStats for the given free list. If the second argument +// to the call is a non-null string, it is printed in the first column; +// otherwise, if the argument is null (the default), then the size of the +// (free list) block is printed in the first column. +void FreeList::print_on(outputStream* st, const char* c) const { + if (c != NULL) { + st->print("%16s", c); + } else { + st->print(SIZE_FORMAT_W(16), size()); + } + st->print("\t" + SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" + SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\n", + bfrSurp(), surplus(), desired(), prevSweep(), beforeSweep(), + count(), coalBirths(), coalDeaths(), splitBirths(), splitDeaths()); +} diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp index 4d4c1362a20..b553dd3fe47 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp @@ -38,6 +38,7 @@ class Mutex; class FreeList VALUE_OBJ_CLASS_SPEC { friend class CompactibleFreeListSpace; + friend class printTreeCensusClosure; FreeChunk* _head; // List of free chunks FreeChunk* _tail; // Tail of list of free chunks size_t _size; // Size in Heap words of each chunks @@ -63,10 +64,11 @@ class FreeList VALUE_OBJ_CLASS_SPEC { protected: void init_statistics(); void set_count(ssize_t v) { _count = v;} - void increment_count() { _count++; } + void increment_count() { _count++; } void decrement_count() { _count--; - assert(_count >= 0, "Count should not be negative"); } + assert(_count >= 0, "Count should not be negative"); + } public: // Constructor @@ -159,6 +161,10 @@ class FreeList VALUE_OBJ_CLASS_SPEC { ssize_t desired() const { return _allocation_stats.desired(); } + void set_desired(ssize_t v) { + assert_proper_lock_protection(); + _allocation_stats.set_desired(v); + } void compute_desired(float inter_sweep_current, float inter_sweep_estimate) { assert_proper_lock_protection(); @@ -298,4 +304,8 @@ class FreeList VALUE_OBJ_CLASS_SPEC { // Verify that the chunk is in the list. // found. Return NULL if "fc" is not found. bool verifyChunkInFreeLists(FreeChunk* fc) const; + + // Printing support + static void print_labels_on(outputStream* st, const char* c); + void print_on(outputStream* st, const char* c = NULL) const; }; diff --git a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared index c0b6332e89f..ca8a47fa2fa 100644 --- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared +++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared @@ -19,15 +19,22 @@ // 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. -// +// // // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! -gcAdaptivePolicyCounters.hpp adaptiveSizePolicy.hpp -gcAdaptivePolicyCounters.hpp gcPolicyCounters.hpp +allocationStats.cpp allocationStats.hpp +allocationStats.cpp ostream.hpp -gcAdaptivePolicyCounters.cpp resourceArea.hpp +allocationStats.hpp allocation.hpp +allocationStats.hpp gcUtil.hpp +allocationStats.hpp globalDefinitions.hpp + +gcAdaptivePolicyCounters.hpp adaptiveSizePolicy.hpp +gcAdaptivePolicyCounters.hpp gcPolicyCounters.hpp + +gcAdaptivePolicyCounters.cpp resourceArea.hpp gcAdaptivePolicyCounters.cpp gcAdaptivePolicyCounters.hpp gSpaceCounters.cpp generation.hpp @@ -44,7 +51,7 @@ immutableSpace.cpp universe.hpp isGCActiveMark.hpp parallelScavengeHeap.hpp -markSweep.inline.hpp psParallelCompact.hpp +markSweep.inline.hpp psParallelCompact.hpp mutableNUMASpace.cpp mutableNUMASpace.hpp mutableNUMASpace.cpp sharedHeap.hpp diff --git a/hotspot/src/share/vm/memory/allocationStats.cpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.cpp similarity index 100% rename from hotspot/src/share/vm/memory/allocationStats.cpp rename to hotspot/src/share/vm/gc_implementation/shared/allocationStats.cpp diff --git a/hotspot/src/share/vm/memory/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp similarity index 99% rename from hotspot/src/share/vm/memory/allocationStats.hpp rename to hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp index 829a39cb5a0..a60fc2bc164 100644 --- a/hotspot/src/share/vm/memory/allocationStats.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp @@ -98,6 +98,8 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC { } ssize_t desired() const { return _desired; } + void set_desired(ssize_t v) { _desired = v; } + ssize_t coalDesired() const { return _coalDesired; } void set_coalDesired(ssize_t v) { _coalDesired = v; } diff --git a/hotspot/src/share/vm/includeDB_core b/hotspot/src/share/vm/includeDB_core index cbf8e561a73..a4c4a356f82 100644 --- a/hotspot/src/share/vm/includeDB_core +++ b/hotspot/src/share/vm/includeDB_core @@ -19,7 +19,7 @@ // 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. -// +// // // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! @@ -46,13 +46,13 @@ // as dependencies. Header files named H.inline.hpp generally contain // bodies for inline functions declared in H.hpp. // -// NOTE: Files that use the token "generate_platform_dependent_include" +// NOTE: Files that use the token "generate_platform_dependent_include" // are expected to contain macro references like , , ... and // makedeps has a dependency on these platform files looking like: -// foo_.trailing_string +// foo_.trailing_string // (where "trailing_string" can be any legal filename strings but typically // is "hpp" or "inline.hpp"). -// +// // The dependency in makedeps (and enforced) is that an underscore // will precedure the macro invocation. Note that this restriction // is only enforced on filenames that have the dependency token @@ -148,12 +148,6 @@ allocation.hpp globals.hpp allocation.inline.hpp os.hpp -allocationStats.cpp allocationStats.hpp - -allocationStats.hpp allocation.hpp -allocationStats.hpp gcUtil.hpp -allocationStats.hpp globalDefinitions.hpp - aprofiler.cpp aprofiler.hpp aprofiler.cpp collectedHeap.inline.hpp aprofiler.cpp oop.inline.hpp @@ -1935,7 +1929,7 @@ icache_.hpp generate_platform_dependent_include init.cpp bytecodes.hpp init.cpp collectedHeap.hpp -init.cpp handles.inline.hpp +init.cpp handles.inline.hpp init.cpp icBuffer.hpp init.cpp icache.hpp init.cpp init.hpp From 09d7f4bbcfe5123354aae0379beadc49bcda94ca Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 29 Feb 2008 19:07:15 -0800 Subject: [PATCH 039/274] 6667588: Don't generate duplicated CMP for float/double values Float CMove generation add duplicated CMPF if there are more then one Move depending on the condition. Reviewed-by: jrose, never, rasbold --- hotspot/src/share/vm/opto/loopopts.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index 0da6b1eeebb..d7b9ec89337 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -435,9 +435,11 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { // Check profitability int cost = 0; + int phis = 0; for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { Node *out = region->fast_out(i); if( !out->is_Phi() ) continue; // Ignore other control edges, etc + phis++; PhiNode* phi = out->as_Phi(); switch (phi->type()->basic_type()) { case T_LONG: @@ -489,6 +491,12 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { } } if( cost >= ConditionalMoveLimit ) return NULL; // Too much goo + Node* bol = iff->in(1); + assert( bol->Opcode() == Op_Bool, "" ); + int cmp_op = bol->in(1)->Opcode(); + // It is expensive to generate flags from a float compare. + // Avoid duplicated float compare. + if( phis > 1 && (cmp_op == Op_CmpF || cmp_op == Op_CmpD)) return NULL; // -------------- // Now replace all Phis with CMOV's From dc6ad19d705a56b1945988da7bb874c099e0c73c Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 29 Feb 2008 19:57:41 -0800 Subject: [PATCH 040/274] 6667618: disable LoadL->ConvL2I ==> LoadI optimization This optimization causes problems (sizes of Load and Store nodes do not match) for objects initialization code and Escape Analysis Reviewed-by: jrose, never --- hotspot/src/share/vm/opto/connode.cpp | 31 +++------------------------ hotspot/src/share/vm/opto/memnode.cpp | 20 ++++++----------- 2 files changed, 10 insertions(+), 41 deletions(-) diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp index 6896f34710d..de3eed6f0e2 100644 --- a/hotspot/src/share/vm/opto/connode.cpp +++ b/hotspot/src/share/vm/opto/connode.cpp @@ -982,34 +982,9 @@ Node *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) { return new (phase->C, 3) AddINode(add1,add2); } - // Fold up with a prior LoadL: LoadL->ConvL2I ==> LoadI - // Requires we understand the 'endianess' of Longs. - if( andl_op == Op_LoadL ) { - Node *adr = andl->in(MemNode::Address); - // VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles -#ifndef VM_LITTLE_ENDIAN - // The transformation can cause problems on BIG_ENDIAN architectures - // where the jint is not the same address as the jlong. Specifically, we - // will fail to insert an anti-dependence in GCM between the LoadI and a - // subsequent StoreL because different memory offsets provoke - // flatten_alias_type() into indicating two different types. See bug - // 4755222. - - // Node *base = adr->is_AddP() ? adr->in(AddPNode::Base) : adr; - // adr = phase->transform( new (phase->C, 4) AddPNode(base,adr,phase->MakeConX(sizeof(jint)))); - return NULL; -#else - if (phase->C->alias_type(andl->adr_type())->is_volatile()) { - // Picking up the low half by itself bypasses the atomic load and we could - // end up with more than one non-atomic load. See bugs 4432655 and 4526490. - // We could go to the trouble of iterating over andl's output edges and - // punting only if there's more than one real use, but we don't bother. - return NULL; - } - return new (phase->C, 3) LoadINode(andl->in(MemNode::Control),andl->in(MemNode::Memory),adr,((LoadLNode*)andl)->raw_adr_type()); -#endif - } - + // Disable optimization: LoadL->ConvL2I ==> LoadI. + // It causes problems (sizes of Load and Store nodes do not match) + // in objects initialization code and Escape Analysis. return NULL; } diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 28f37d9a8a5..03f43d88595 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -108,19 +108,13 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { // Avoid independent memory operations Node* old_mem = mem; - if (mem->is_Proj() && mem->in(0)->is_Initialize()) { - InitializeNode* init = mem->in(0)->as_Initialize(); - if (init->is_complete()) { // i.e., after macro expansion - const TypePtr* tp = t_adr->is_ptr(); - uint alias_idx = phase->C->get_alias_index(tp); - // Free this slice from the init. It was hooked, temporarily, - // by GraphKit::set_output_for_allocation. - if (alias_idx > Compile::AliasIdxRaw) { - mem = init->memory(alias_idx); - // ...but not with the raw-pointer slice. - } - } - } + // The code which unhooks non-raw memories from complete (macro-expanded) + // initializations was removed. After macro-expansion all stores catched + // by Initialize node became raw stores and there is no information + // which memory slices they modify. So it is unsafe to move any memory + // operation above these stores. Also in most cases hooked non-raw memories + // were already unhooked by using information from detect_ptr_independence() + // and find_previous_store(). if (mem->is_MergeMem()) { MergeMemNode* mmem = mem->as_MergeMem(); From fde483bc31506313b228b55c163dc7cd3716ea04 Mon Sep 17 00:00:00 2001 From: Mark Reinhold Date: Fri, 29 Feb 2008 20:03:57 -0800 Subject: [PATCH 041/274] 6669216: Add jcheck configuration directories Reviewed-by: ohair, xdono --- .jcheck/conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 .jcheck/conf diff --git a/.jcheck/conf b/.jcheck/conf new file mode 100644 index 00000000000..d8227cd90e3 --- /dev/null +++ b/.jcheck/conf @@ -0,0 +1 @@ +project=jdk7 From 5529465023ff79b998cc7ebc248db4eaa3953cc1 Mon Sep 17 00:00:00 2001 From: Mark Reinhold Date: Fri, 29 Feb 2008 20:03:57 -0800 Subject: [PATCH 042/274] 6669216: Add jcheck configuration directories Reviewed-by: ohair, xdono --- corba/.jcheck/conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 corba/.jcheck/conf diff --git a/corba/.jcheck/conf b/corba/.jcheck/conf new file mode 100644 index 00000000000..d8227cd90e3 --- /dev/null +++ b/corba/.jcheck/conf @@ -0,0 +1 @@ +project=jdk7 From 1559ee2a70904af7e487f9bbfece5ff8c41737d4 Mon Sep 17 00:00:00 2001 From: Mark Reinhold Date: Fri, 29 Feb 2008 20:03:58 -0800 Subject: [PATCH 043/274] 6669216: Add jcheck configuration directories Reviewed-by: ohair, xdono --- hotspot/.jcheck/conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 hotspot/.jcheck/conf diff --git a/hotspot/.jcheck/conf b/hotspot/.jcheck/conf new file mode 100644 index 00000000000..d8227cd90e3 --- /dev/null +++ b/hotspot/.jcheck/conf @@ -0,0 +1 @@ +project=jdk7 From c5ef8d3eaf301ae73e33cfc9080904b3f5cd2c5f Mon Sep 17 00:00:00 2001 From: Mark Reinhold Date: Fri, 29 Feb 2008 20:03:59 -0800 Subject: [PATCH 044/274] 6669216: Add jcheck configuration directories Reviewed-by: ohair, xdono --- jaxp/.jcheck/conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 jaxp/.jcheck/conf diff --git a/jaxp/.jcheck/conf b/jaxp/.jcheck/conf new file mode 100644 index 00000000000..d8227cd90e3 --- /dev/null +++ b/jaxp/.jcheck/conf @@ -0,0 +1 @@ +project=jdk7 From f7a57b1ea2cf7cb235282ea20d8a1193f4192361 Mon Sep 17 00:00:00 2001 From: Mark Reinhold Date: Fri, 29 Feb 2008 20:03:59 -0800 Subject: [PATCH 045/274] 6669216: Add jcheck configuration directories Reviewed-by: ohair, xdono --- jaxws/.jcheck/conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 jaxws/.jcheck/conf diff --git a/jaxws/.jcheck/conf b/jaxws/.jcheck/conf new file mode 100644 index 00000000000..d8227cd90e3 --- /dev/null +++ b/jaxws/.jcheck/conf @@ -0,0 +1 @@ +project=jdk7 From c426bbd074ccdb23e2bf6ffcb8429ead32898adc Mon Sep 17 00:00:00 2001 From: Mark Reinhold Date: Fri, 29 Feb 2008 20:04:03 -0800 Subject: [PATCH 046/274] 6669216: Add jcheck configuration directories Reviewed-by: ohair, xdono --- langtools/.jcheck/conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 langtools/.jcheck/conf diff --git a/langtools/.jcheck/conf b/langtools/.jcheck/conf new file mode 100644 index 00000000000..d8227cd90e3 --- /dev/null +++ b/langtools/.jcheck/conf @@ -0,0 +1 @@ +project=jdk7 From 6c0c606249d9751836d74b481d9a1e52bf0247d1 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Sun, 2 Mar 2008 16:10:12 -0800 Subject: [PATCH 047/274] 6557851: CMS: ergonomics defaults are not set with FLAG_SET_ERGO Default values set by cms ergonomics are set with FLAG_SET_DEFAULT so down stream the values look like the default values and affect how later parameters are set. Set these values with FLAG_SET_ERGO instead and adjust how later parameters are interpreted. Reviewed-by: iveresov, apetrusenko, pbk, ysr --- .../parNew/asParNewGeneration.cpp | 4 +- .../parallelScavenge/asPSYoungGen.cpp | 6 +- .../parallelScavenge/parallelScavengeHeap.cpp | 2 +- .../parallelScavenge/parallelScavengeHeap.hpp | 14 +- .../parallelScavenge/psYoungGen.cpp | 10 +- .../src/share/vm/memory/collectorPolicy.cpp | 338 ++++++++++++++---- .../src/share/vm/memory/collectorPolicy.hpp | 31 ++ hotspot/src/share/vm/runtime/arguments.cpp | 52 ++- hotspot/src/share/vm/runtime/globals.cpp | 12 + .../share/vm/runtime/globals_extension.hpp | 4 + 10 files changed, 376 insertions(+), 97 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp index 506619547d2..fa4a554b976 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp @@ -74,8 +74,8 @@ size_t ASParNewGeneration::available_to_live() const { #ifdef SHRINKS_AT_END_OF_EDEN size_t delta_in_survivor = 0; ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t space_alignment = heap->intra_generation_alignment(); - const size_t gen_alignment = heap->generation_alignment(); + const size_t space_alignment = heap->intra_heap_alignment(); + const size_t gen_alignment = heap->object_heap_alignment(); MutableSpace* space_shrinking = NULL; if (from_space()->end() > to_space()->end()) { diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp index 3d16cf68109..7ef34bb89bd 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp @@ -86,7 +86,7 @@ size_t ASPSYoungGen::available_for_contraction() { if (eden_space()->is_empty()) { // Respect the minimum size for eden and for the young gen as a whole. ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t eden_alignment = heap->intra_generation_alignment(); + const size_t eden_alignment = heap->intra_heap_alignment(); const size_t gen_alignment = heap->young_gen_alignment(); assert(eden_space()->capacity_in_bytes() >= eden_alignment, @@ -124,7 +124,7 @@ size_t ASPSYoungGen::available_for_contraction() { // to_space can be. size_t ASPSYoungGen::available_to_live() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t alignment = heap->intra_generation_alignment(); + const size_t alignment = heap->intra_heap_alignment(); // Include any space that is committed but is not in eden. size_t available = pointer_delta(eden_space()->bottom(), @@ -275,7 +275,7 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size, assert(eden_start < from_start, "Cannot push into from_space"); ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t alignment = heap->intra_generation_alignment(); + const size_t alignment = heap->intra_heap_alignment(); // Check whether from space is below to space if (from_start < to_start) { diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp index 7fde520423c..8088f0c5d0d 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @@ -173,7 +173,7 @@ jint ParallelScavengeHeap::initialize() { new PSAdaptiveSizePolicy(eden_capacity, initial_promo_size, young_gen()->to_space()->capacity_in_bytes(), - intra_generation_alignment(), + intra_heap_alignment(), max_gc_pause_sec, max_gc_minor_pause_sec, GCTimeRatio diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp index 5c1a765c215..6ea9b35f984 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp @@ -58,9 +58,9 @@ class ParallelScavengeHeap : public CollectedHeap { public: ParallelScavengeHeap() : CollectedHeap() { - set_alignment(_perm_gen_alignment, intra_generation_alignment()); - set_alignment(_young_gen_alignment, intra_generation_alignment()); - set_alignment(_old_gen_alignment, intra_generation_alignment()); + set_alignment(_perm_gen_alignment, intra_heap_alignment()); + set_alignment(_young_gen_alignment, intra_heap_alignment()); + set_alignment(_old_gen_alignment, intra_heap_alignment()); } // For use by VM operations @@ -92,14 +92,14 @@ class ParallelScavengeHeap : public CollectedHeap { void post_initialize(); void update_counters(); - // The alignment used for the various generations. size_t perm_gen_alignment() const { return _perm_gen_alignment; } size_t young_gen_alignment() const { return _young_gen_alignment; } size_t old_gen_alignment() const { return _old_gen_alignment; } - // The alignment used for eden and survivors within the young gen. - size_t intra_generation_alignment() const { return 64 * K; } + // The alignment used for eden and survivors within the young gen + // and for boundary between young gen and old gen. + size_t intra_heap_alignment() const { return 64 * K; } size_t capacity() const; size_t used() const; @@ -217,6 +217,6 @@ class ParallelScavengeHeap : public CollectedHeap { inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val) { assert(is_power_of_2((intptr_t)val), "must be a power of 2"); - var = round_to(val, intra_generation_alignment()); + var = round_to(val, intra_heap_alignment()); return var; } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp index ac7f64eaa06..b7088556bdc 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp @@ -88,7 +88,7 @@ void PSYoungGen::initialize_work() { // Compute maximum space sizes for performance counters ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - size_t alignment = heap->intra_generation_alignment(); + size_t alignment = heap->intra_heap_alignment(); size_t size = _virtual_space->reserved_size(); size_t max_survivor_size; @@ -141,7 +141,7 @@ void PSYoungGen::compute_initial_space_boundaries() { assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); // Compute sizes - size_t alignment = heap->intra_generation_alignment(); + size_t alignment = heap->intra_heap_alignment(); size_t size = _virtual_space->committed_size(); size_t survivor_size = size / InitialSurvivorRatio; @@ -192,7 +192,7 @@ void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) { #ifndef PRODUCT void PSYoungGen::space_invariants() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t alignment = heap->intra_generation_alignment(); + const size_t alignment = heap->intra_heap_alignment(); // Currently, our eden size cannot shrink to zero guarantee(eden_space()->capacity_in_bytes() >= alignment, "eden too small"); @@ -392,7 +392,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size, char* to_end = (char*)to_space()->end(); ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t alignment = heap->intra_generation_alignment(); + const size_t alignment = heap->intra_heap_alignment(); const bool maintain_minimum = (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size(); @@ -708,7 +708,7 @@ size_t PSYoungGen::available_to_min_gen() { size_t PSYoungGen::available_to_live() { size_t delta_in_survivor = 0; ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t space_alignment = heap->intra_generation_alignment(); + const size_t space_alignment = heap->intra_heap_alignment(); const size_t gen_alignment = heap->young_gen_alignment(); MutableSpace* space_shrinking = NULL; diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index de43e6aadf8..b26158e247b 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -57,45 +57,51 @@ void CollectorPolicy::initialize_size_info() { // User inputs from -mx and ms are aligned _initial_heap_byte_size = align_size_up(Arguments::initial_heap_size(), min_alignment()); - _min_heap_byte_size = align_size_up(Arguments::min_heap_size(), - min_alignment()); - _max_heap_byte_size = align_size_up(MaxHeapSize, max_alignment()); + set_min_heap_byte_size(align_size_up(Arguments::min_heap_size(), + min_alignment())); + set_max_heap_byte_size(align_size_up(MaxHeapSize, max_alignment())); // Check validity of heap parameters from launcher - if (_initial_heap_byte_size == 0) { - _initial_heap_byte_size = NewSize + OldSize; + if (initial_heap_byte_size() == 0) { + set_initial_heap_byte_size(NewSize + OldSize); } else { - Universe::check_alignment(_initial_heap_byte_size, min_alignment(), + Universe::check_alignment(initial_heap_byte_size(), min_alignment(), "initial heap"); } - if (_min_heap_byte_size == 0) { - _min_heap_byte_size = NewSize + OldSize; + if (min_heap_byte_size() == 0) { + set_min_heap_byte_size(NewSize + OldSize); } else { - Universe::check_alignment(_min_heap_byte_size, min_alignment(), + Universe::check_alignment(min_heap_byte_size(), min_alignment(), "initial heap"); } // Check heap parameter properties - if (_initial_heap_byte_size < M) { + if (initial_heap_byte_size() < M) { vm_exit_during_initialization("Too small initial heap"); } // Check heap parameter properties - if (_min_heap_byte_size < M) { + if (min_heap_byte_size() < M) { vm_exit_during_initialization("Too small minimum heap"); } - if (_initial_heap_byte_size <= NewSize) { + if (initial_heap_byte_size() <= NewSize) { // make sure there is at least some room in old space vm_exit_during_initialization("Too small initial heap for new size specified"); } - if (_max_heap_byte_size < _min_heap_byte_size) { + if (max_heap_byte_size() < min_heap_byte_size()) { vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified"); } - if (_initial_heap_byte_size < _min_heap_byte_size) { + if (initial_heap_byte_size() < min_heap_byte_size()) { vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified"); } - if (_max_heap_byte_size < _initial_heap_byte_size) { + if (max_heap_byte_size() < initial_heap_byte_size()) { vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); } + + if (PrintGCDetails && Verbose) { + gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap " + SIZE_FORMAT " Maximum heap " SIZE_FORMAT, + min_heap_byte_size(), initial_heap_byte_size(), max_heap_byte_size()); + } } void CollectorPolicy::initialize_perm_generation(PermGen::Name pgnm) { @@ -128,10 +134,26 @@ GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap, // GenCollectorPolicy methods. +size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) { + size_t x = base_size / (NewRatio+1); + size_t new_gen_size = x > min_alignment() ? + align_size_down(x, min_alignment()) : + min_alignment(); + return new_gen_size; +} + +size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size, + size_t maximum_size) { + size_t alignment = min_alignment(); + size_t max_minus = maximum_size - alignment; + return desired_size < max_minus ? desired_size : max_minus; +} + + void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, size_t init_promo_size, size_t init_survivor_size) { - double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; + const double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; _size_policy = new AdaptiveSizePolicy(init_eden_size, init_promo_size, init_survivor_size, @@ -210,74 +232,260 @@ void TwoGenerationCollectorPolicy::initialize_flags() { assert(MaxHeapSize % max_alignment() == 0, "maximum heap alignment"); } +// Values set on the command line win over any ergonomically +// set command line parameters. +// Ergonomic choice of parameters are done before this +// method is called. Values for command line parameters such as NewSize +// and MaxNewSize feed those ergonomic choices into this method. +// This method makes the final generation sizings consistent with +// themselves and with overall heap sizings. +// In the absence of explicitly set command line flags, policies +// such as the use of NewRatio are used to size the generation. void GenCollectorPolicy::initialize_size_info() { CollectorPolicy::initialize_size_info(); - // Minimum sizes of the generations may be different than - // the initial sizes. - if (!FLAG_IS_DEFAULT(NewSize)) { - _min_gen0_size = NewSize; - } else { - _min_gen0_size = align_size_down(_min_heap_byte_size / (NewRatio+1), + // min_alignment() is used for alignment within a generation. + // There is additional alignment done down stream for some + // collectors that sometimes causes unwanted rounding up of + // generations sizes. + + // Determine maximum size of gen0 + + size_t max_new_size = 0; + if (FLAG_IS_CMDLINE(MaxNewSize)) { + if (MaxNewSize < min_alignment()) { + max_new_size = min_alignment(); + } else if (MaxNewSize >= max_heap_byte_size()) { + max_new_size = align_size_down(max_heap_byte_size() - min_alignment(), min_alignment()); - // We bound the minimum size by NewSize below (since it historically + warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or " + "greater than the entire heap (" SIZE_FORMAT "k). A " + "new generation size of " SIZE_FORMAT "k will be used.", + MaxNewSize/K, max_heap_byte_size()/K, max_new_size/K); + } else { + max_new_size = align_size_down(MaxNewSize, min_alignment()); + } + + // The case for FLAG_IS_ERGO(MaxNewSize) could be treated + // specially at this point to just use an ergonomically set + // MaxNewSize to set max_new_size. For cases with small + // heaps such a policy often did not work because the MaxNewSize + // was larger than the entire heap. The interpretation given + // to ergonomically set flags is that the flags are set + // by different collectors for their own special needs but + // are not allowed to badly shape the heap. This allows the + // different collectors to decide what's best for themselves + // without having to factor in the overall heap shape. It + // can be the case in the future that the collectors would + // only make "wise" ergonomics choices and this policy could + // just accept those choices. The choices currently made are + // not always "wise". + } else { + max_new_size = scale_by_NewRatio_aligned(max_heap_byte_size()); + // Bound the maximum size by NewSize below (since it historically // would have been NewSize and because the NewRatio calculation could // yield a size that is too small) and bound it by MaxNewSize above. - // This is not always best. The NewSize calculated by CMS (which has - // a fixed minimum of 16m) can sometimes be "too" large. Consider - // the case where -Xmx32m. The CMS calculated NewSize would be about - // half the entire heap which seems too large. But the counter - // example is seen when the client defaults for NewRatio are used. - // An initial young generation size of 640k was observed - // with -Xmx128m -XX:MaxNewSize=32m when NewSize was not used - // as a lower bound as with - // _min_gen0_size = MIN2(_min_gen0_size, MaxNewSize); - // and 640k seemed too small a young generation. - _min_gen0_size = MIN2(MAX2(_min_gen0_size, NewSize), MaxNewSize); + // Ergonomics plays here by previously calculating the desired + // NewSize and MaxNewSize. + max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize); + } + assert(max_new_size > 0, "All paths should set max_new_size"); + + // Given the maximum gen0 size, determine the initial and + // minimum sizes. + + if (max_heap_byte_size() == min_heap_byte_size()) { + // The maximum and minimum heap sizes are the same so + // the generations minimum and initial must be the + // same as its maximum. + set_min_gen0_size(max_new_size); + set_initial_gen0_size(max_new_size); + set_max_gen0_size(max_new_size); + } else { + size_t desired_new_size = 0; + if (!FLAG_IS_DEFAULT(NewSize)) { + // If NewSize is set ergonomically (for example by cms), it + // would make sense to use it. If it is used, also use it + // to set the initial size. Although there is no reason + // the minimum size and the initial size have to be the same, + // the current implementation gets into trouble during the calculation + // of the tenured generation sizes if they are different. + // Note that this makes the initial size and the minimum size + // generally small compared to the NewRatio calculation. + _min_gen0_size = NewSize; + desired_new_size = NewSize; + max_new_size = MAX2(max_new_size, NewSize); + } else { + // For the case where NewSize is the default, use NewRatio + // to size the minimum and initial generation sizes. + // Use the default NewSize as the floor for these values. If + // NewRatio is overly large, the resulting sizes can be too + // small. + _min_gen0_size = MAX2(scale_by_NewRatio_aligned(min_heap_byte_size()), + NewSize); + desired_new_size = + MAX2(scale_by_NewRatio_aligned(initial_heap_byte_size()), + NewSize); + } + + assert(_min_gen0_size > 0, "Sanity check"); + set_initial_gen0_size(desired_new_size); + set_max_gen0_size(max_new_size); + + // At this point the desirable initial and minimum sizes have been + // determined without regard to the maximum sizes. + + // Bound the sizes by the corresponding overall heap sizes. + set_min_gen0_size( + bound_minus_alignment(_min_gen0_size, min_heap_byte_size())); + set_initial_gen0_size( + bound_minus_alignment(_initial_gen0_size, initial_heap_byte_size())); + set_max_gen0_size( + bound_minus_alignment(_max_gen0_size, max_heap_byte_size())); + + // At this point all three sizes have been checked against the + // maximum sizes but have not been checked for consistency + // amoung the three. + + // Final check min <= initial <= max + set_min_gen0_size(MIN2(_min_gen0_size, _max_gen0_size)); + set_initial_gen0_size( + MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size)); + set_min_gen0_size(MIN2(_min_gen0_size, _initial_gen0_size)); } - // Parameters are valid, compute area sizes. - size_t max_new_size = align_size_down(_max_heap_byte_size / (NewRatio+1), - min_alignment()); - max_new_size = MIN2(MAX2(max_new_size, _min_gen0_size), MaxNewSize); - - // desired_new_size is used to set the initial size. The - // initial size must be greater than the minimum size. - size_t desired_new_size = - align_size_down(_initial_heap_byte_size / (NewRatio+1), - min_alignment()); - - size_t new_size = MIN2(MAX2(desired_new_size, _min_gen0_size), max_new_size); - - _initial_gen0_size = new_size; - _max_gen0_size = max_new_size; + if (PrintGCDetails && Verbose) { + gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 " + SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, + min_gen0_size(), initial_gen0_size(), max_gen0_size()); + } } +// Call this method during the sizing of the gen1 to make +// adjustments to gen0 because of gen1 sizing policy. gen0 initially has +// the most freedom in sizing because it is done before the +// policy for gen1 is applied. Once gen1 policies have been applied, +// there may be conflicts in the shape of the heap and this method +// is used to make the needed adjustments. The application of the +// policies could be more sophisticated (iterative for example) but +// keeping it simple also seems a worthwhile goal. +bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr, + size_t* gen1_size_ptr, + size_t heap_size, + size_t min_gen0_size) { + bool result = false; + if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) { + if (((*gen0_size_ptr + OldSize) > heap_size) && + (heap_size - min_gen0_size) >= min_alignment()) { + // Adjust gen0 down to accomodate OldSize + *gen0_size_ptr = heap_size - min_gen0_size; + *gen0_size_ptr = + MAX2((uintx)align_size_down(*gen0_size_ptr, min_alignment()), + min_alignment()); + assert(*gen0_size_ptr > 0, "Min gen0 is too large"); + result = true; + } else { + *gen1_size_ptr = heap_size - *gen0_size_ptr; + *gen1_size_ptr = + MAX2((uintx)align_size_down(*gen1_size_ptr, min_alignment()), + min_alignment()); + } + } + return result; +} + +// Minimum sizes of the generations may be different than +// the initial sizes. An inconsistently is permitted here +// in the total size that can be specified explicitly by +// command line specification of OldSize and NewSize and +// also a command line specification of -Xms. Issue a warning +// but allow the values to pass. + void TwoGenerationCollectorPolicy::initialize_size_info() { GenCollectorPolicy::initialize_size_info(); - // Minimum sizes of the generations may be different than - // the initial sizes. An inconsistently is permitted here - // in the total size that can be specified explicitly by - // command line specification of OldSize and NewSize and - // also a command line specification of -Xms. Issue a warning - // but allow the values to pass. - if (!FLAG_IS_DEFAULT(OldSize)) { - _min_gen1_size = OldSize; + // At this point the minimum, initial and maximum sizes + // of the overall heap and of gen0 have been determined. + // The maximum gen1 size can be determined from the maximum gen0 + // and maximum heap size since not explicit flags exits + // for setting the gen1 maximum. + _max_gen1_size = max_heap_byte_size() - _max_gen0_size; + _max_gen1_size = + MAX2((uintx)align_size_down(_max_gen1_size, min_alignment()), + min_alignment()); + // If no explicit command line flag has been set for the + // gen1 size, use what is left for gen1. + if (FLAG_IS_DEFAULT(OldSize) || FLAG_IS_ERGO(OldSize)) { + // The user has not specified any value or ergonomics + // has chosen a value (which may or may not be consistent + // with the overall heap size). In either case make + // the minimum, maximum and initial sizes consistent + // with the gen0 sizes and the overall heap sizes. + assert(min_heap_byte_size() > _min_gen0_size, + "gen0 has an unexpected minimum size"); + set_min_gen1_size(min_heap_byte_size() - min_gen0_size()); + set_min_gen1_size( + MAX2((uintx)align_size_down(_min_gen1_size, min_alignment()), + min_alignment())); + set_initial_gen1_size(initial_heap_byte_size() - initial_gen0_size()); + set_initial_gen1_size( + MAX2((uintx)align_size_down(_initial_gen1_size, min_alignment()), + min_alignment())); + + } else { + // It's been explicitly set on the command line. Use the + // OldSize and then determine the consequences. + set_min_gen1_size(OldSize); + set_initial_gen1_size(OldSize); + + // If the user has explicitly set an OldSize that is inconsistent + // with other command line flags, issue a warning. // The generation minimums and the overall heap mimimum should // be within one heap alignment. - if ((_min_gen1_size + _min_gen0_size + max_alignment()) < - _min_heap_byte_size) { + if ((_min_gen1_size + _min_gen0_size + min_alignment()) < + min_heap_byte_size()) { warning("Inconsistency between minimum heap size and minimum " - "generation sizes: using min heap = " SIZE_FORMAT, - _min_heap_byte_size); + "generation sizes: using minimum heap = " SIZE_FORMAT, + min_heap_byte_size()); } - } else { - _min_gen1_size = _min_heap_byte_size - _min_gen0_size; + if ((OldSize > _max_gen1_size)) { + warning("Inconsistency between maximum heap size and maximum " + "generation sizes: using maximum heap = " SIZE_FORMAT + " -XX:OldSize flag is being ignored", + max_heap_byte_size()); } + // If there is an inconsistency between the OldSize and the minimum and/or + // initial size of gen0, since OldSize was explicitly set, OldSize wins. + if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, + min_heap_byte_size(), OldSize)) { + if (PrintGCDetails && Verbose) { + gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 " + SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, + min_gen0_size(), initial_gen0_size(), max_gen0_size()); + } + } + // Initial size + if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size, + initial_heap_byte_size(), OldSize)) { + if (PrintGCDetails && Verbose) { + gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 " + SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, + min_gen0_size(), initial_gen0_size(), max_gen0_size()); + } + } + } + // Enforce the maximum gen1 size. + set_min_gen1_size(MIN2(_min_gen1_size, _max_gen1_size)); - _initial_gen1_size = _initial_heap_byte_size - _initial_gen0_size; - _max_gen1_size = _max_heap_byte_size - _max_gen0_size; + // Check that min gen1 <= initial gen1 <= max gen1 + set_initial_gen1_size(MAX2(_initial_gen1_size, _min_gen1_size)); + set_initial_gen1_size(MIN2(_initial_gen1_size, _max_gen1_size)); + + if (PrintGCDetails && Verbose) { + gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 " + SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT, + min_gen1_size(), initial_gen1_size(), max_gen1_size()); + } } HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp index fd00a800d32..da98dfd0106 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.hpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp @@ -82,8 +82,11 @@ class CollectorPolicy : public CHeapObj { size_t max_alignment() { return _max_alignment; } size_t initial_heap_byte_size() { return _initial_heap_byte_size; } + void set_initial_heap_byte_size(size_t v) { _initial_heap_byte_size = v; } size_t max_heap_byte_size() { return _max_heap_byte_size; } + void set_max_heap_byte_size(size_t v) { _max_heap_byte_size = v; } size_t min_heap_byte_size() { return _min_heap_byte_size; } + void set_min_heap_byte_size(size_t v) { _min_heap_byte_size = v; } enum Name { CollectorPolicyKind, @@ -182,8 +185,24 @@ class GenCollectorPolicy : public CollectorPolicy { // compute max heap alignment size_t compute_max_alignment(); + // Scale the base_size by NewRation according to + // result = base_size / (NewRatio + 1) + // and align by min_alignment() + size_t scale_by_NewRatio_aligned(size_t base_size); + + // Bound the value by the given maximum minus the + // min_alignment. + size_t bound_minus_alignment(size_t desired_size, size_t maximum_size); public: + // Accessors + size_t min_gen0_size() { return _min_gen0_size; } + void set_min_gen0_size(size_t v) { _min_gen0_size = v; } + size_t initial_gen0_size() { return _initial_gen0_size; } + void set_initial_gen0_size(size_t v) { _initial_gen0_size = v; } + size_t max_gen0_size() { return _max_gen0_size; } + void set_max_gen0_size(size_t v) { _max_gen0_size = v; } + virtual int number_of_generations() = 0; virtual GenerationSpec **generations() { @@ -236,6 +255,14 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy { void initialize_generations() { ShouldNotReachHere(); } public: + // Accessors + size_t min_gen1_size() { return _min_gen1_size; } + void set_min_gen1_size(size_t v) { _min_gen1_size = v; } + size_t initial_gen1_size() { return _initial_gen1_size; } + void set_initial_gen1_size(size_t v) { _initial_gen1_size = v; } + size_t max_gen1_size() { return _max_gen1_size; } + void set_max_gen1_size(size_t v) { _max_gen1_size = v; } + // Inherited methods TwoGenerationCollectorPolicy* as_two_generation_policy() { return this; } @@ -246,6 +273,10 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy { virtual CollectorPolicy::Name kind() { return CollectorPolicy::TwoGenerationCollectorPolicyKind; } + + // Returns true is gen0 sizes were adjusted + bool adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr, + size_t heap_size, size_t min_gen1_size); }; class MarkSweepPolicy : public TwoGenerationCollectorPolicy { diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 0e631006212..c4a1c624ac6 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1000,7 +1000,7 @@ void Arguments::set_cms_and_parnew_gc_flags() { intx tenuring_default; if (CMSUseOldDefaults) { // old defaults: "old" as of 6.0 if FLAG_IS_DEFAULT(CMSYoungGenPerWorker) { - FLAG_SET_DEFAULT(CMSYoungGenPerWorker, 4*M); + FLAG_SET_ERGO(intx, CMSYoungGenPerWorker, 4*M); } young_gen_per_worker = 4*M; new_ratio = (intx)15; @@ -1025,16 +1025,20 @@ void Arguments::set_cms_and_parnew_gc_flags() { // for "short" pauses ~ 4M*ParallelGCThreads if (FLAG_IS_DEFAULT(MaxNewSize)) { // MaxNewSize not set at command-line if (!FLAG_IS_DEFAULT(NewSize)) { // NewSize explicitly set at command-line - FLAG_SET_DEFAULT(MaxNewSize, MAX2(NewSize, preferred_max_new_size)); + FLAG_SET_ERGO(uintx, MaxNewSize, MAX2(NewSize, preferred_max_new_size)); } else { - FLAG_SET_DEFAULT(MaxNewSize, preferred_max_new_size); + FLAG_SET_ERGO(uintx, MaxNewSize, preferred_max_new_size); } + if(PrintGCDetails && Verbose) { + // Too early to use gclog_or_tty + tty->print_cr("Ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize); + } } // Unless explicitly requested otherwise, prefer a large // Old to Young gen size so as to shift the collection load // to the old generation concurrent collector if (FLAG_IS_DEFAULT(NewRatio)) { - FLAG_SET_DEFAULT(NewRatio, MAX2(NewRatio, new_ratio)); + FLAG_SET_ERGO(intx, NewRatio, MAX2(NewRatio, new_ratio)); size_t min_new = align_size_up(ScaleForWordSize(min_new_default), os::vm_page_size()); size_t prev_initial_size = initial_heap_size(); @@ -1052,19 +1056,34 @@ void Arguments::set_cms_and_parnew_gc_flags() { size_t max_heap = align_size_down(MaxHeapSize, CardTableRS::ct_max_alignment_constraint()); + if(PrintGCDetails && Verbose) { + // Too early to use gclog_or_tty + tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT + " initial_heap_size: " SIZE_FORMAT + " max_heap: " SIZE_FORMAT, + min_heap_size(), initial_heap_size(), max_heap); + } if (max_heap > min_new) { // Unless explicitly requested otherwise, make young gen // at least min_new, and at most preferred_max_new_size. if (FLAG_IS_DEFAULT(NewSize)) { - FLAG_SET_DEFAULT(NewSize, MAX2(NewSize, min_new)); - FLAG_SET_DEFAULT(NewSize, MIN2(preferred_max_new_size, NewSize)); + FLAG_SET_ERGO(uintx, NewSize, MAX2(NewSize, min_new)); + FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize)); + if(PrintGCDetails && Verbose) { + // Too early to use gclog_or_tty + tty->print_cr("Ergo set NewSize: " SIZE_FORMAT, NewSize); + } } // Unless explicitly requested otherwise, size old gen // so that it's at least 3X of NewSize to begin with; // later NewRatio will decide how it grows; see above. if (FLAG_IS_DEFAULT(OldSize)) { if (max_heap > NewSize) { - FLAG_SET_DEFAULT(OldSize, MIN2(3*NewSize, max_heap - NewSize)); + FLAG_SET_ERGO(uintx, OldSize, MIN2(3*NewSize, max_heap - NewSize)); + if(PrintGCDetails && Verbose) { + // Too early to use gclog_or_tty + tty->print_cr("Ergo set OldSize: " SIZE_FORMAT, OldSize); + } } } } @@ -1073,14 +1092,14 @@ void Arguments::set_cms_and_parnew_gc_flags() { // promote all objects surviving "tenuring_default" scavenges. if (FLAG_IS_DEFAULT(MaxTenuringThreshold) && FLAG_IS_DEFAULT(SurvivorRatio)) { - FLAG_SET_DEFAULT(MaxTenuringThreshold, tenuring_default); + FLAG_SET_ERGO(intx, MaxTenuringThreshold, tenuring_default); } // If we decided above (or user explicitly requested) // `promote all' (via MaxTenuringThreshold := 0), // prefer minuscule survivor spaces so as not to waste // space for (non-existent) survivors if (FLAG_IS_DEFAULT(SurvivorRatio) && MaxTenuringThreshold == 0) { - FLAG_SET_DEFAULT(SurvivorRatio, MAX2((intx)1024, SurvivorRatio)); + FLAG_SET_ERGO(intx, SurvivorRatio, MAX2((intx)1024, SurvivorRatio)); } // If OldPLABSize is set and CMSParPromoteBlocksToClaim is not, // set CMSParPromoteBlocksToClaim equal to OldPLABSize. @@ -1089,7 +1108,11 @@ void Arguments::set_cms_and_parnew_gc_flags() { // See CR 6362902. if (!FLAG_IS_DEFAULT(OldPLABSize)) { if (FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim)) { - FLAG_SET_CMDLINE(uintx, CMSParPromoteBlocksToClaim, OldPLABSize); + // OldPLABSize is not the default value but CMSParPromoteBlocksToClaim + // is. In this situtation let CMSParPromoteBlocksToClaim follow + // the value (either from the command line or ergonomics) of + // OldPLABSize. Following OldPLABSize is an ergonomics decision. + FLAG_SET_ERGO(uintx, CMSParPromoteBlocksToClaim, OldPLABSize); } else { // OldPLABSize and CMSParPromoteBlocksToClaim are both set. @@ -1211,12 +1234,13 @@ void Arguments::set_parallel_gc_flags() { if (UseParallelOldGC) { // Par compact uses lower default values since they are treated as - // minimums. + // minimums. These are different defaults because of the different + // interpretation and are not ergonomically set. if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) { - MarkSweepDeadRatio = 1; + FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1); } if (FLAG_IS_DEFAULT(PermMarkSweepDeadRatio)) { - PermMarkSweepDeadRatio = 5; + FLAG_SET_DEFAULT(PermMarkSweepDeadRatio, 5); } } } @@ -2452,7 +2476,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) { return JNI_EINVAL; } - if (UseParallelGC) { + if (UseParallelGC || UseParallelOldGC) { // Set some flags for ParallelGC if needed. set_parallel_gc_flags(); } else if (UseConcMarkSweepGC) { diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp index 50bf7658b11..139fe1c41f5 100644 --- a/hotspot/src/share/vm/runtime/globals.cpp +++ b/hotspot/src/share/vm/runtime/globals.cpp @@ -205,6 +205,18 @@ bool CommandLineFlagsEx::is_default(CommandLineFlag flag) { return (f->origin == DEFAULT); } +bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) { + assert((size_t)flag < Flag::numFlags, "bad command line flag index"); + Flag* f = &Flag::flags[flag]; + return (f->origin == ERGONOMIC); +} + +bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) { + assert((size_t)flag < Flag::numFlags, "bad command line flag index"); + Flag* f = &Flag::flags[flag]; + return (f->origin == COMMAND_LINE); +} + bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) { Flag* result = Flag::find_flag((char*)name, strlen(name)); if (result == NULL) return false; diff --git a/hotspot/src/share/vm/runtime/globals_extension.hpp b/hotspot/src/share/vm/runtime/globals_extension.hpp index 10d22537077..d6cc1cf58d0 100644 --- a/hotspot/src/share/vm/runtime/globals_extension.hpp +++ b/hotspot/src/share/vm/runtime/globals_extension.hpp @@ -154,6 +154,8 @@ RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE, RUNTIME_PD_DEVELOP_FLAG_ } CommandLineFlagWithType; #define FLAG_IS_DEFAULT(name) (CommandLineFlagsEx::is_default(FLAG_MEMBER(name))) +#define FLAG_IS_ERGO(name) (CommandLineFlagsEx::is_ergo(FLAG_MEMBER(name))) +#define FLAG_IS_CMDLINE(name) (CommandLineFlagsEx::is_cmdline(FLAG_MEMBER(name))) #define FLAG_SET_DEFAULT(name, value) ((name) = (value)) @@ -171,4 +173,6 @@ class CommandLineFlagsEx : CommandLineFlags { static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin); static bool is_default(CommandLineFlag flag); + static bool is_ergo(CommandLineFlag flag); + static bool is_cmdline(CommandLineFlag flag); }; From 104cc8635953e92ea90fa9eeabd8b28ace693a7e Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Mon, 3 Mar 2008 10:32:38 +0100 Subject: [PATCH 048/274] 6602310: Extensions to Query API for JMX 2.0 6604768: IN queries require their arguments to be constants New JMX query language and support for dotted attributes in queries. Reviewed-by: dfuchs --- .../com/sun/jmx/mbeanserver/Introspector.java | 36 + .../classes/javax/management/AndQueryExp.java | 23 +- .../javax/management/AttributeValueExp.java | 87 +- .../javax/management/BetweenQueryExp.java | 33 +- .../javax/management/BinaryOpValueExp.java | 70 +- .../javax/management/BinaryRelQueryExp.java | 29 +- .../javax/management/BooleanValueExp.java | 6 + .../classes/javax/management/InQueryExp.java | 14 +- .../javax/management/MatchQueryExp.java | 27 +- .../classes/javax/management/NotQueryExp.java | 6 + .../javax/management/NumericValueExp.java | 17 +- .../classes/javax/management/ObjectName.java | 9 +- .../classes/javax/management/OrQueryExp.java | 22 +- .../QualifiedAttributeValueExp.java | 15 +- .../share/classes/javax/management/Query.java | 412 +++++++++- .../classes/javax/management/QueryEval.java | 2 +- .../classes/javax/management/QueryExp.java | 7 +- .../classes/javax/management/QueryParser.java | 663 +++++++++++++++ .../javax/management/StringValueExp.java | 2 +- .../javax/management/ToQueryString.java | 38 + .../javax/management/monitor/Monitor.java | 41 +- .../management/query/QueryDottedAttrTest.java | 192 +++++ .../management/query/QueryExpStringTest.java | 108 ++- .../management/query/QueryParseTest.java | 778 ++++++++++++++++++ 24 files changed, 2488 insertions(+), 149 deletions(-) create mode 100644 jdk/src/share/classes/javax/management/QueryParser.java create mode 100644 jdk/src/share/classes/javax/management/ToQueryString.java create mode 100644 jdk/test/javax/management/query/QueryDottedAttrTest.java create mode 100644 jdk/test/javax/management/query/QueryParseTest.java diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java index b68fd28ffa7..2a72f3d222f 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java @@ -43,6 +43,13 @@ import javax.management.MBeanInfo; import javax.management.NotCompliantMBeanException; import com.sun.jmx.mbeanserver.Util; +import com.sun.jmx.remote.util.EnvHelp; +import java.beans.BeanInfo; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import javax.management.AttributeNotFoundException; +import javax.management.openmbean.CompositeData; /** * This class contains the methods for performing all the tests needed to verify @@ -482,4 +489,33 @@ public class Introspector { return null; } + + public static Object elementFromComplex(Object complex, String element) + throws AttributeNotFoundException { + try { + if (complex.getClass().isArray() && element.equals("length")) { + return Array.getLength(complex); + } else if (complex instanceof CompositeData) { + return ((CompositeData) complex).get(element); + } else { + // Java Beans introspection + // + BeanInfo bi = java.beans.Introspector.getBeanInfo(complex.getClass()); + PropertyDescriptor[] pds = bi.getPropertyDescriptors(); + for (PropertyDescriptor pd : pds) + if (pd.getName().equals(element)) + return pd.getReadMethod().invoke(complex); + throw new AttributeNotFoundException( + "Could not find the getter method for the property " + + element + " using the Java Beans introspector"); + } + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } catch (AttributeNotFoundException e) { + throw e; + } catch (Exception e) { + throw EnvHelp.initCause( + new AttributeNotFoundException(e.getMessage()), e); + } + } } diff --git a/jdk/src/share/classes/javax/management/AndQueryExp.java b/jdk/src/share/classes/javax/management/AndQueryExp.java index 6f61f503f1e..9571c06779e 100644 --- a/jdk/src/share/classes/javax/management/AndQueryExp.java +++ b/jdk/src/share/classes/javax/management/AndQueryExp.java @@ -104,4 +104,25 @@ class AndQueryExp extends QueryEval implements QueryExp { return "(" + exp1 + ") and (" + exp2 + ")"; } - } + @Override + String toQueryString() { + // Parentheses are only added if needed to disambiguate. + return parens(exp1) + " and " + parens(exp2); + } + + // Add parens if needed to disambiguate an expression such as + // Query.and(Query.or(a, b), c). We need to return + // (a or b) and c + // in such a case, because + // a or b and c + // would mean + // a or (b and c) + private static String parens(QueryExp exp) { + String s = Query.toString(exp); + if (exp instanceof OrQueryExp) + return "(" + s + ")"; + else + return s; + } + +} diff --git a/jdk/src/share/classes/javax/management/AttributeValueExp.java b/jdk/src/share/classes/javax/management/AttributeValueExp.java index f520bbaf06c..d986aba7218 100644 --- a/jdk/src/share/classes/javax/management/AttributeValueExp.java +++ b/jdk/src/share/classes/javax/management/AttributeValueExp.java @@ -26,12 +26,17 @@ package javax.management; -// RI import -import javax.management.MBeanServer; +import com.sun.jmx.mbeanserver.Introspector; +import java.io.IOException; +import java.io.ObjectInputStream; /** - * Represents attributes used as arguments to relational constraints. - * An AttributeValueExp may be used anywhere a ValueExp is required. + *

Represents attributes used as arguments to relational constraints. + * Instances of this class are usually obtained using {@link Query#attr(String) + * Query.attr}.

+ * + *

An AttributeValueExp may be used anywhere a + * ValueExp is required. * * @since 1.5 */ @@ -46,6 +51,8 @@ public class AttributeValueExp implements ValueExp { */ private String attr; + private transient int dotIndex; + /** * An AttributeValueExp with a null attribute. * @deprecated An instance created with this constructor cannot be @@ -64,6 +71,18 @@ public class AttributeValueExp implements ValueExp { */ public AttributeValueExp(String attr) { this.attr = attr; + setDotIndex(); + } + + private void setDotIndex() { + if (attr != null) + dotIndex = attr.indexOf('.'); + } + + private void readObject(ObjectInputStream in) + throws ClassNotFoundException, IOException { + in.defaultReadObject(); + setDotIndex(); } /** @@ -76,7 +95,13 @@ public class AttributeValueExp implements ValueExp { } /** - * Applies the AttributeValueExp on an MBean. + *

Applies the AttributeValueExp on an MBean. + * This method calls {@link #getAttribute getAttribute(name)} and wraps + * the result as a {@code ValueExp}. The value returned by + * {@code getAttribute} must be a {@code Number}, {@code String}, + * or {@code Boolean}; otherwise this method throws a + * {@code BadAttributeValueExpException}, which will cause + * the containing query to be false for this {@code name}.

* * @param name The name of the MBean on which the AttributeValueExp will be applied. * @@ -88,6 +113,7 @@ public class AttributeValueExp implements ValueExp { * @exception BadBinaryOpValueExpException * */ + @Override public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException { Object result = getAttribute(name); @@ -106,8 +132,9 @@ public class AttributeValueExp implements ValueExp { /** * Returns the string representing its value. */ + @Override public String toString() { - return attr; + return QueryParser.quoteId(attr); } @@ -115,18 +142,38 @@ public class AttributeValueExp implements ValueExp { * Sets the MBean server on which the query is to be performed. * * @param s The MBean server on which the query is to be performed. + * + * @deprecated This method has no effect. The MBean Server used to + * obtain an attribute value is {@link QueryEval#getMBeanServer()}. */ /* There is no need for this method, because if a query is being evaluted an AttributeValueExp can only appear inside a QueryExp, and that QueryExp will itself have done setMBeanServer. */ + @Deprecated + @Override public void setMBeanServer(MBeanServer s) { } /** - * Return the value of the given attribute in the named MBean. + *

Return the value of the given attribute in the named MBean. * If the attempt to access the attribute generates an exception, - * return null. + * return null.

+ * + *

Let n be the {@linkplain #getAttributeName attribute + * name}. Then this method proceeds as follows. First it calls + * {@link MBeanServer#getAttribute getAttribute(name, n)}. If that + * generates an {@link AttributeNotFoundException}, and if n + * contains at least one dot ({@code .}), then the method calls {@code + * getAttribute(name, }n{@code .substring(0, }n{@code + * .indexOf('.')))}; in other words it calls {@code getAttribute} + * with the substring of n before the first dot. Then it + * extracts a component from the retrieved value, as described in the documentation for the {@code + * monitor} package.

+ * + *

The MBean Server used is the one returned by {@link + * QueryEval#getMBeanServer()}.

* * @param name the name of the MBean whose attribute is to be returned. * @@ -139,10 +186,34 @@ public class AttributeValueExp implements ValueExp { MBeanServer server = QueryEval.getMBeanServer(); + try { return server.getAttribute(name, attr); + } catch (AttributeNotFoundException e) { + if (dotIndex < 0) + throw e; + } + + String toGet = attr.substring(0, dotIndex); + + Object value = server.getAttribute(name, toGet); + + return extractElement(value, attr.substring(dotIndex + 1)); } catch (Exception re) { return null; } } + private Object extractElement(Object value, String elementWithDots) + throws AttributeNotFoundException { + while (true) { + int dot = elementWithDots.indexOf('.'); + String element = (dot < 0) ? + elementWithDots : elementWithDots.substring(0, dot); + value = Introspector.elementFromComplex(value, element); + if (dot < 0) + return value; + elementWithDots = elementWithDots.substring(dot + 1); + } + } + } diff --git a/jdk/src/share/classes/javax/management/BetweenQueryExp.java b/jdk/src/share/classes/javax/management/BetweenQueryExp.java index 247c6b4bab7..4079f637961 100644 --- a/jdk/src/share/classes/javax/management/BetweenQueryExp.java +++ b/jdk/src/share/classes/javax/management/BetweenQueryExp.java @@ -109,34 +109,25 @@ class BetweenQueryExp extends QueryEval implements QueryExp { ValueExp val1 = exp1.apply(name); ValueExp val2 = exp2.apply(name); ValueExp val3 = exp3.apply(name); - String sval1; - String sval2; - String sval3; - double dval1; - double dval2; - double dval3; - long lval1; - long lval2; - long lval3; boolean numeric = val1 instanceof NumericValueExp; if (numeric) { if (((NumericValueExp)val1).isLong()) { - lval1 = ((NumericValueExp)val1).longValue(); - lval2 = ((NumericValueExp)val2).longValue(); - lval3 = ((NumericValueExp)val3).longValue(); + long lval1 = ((NumericValueExp)val1).longValue(); + long lval2 = ((NumericValueExp)val2).longValue(); + long lval3 = ((NumericValueExp)val3).longValue(); return lval2 <= lval1 && lval1 <= lval3; } else { - dval1 = ((NumericValueExp)val1).doubleValue(); - dval2 = ((NumericValueExp)val2).doubleValue(); - dval3 = ((NumericValueExp)val3).doubleValue(); + double dval1 = ((NumericValueExp)val1).doubleValue(); + double dval2 = ((NumericValueExp)val2).doubleValue(); + double dval3 = ((NumericValueExp)val3).doubleValue(); return dval2 <= dval1 && dval1 <= dval3; } } else { - sval1 = ((StringValueExp)val1).toString(); - sval2 = ((StringValueExp)val2).toString(); - sval3 = ((StringValueExp)val3).toString(); + String sval1 = ((StringValueExp)val1).getValue(); + String sval2 = ((StringValueExp)val2).getValue(); + String sval3 = ((StringValueExp)val3).getValue(); return sval2.compareTo(sval1) <= 0 && sval1.compareTo(sval3) <= 0; } } @@ -148,4 +139,8 @@ class BetweenQueryExp extends QueryEval implements QueryExp { return "(" + exp1 + ") between (" + exp2 + ") and (" + exp3 + ")"; } - } + @Override + String toQueryString() { + return exp1 + " between " + exp2 + " and " + exp3; + } +} diff --git a/jdk/src/share/classes/javax/management/BinaryOpValueExp.java b/jdk/src/share/classes/javax/management/BinaryOpValueExp.java index 536f1f61566..138258b9d2a 100644 --- a/jdk/src/share/classes/javax/management/BinaryOpValueExp.java +++ b/jdk/src/share/classes/javax/management/BinaryOpValueExp.java @@ -167,12 +167,74 @@ class BinaryOpValueExp extends QueryEval implements ValueExp { */ public String toString() { try { - return exp1 + " " + opString() + " " + exp2; + return parens(exp1, true) + " " + opString() + " " + parens(exp2, false); } catch (BadBinaryOpValueExpException ex) { return "invalid expression"; } } + /* + * Add parentheses to the given subexpression if necessary to + * preserve meaning. Suppose this BinaryOpValueExp is + * Query.times(Query.plus(Query.attr("A"), Query.attr("B")), Query.attr("C")). + * Then the original toString() logic would return A + B * C. + * We check precedences in order to return (A + B) * C, which is the + * meaning of the ValueExp. + * + * We need to add parentheses if the unparenthesized expression would + * be parsed as a different ValueExp from the original. + * We cannot omit parentheses even when mathematically + * the result would be equivalent, because we do not know whether the + * numeric values will be integer or floating-point. Addition and + * multiplication are associative for integers but not always for + * floating-point. + * + * So the rule is that we omit parentheses if the ValueExp + * is (A op1 B) op2 C and the precedence of op1 is greater than or + * equal to that of op2; or if the ValueExp is A op1 (B op2 C) and + * the precedence of op2 is greater than that of op1. (There are two + * precedences: that of * and / is greater than that of + and -.) + * The case of (A op1 B) op2 (C op3 D) applies each rule in turn. + * + * The following examples show the rules in action. On the left, + * the original ValueExp. On the right, the string representation. + * + * (A + B) + C A + B + C + * (A * B) + C A * B + C + * (A + B) * C (A + B) * C + * (A * B) * C A * B * C + * A + (B + C) A + (B + C) + * A + (B * C) A + B * C + * A * (B + C) A * (B + C) + * A * (B * C) A * (B * C) + */ + private String parens(ValueExp subexp, boolean left) + throws BadBinaryOpValueExpException { + boolean omit; + if (subexp instanceof BinaryOpValueExp) { + int subop = ((BinaryOpValueExp) subexp).op; + if (left) + omit = (precedence(subop) >= precedence(op)); + else + omit = (precedence(subop) > precedence(op)); + } else + omit = true; + + if (omit) + return subexp.toString(); + else + return "(" + subexp + ")"; + } + + private int precedence(int xop) throws BadBinaryOpValueExpException { + switch (xop) { + case Query.PLUS: case Query.MINUS: return 0; + case Query.TIMES: case Query.DIV: return 1; + default: + throw new BadBinaryOpValueExpException(this); + } + } + private String opString() throws BadBinaryOpValueExpException { switch (op) { case Query.PLUS: @@ -188,4 +250,10 @@ class BinaryOpValueExp extends QueryEval implements ValueExp { throw new BadBinaryOpValueExpException(this); } + @Deprecated + public void setMBeanServer(MBeanServer s) { + super.setMBeanServer(s); + } + + } diff --git a/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java b/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java index 47809f35d9d..2e740aee2bd 100644 --- a/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java +++ b/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java @@ -108,20 +108,12 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { BadAttributeValueExpException, InvalidApplicationException { Object val1 = exp1.apply(name); Object val2 = exp2.apply(name); - String sval1; - String sval2; - double dval1; - double dval2; - long lval1; - long lval2; - boolean bval1; - boolean bval2; boolean numeric = val1 instanceof NumericValueExp; boolean bool = val1 instanceof BooleanValueExp; if (numeric) { if (((NumericValueExp)val1).isLong()) { - lval1 = ((NumericValueExp)val1).longValue(); - lval2 = ((NumericValueExp)val2).longValue(); + long lval1 = ((NumericValueExp)val1).longValue(); + long lval2 = ((NumericValueExp)val2).longValue(); switch (relOp) { case Query.GT: @@ -136,8 +128,8 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { return lval1 == lval2; } } else { - dval1 = ((NumericValueExp)val1).doubleValue(); - dval2 = ((NumericValueExp)val2).doubleValue(); + double dval1 = ((NumericValueExp)val1).doubleValue(); + double dval2 = ((NumericValueExp)val2).doubleValue(); switch (relOp) { case Query.GT: @@ -155,8 +147,8 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { } else if (bool) { - bval1 = ((BooleanValueExp)val1).getValue().booleanValue(); - bval2 = ((BooleanValueExp)val2).getValue().booleanValue(); + boolean bval1 = ((BooleanValueExp)val1).getValue().booleanValue(); + boolean bval2 = ((BooleanValueExp)val2).getValue().booleanValue(); switch (relOp) { case Query.GT: @@ -172,8 +164,8 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { } } else { - sval1 = ((StringValueExp)val1).getValue(); - sval2 = ((StringValueExp)val2).getValue(); + String sval1 = ((StringValueExp)val1).getValue(); + String sval2 = ((StringValueExp)val2).getValue(); switch (relOp) { case Query.GT: @@ -199,6 +191,11 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp { return "(" + exp1 + ") " + relOpString() + " (" + exp2 + ")"; } + @Override + String toQueryString() { + return exp1 + " " + relOpString() + " " + exp2; + } + private String relOpString() { switch (relOp) { case Query.GT: diff --git a/jdk/src/share/classes/javax/management/BooleanValueExp.java b/jdk/src/share/classes/javax/management/BooleanValueExp.java index 6dc569744cf..7a5348fd0ab 100644 --- a/jdk/src/share/classes/javax/management/BooleanValueExp.java +++ b/jdk/src/share/classes/javax/management/BooleanValueExp.java @@ -84,4 +84,10 @@ class BooleanValueExp extends QueryEval implements ValueExp { return this; } + @Deprecated + public void setMBeanServer(MBeanServer s) { + super.setMBeanServer(s); + } + + } diff --git a/jdk/src/share/classes/javax/management/InQueryExp.java b/jdk/src/share/classes/javax/management/InQueryExp.java index 01f2c503a1b..103ba3b8633 100644 --- a/jdk/src/share/classes/javax/management/InQueryExp.java +++ b/jdk/src/share/classes/javax/management/InQueryExp.java @@ -91,21 +91,23 @@ class InQueryExp extends QueryEval implements QueryExp { * @exception BadAttributeValueExpException * @exception InvalidApplicationException */ - public boolean apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, + public boolean apply(ObjectName name) + throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException { if (valueList != null) { ValueExp v = val.apply(name); boolean numeric = v instanceof NumericValueExp; - for (int i = 0; i < valueList.length; i++) { + for (ValueExp element : valueList) { + element = element.apply(name); if (numeric) { - if (((NumericValueExp)valueList[i]).doubleValue() == - ((NumericValueExp)v).doubleValue()) { + if (((NumericValueExp) element).doubleValue() == + ((NumericValueExp) v).doubleValue()) { return true; } } else { - if (((StringValueExp)valueList[i]).getValue().equals( - ((StringValueExp)v).getValue())) { + if (((StringValueExp) element).getValue().equals( + ((StringValueExp) v).getValue())) { return true; } } diff --git a/jdk/src/share/classes/javax/management/MatchQueryExp.java b/jdk/src/share/classes/javax/management/MatchQueryExp.java index 12e42769ffd..779fac1989f 100644 --- a/jdk/src/share/classes/javax/management/MatchQueryExp.java +++ b/jdk/src/share/classes/javax/management/MatchQueryExp.java @@ -113,7 +113,32 @@ class MatchQueryExp extends QueryEval implements QueryExp { } private static String likeTranslate(String s) { - return s.replace('?', '_').replace('*', '%'); + StringBuilder sb = new StringBuilder(); + int c; + for (int i = 0; i < s.length(); i += Character.charCount(c)) { + c = s.codePointAt(i); + switch (c) { + case '\\': + i += Character.charCount(c); + sb.append('\\'); + if (i < s.length()) { + c = s.codePointAt(i); + sb.appendCodePoint(c); + } + break; + case '*': + sb.append('%'); break; + case '?': + sb.append('_'); break; + case '%': + sb.append("\\%"); break; + case '_': + sb.append("\\_"); break; + default: + sb.appendCodePoint(c); break; + } + } + return sb.toString(); } /* diff --git a/jdk/src/share/classes/javax/management/NotQueryExp.java b/jdk/src/share/classes/javax/management/NotQueryExp.java index a099152012a..ef2dc57b797 100644 --- a/jdk/src/share/classes/javax/management/NotQueryExp.java +++ b/jdk/src/share/classes/javax/management/NotQueryExp.java @@ -86,8 +86,14 @@ class NotQueryExp extends QueryEval implements QueryExp { /** * Returns the string representing the object. */ + @Override public String toString() { return "not (" + exp + ")"; } + @Override + String toQueryString() { + return "not (" + Query.toString(exp) + ")"; + } + } diff --git a/jdk/src/share/classes/javax/management/NumericValueExp.java b/jdk/src/share/classes/javax/management/NumericValueExp.java index bd8da33eaab..c823a93deb4 100644 --- a/jdk/src/share/classes/javax/management/NumericValueExp.java +++ b/jdk/src/share/classes/javax/management/NumericValueExp.java @@ -151,11 +151,18 @@ class NumericValueExp extends QueryEval implements ValueExp { * Returns the string representing the object */ public String toString() { + if (val == null) + return "null"; if (val instanceof Long || val instanceof Integer) { - return String.valueOf(val.longValue()); + return Long.toString(val.longValue()); } - return String.valueOf(val.doubleValue()); + double d = val.doubleValue(); + if (Double.isInfinite(d)) + return (d > 0) ? "(1.0 / 0.0)" : "(-1.0 / 0.0)"; + if (Double.isNaN(d)) + return "(0.0 / 0.0)"; + return Double.toString(d); } /** @@ -244,4 +251,10 @@ class NumericValueExp extends QueryEval implements ValueExp { out.defaultWriteObject(); } } + + @Deprecated + public void setMBeanServer(MBeanServer s) { + super.setMBeanServer(s); + } + } diff --git a/jdk/src/share/classes/javax/management/ObjectName.java b/jdk/src/share/classes/javax/management/ObjectName.java index 8721bb62d18..cef869510b1 100644 --- a/jdk/src/share/classes/javax/management/ObjectName.java +++ b/jdk/src/share/classes/javax/management/ObjectName.java @@ -222,7 +222,8 @@ import javax.management.QueryExp; * @since 1.5 */ @SuppressWarnings("serial") // don't complain serialVersionUID not constant -public class ObjectName implements Comparable, QueryExp { +public class ObjectName extends ToQueryString + implements Comparable, QueryExp { /** * A structure recording property structure and @@ -1779,10 +1780,16 @@ public class ObjectName implements Comparable, QueryExp { * * @return a string representation of this object name. */ + @Override public String toString() { return getSerializedNameString(); } + @Override + String toQueryString() { + return "LIKE " + Query.value(toString()); + } + /** * Compares the current object name with another object name. Two * ObjectName instances are equal if and only if their canonical diff --git a/jdk/src/share/classes/javax/management/OrQueryExp.java b/jdk/src/share/classes/javax/management/OrQueryExp.java index 772a32385ae..e1ca5122f28 100644 --- a/jdk/src/share/classes/javax/management/OrQueryExp.java +++ b/jdk/src/share/classes/javax/management/OrQueryExp.java @@ -98,9 +98,29 @@ class OrQueryExp extends QueryEval implements QueryExp { } /** - * Returns a string representation of this AndQueryExp + * Returns a string representation of this OrQueryExp */ public String toString() { return "(" + exp1 + ") or (" + exp2 + ")"; } + + @Override + String toQueryString() { + return parens(exp1) + " or " + parens(exp2); + } + + // Add parentheses to avoid possible confusion. If we have an expression + // such as Query.or(Query.and(a, b), c), then we return + // (a and b) or c + // rather than just + // a and b or c + // In fact the precedence rules are such that the parentheses are not + // strictly necessary, but omitting them would be confusing. + private static String parens(QueryExp exp) { + String s = Query.toString(exp); + if (exp instanceof AndQueryExp) + return "(" + s + ")"; + else + return s; + } } diff --git a/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java b/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java index fe7ce41a012..3934d27084f 100644 --- a/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java +++ b/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java @@ -27,9 +27,11 @@ package javax.management; /** - * This class represents indexed attributes used as arguments to relational - * constraints. An QualifiedAttributeValueExp may be used anywhere a - * ValueExp is required. + *

Represents attributes used as arguments to relational constraints, + * where the attribute must be in an MBean of a specified {@linkplain + * MBeanInfo#getClassName() class}. A QualifiedAttributeValueExp may be used + * anywhere a ValueExp is required. + * * @serial include * * @since 1.5 @@ -48,7 +50,9 @@ class QualifiedAttributeValueExp extends AttributeValueExp { /** * Basic Constructor. + * @deprecated see {@link AttributeValueExp#AttributeValueExp()} */ + @Deprecated public QualifiedAttributeValueExp() { } @@ -81,6 +85,7 @@ class QualifiedAttributeValueExp extends AttributeValueExp { * @exception BadAttributeValueExpException * @exception InvalidApplicationException */ + @Override public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException, BadAttributeValueExpException, InvalidApplicationException { try { @@ -105,9 +110,11 @@ class QualifiedAttributeValueExp extends AttributeValueExp { /** * Returns the string representing its value */ + @Override public String toString() { if (className != null) { - return className + "." + super.toString(); + return QueryParser.quoteId(className) + "#" + + QueryParser.quoteId(super.toString()); } else { return super.toString(); } diff --git a/jdk/src/share/classes/javax/management/Query.java b/jdk/src/share/classes/javax/management/Query.java index 84a71da510b..d3b461da75d 100644 --- a/jdk/src/share/classes/javax/management/Query.java +++ b/jdk/src/share/classes/javax/management/Query.java @@ -27,19 +27,346 @@ package javax.management; /** - *

Constructs query object constraints. The static methods provided - * return query expressions that may be used in listing and - * enumerating MBeans. Individual constraint construction methods - * allow only appropriate types as arguments. Composition of calls can - * construct arbitrary nestings of constraints, as the following - * example illustrates:

+ *

Constructs query object constraints.

+ * + *

The MBean Server can be queried for MBeans that meet a particular + * condition, using its {@link MBeanServer#queryNames queryNames} or + * {@link MBeanServer#queryMBeans queryMBeans} method. The {@link QueryExp} + * parameter to the method can be any implementation of the interface + * {@code QueryExp}, but it is usually best to obtain the {@code QueryExp} + * value by calling the static methods in this class. This is particularly + * true when querying a remote MBean Server: a custom implementation of the + * {@code QueryExp} interface might not be present in the remote MBean Server, + * but the methods in this class return only standard classes that are + * part of the JMX implementation.

+ * + *

There are two ways to create {@code QueryExp} objects using the methods + * in this class. The first is to build them by chaining together calls to + * the various methods. The second is to use the Query Language described + * below and produce the {@code QueryExp} by calling + * {@link #fromString Query.fromString}. The two ways are equivalent: + * every {@code QueryExp} returned by {@code fromString} can also be + * constructed by chaining method calls.

+ * + *

As an example, suppose you wanted to find all MBeans where the {@code + * Enabled} attribute is {@code true} and the {@code Owner} attribute is {@code + * "Duke"}. Here is how you could construct the appropriate {@code QueryExp} by + * chaining together method calls:

* *
- * QueryExp exp = Query.and(Query.gt(Query.attr("age"),Query.value(5)),
- *                          Query.match(Query.attr("name"),
- *                                      Query.value("Smith")));
+ * QueryExp query =
+ *     Query.and(Query.eq(Query.attr("Enabled"), Query.value(true)),
+ *               Query.eq(Query.attr("Owner"), Query.value("Duke")));
  * 
* + *

Here is how you could construct the same {@code QueryExp} using the + * Query Language:

+ * + *
+ * QueryExp query = Query.fromString("Enabled = true and Owner = 'Duke'");
+ * 
+ * + *

The principal advantage of the method-chaining approach is that the + * compiler will check that the query makes sense. The principal advantage + * of the Query Language approach is that it is easier to write and especially + * read.

+ * + * + *

Query Language

+ * + *

The query language is closely modeled on the WHERE clause of + * SQL SELECT statements. The formal specification of the language + * appears below, but it is probably easier to + * understand it with examples such as the following.

+ * + *
+ *
{@code Message = 'OK'} + *
Selects MBeans that have a {@code Message} attribute whose value + * is the string {@code OK}. + * + *
{@code FreeSpacePercent < 10} + *
Selects MBeans that have a {@code FreeSpacePercent} attribute whose + * value is a number less than 10. + * + *
{@code FreeSpacePercent < 10 and WarningSent = false} + *
Selects the same MBeans as the previous example, but they must + * also have a boolean attribute {@code WarningSent} whose value + * is false. + * + *
{@code SpaceUsed > TotalSpace * (2.0 / 3.0)} + *
Selects MBeans that have {@code SpaceUsed} and {@code TotalSpace} + * attributes where the first is more than two-thirds the second. + * + *
{@code not (FreeSpacePercent between 10 and 90)} + *
Selects MBeans that have a {@code FreeSpacePercent} attribute whose + * value is not between 10 and 90, inclusive. + * + *
{@code FreeSpacePercent not between 10 and 90} + *
Another way of writing the previous query. + * + *
{@code Status in ('STOPPED', 'STARTING', 'STARTED')} + *
Selects MBeans that have a {@code Status} attribute whose value + * is one of those three strings. + * + *
{@code Message like 'OK: %'} + *
Selects MBeans that have a {@code Message} attribute whose value + * is a string beginning with {@code "OK: "}. Notice that the + * wildcard characters are SQL's ones. In the query language, + * {@code %} means "any sequence of characters" and {@code _} + * means "any single character". In the rest of the JMX API, these + * correspond to {@code *} and {@code %} respectively. + * + *
{@code instanceof 'javax.management.NotificationBroadcaster'} + *
Selects MBeans that are instances of + * {@link javax.management.NotificationBroadcaster}, as reported by + * {@link javax.management.MBeanServer#isInstanceOf MBeanServer.isInstanceOf}. + * + *
{@code like 'mydomain:*'} + *
Selects MBeans whose {@link ObjectName}s have the domain {@code mydomain}. + * + *
+ * + *

The last two examples do not correspond to valid SQL syntax, but all + * the others do.

+ * + *

The remainder of this description is a formal specification of the + * query language.

+ * + * + *

Lexical elements

+ * + *

Keywords such as and, like, and between are not + * case sensitive. You can write between, BETWEEN, or + * BeTwEeN with the same effect.

+ * + *

On the other hand, attribute names are case sensitive. The + * attribute {@code Name} is not the same as the attribute {@code name}.

+ * + *

To access an attribute whose name, ignoring case, is the same as one of + * the keywords {@code not}, {@code instanceof}, {@code like}, {@code true}, + * or {@code false}, you can use double quotes, for example {@code "not"}. + * Double quotes can also be used to include non-identifier characters in + * the name of an attribute, for example {@code "attribute-name-with-hyphens"}. + * To include the double quote character in the attribute name, write it + * twice. {@code "foo""bar""baz"} represents the attribute called + * {@code foo"bar"baz}. + * + *

String constants are written with single quotes like {@code 'this'}. A + * single quote within a string constant must be doubled, for example + * {@code 'can''t'}.

+ * + *

Integer constants are written as a sequence of decimal digits, + * optionally preceded by a plus or minus sign. An integer constant must be + * a valid input to {@link Long#valueOf(String)}.

+ * + *

Floating-point constants are written using the Java syntax. A + * floating-point constant must be a valid input to + * {@link Double#valueOf(String)}.

+ * + *

A boolean constant is either {@code true} or {@code false}, ignoring + * case.

+ * + *

Spaces cannot appear inside identifiers (unless written with double + * quotes) or keywords or multi-character tokens such as {@code <=}. Spaces can + * appear anywhere else, but are not required except to separate tokens. For + * example, the query {@code a < b and 5 = c} could also be written {@code a + * + * + *

Grammar

+ * + *
+ *
query: + *
andquery [OR query] + * + *
andquery: + *
predicate [AND andquery] + * + *
predicate: + *
( query ) |
+ * NOT predicate |
+ * INSTANCEOF stringvalue |
+ * LIKE objectnamepattern |
+ * value predrhs + * + *
predrhs: + *
compare value |
+ * [NOT] BETWEEN value AND + * value |
+ * [NOT] IN ( value + * commavalues ) |
+ * [NOT] LIKE stringvalue + * + *
commavalues: + *
[ , value commavalues ] + * + *
compare: + *
= | < | > | + * <= | >= | <> | != + * + *
value: + *
factor [plusorminus + * value] + * + *
plusorminus: + *
+ | - + * + *
factor: + *
term [timesordivide + * factor] + * + *
timesordivide: + *
* | / + * + *
term: + *
attr | literal | + * ( value ) + * + *
attr: + *
name [# name] + * + *
name: + *
identifier [.name] + * + *
identifier: + *
Java-identifier | double-quoted-identifier + * + *
literal: + *
booleanlit | longlit | + * doublelit | stringlit + * + *
booleanlit: + *
FALSE | TRUE + * + *
stringvalue: + *
stringlit + * + *
objectnamepattern: + *
stringlit + * + *
+ * + * + *

Semantics

+ * + *

The meaning of the grammar is described in the table below. + * This defines a function q that maps a string to a Java object + * such as a {@link QueryExp} or a {@link ValueExp}.

+ * + * + * + * + *
String sq(s)
query1 OR query2 + * {@link Query#or Query.or}(q(query1), q(query2)) + * + *
query1 AND query2 + * {@link Query#and Query.and}(q(query1), q(query2)) + * + *
( queryOrValue ) + * q(queryOrValue) + * + *
NOT query + * {@link Query#not Query.not}(q(query)) + * + *
INSTANCEOF stringLiteral + * {@link Query#isInstanceOf Query.isInstanceOf}({@link Query#value(String) Query.value}(q(stringLiteral))) + * + *
LIKE stringLiteral + * {@link ObjectName#ObjectName(String) new ObjectName}(q(stringLiteral)) + * + *
value1 = value2 + * {@link Query#eq Query.eq}(q(value1), q(value2)) + * + *
value1 < value2 + * {@link Query#lt Query.lt}(q(value1), q(value2)) + * + *
value1 > value2 + * {@link Query#gt Query.gt}(q(value1), q(value2)) + * + *
value1 <= value2 + * {@link Query#leq Query.leq}(q(value1), q(value2)) + * + *
value1 >= value2 + * {@link Query#geq Query.geq}(q(value1), q(value2)) + * + *
value1 <> value2 + * {@link Query#not Query.not}({@link Query#eq Query.eq}(q(value1), q(value2))) + * + *
value1 != value2 + * {@link Query#not Query.not}({@link Query#eq Query.eq}(q(value1), q(value2))) + * + *
value1 BETWEEN value2 AND value3 + * {@link Query#between Query.between}(q(value1), + * q(value2), q(value3)) + * + *
value1 NOT BETWEEN value2 AND value3 + * {@link Query#not Query.not}({@link Query#between Query.between}(q(value1), q(value2), q(value3))) + * + *
value1 IN ( value2, value3 ) + * {@link Query#in Query.in}(q(value1), + * new ValueExp[] { + * q(value2), q(value3)}) + * + *
value1 NOT IN ( value2, value3 ) + * {@link Query#not Query.not}({@link Query#in Query.in}(q(value1), + * new ValueExp[] { + * q(value2), q(value3)})) + * + *
value LIKE stringLiteral + * {@link Query#match Query.match}(q(value), + * translateWildcards(q(stringLiteral))) + * + *
value NOT LIKE stringLiteral + * {@link Query#not Query.not}({@link Query#match Query.match}(q(value), + * translateWildcards(q(stringLiteral)))) + * + *
value1 + value2 + * {@link Query#plus Query.plus}(q(value1), q(value2)) + * + *
value1 - value2 + * {@link Query#minus Query.minus}(q(value1), q(value2)) + * + *
value1 * value2 + * {@link Query#times Query.times}(q(value1), q(value2)) + * + *
value1 / value2 + * {@link Query#div Query.div}(q(value1), q(value2)) + * + *
name + * {@link Query#attr(String) Query.attr}(q(name)) + * + *
name1#name2 + * {@link Query#attr(String,String) Query.attr}(q(name1), + * q(name2)) + * + *
FALSE + * {@link Query#value(boolean) Query.value}(false) + * + *
TRUE + * {@link Query#value(boolean) Query.value}(true) + * + *
decimalLiteral + * {@link Query#value(long) Query.value}({@link Long#valueOf(String) Long.valueOf}(decimalLiteral)) + * + *
floatingPointLiteral + * {@link Query#value(double) Query.value}({@link Double#valueOf(String) Double.valueOf}(floatingPointLiteral)) + *
+ * + *

Here, translateWildcards is a function + * that translates from the SQL notation for wildcards, using {@code %} and + * {@code _}, to the JMX API notation, using {@code *} and {@code ?}. If the + * LIKE string already contains {@code *} or {@code ?}, these characters + * have their literal meanings, and will be quoted in the call to + * {@link Query#match Query.match}.

+ * * @since 1.5 */ public class Query extends Object { @@ -277,16 +604,12 @@ package javax.management; } /** - *

Returns a new attribute expression.

- * - *

Evaluating this expression for a given - * objectName includes performing {@link - * MBeanServer#getAttribute MBeanServer.getAttribute(objectName, - * name)}.

+ *

Returns a new attribute expression. See {@link AttributeValueExp} + * for a detailed description of the semantics of the expression.

* * @param name The name of the attribute. * - * @return An attribute expression for the attribute named name. + * @return An attribute expression for the attribute named {@code name}. */ public static AttributeValueExp attr(String name) { return new AttributeValueExp(name); @@ -627,6 +950,63 @@ package javax.management; return new InstanceOfQueryExp(classNameValue); } + /** + *

Return a string representation of the given query. The string + * returned by this method can be converted back into an equivalent + * query using {@link #fromString fromString}.

+ * + *

(Two queries are equivalent if they produce the same result in + * all cases. Equivalent queries are not necessarily identical: + * for example the queries {@code Query.lt(Query.attr("A"), Query.attr("B"))} + * and {@code Query.not(Query.ge(Query.attr("A"), Query.attr("B")))} are + * equivalent but not identical.)

+ * + *

The string returned by this method is only guaranteed to be converted + * back into an equivalent query if {@code query} was constructed, or + * could have been constructed, using the methods of this class. + * If you make a custom query {@code myQuery} by implementing + * {@link QueryExp} yourself then the result of + * {@code Query.toString(myQuery)} is unspecified.

+ * + * @param query the query to convert. If it is null, the result will + * also be null. + * @return the string representation of the query, or null if the + * query is null. + * + * @since 1.7 + */ + public static String toString(QueryExp query) { + if (query == null) + return null; + + if (query instanceof ToQueryString) + return ((ToQueryString) query).toQueryString(); + + return query.toString(); + } + + /** + *

Produce a query from the given string. The query returned + * by this method can be converted back into a string using + * {@link #toString(QueryExp) toString}. The resultant string will + * not necessarily be equal to {@code s}.

+ * + * @param s the string to convert. + * + * @return a {@code QueryExp} derived by parsing the string, or + * null if the string is null. + * + * @throws IllegalArgumentException if the string is not a valid + * query string. + * + * @since 1.7 + */ + public static QueryExp fromString(String s) { + if (s == null) + return null; + return new QueryParser(s).parseQuery(); + } + /** * Utility method to escape strings used with * Query.{initial|any|final}SubString() methods. diff --git a/jdk/src/share/classes/javax/management/QueryEval.java b/jdk/src/share/classes/javax/management/QueryEval.java index 05c4e38b4be..02c651c3c4c 100644 --- a/jdk/src/share/classes/javax/management/QueryEval.java +++ b/jdk/src/share/classes/javax/management/QueryEval.java @@ -38,7 +38,7 @@ import javax.management.MBeanServer; * * @since 1.5 */ -public abstract class QueryEval implements Serializable { +public abstract class QueryEval extends ToQueryString implements Serializable { /* Serial version */ private static final long serialVersionUID = 2675899265640874796L; diff --git a/jdk/src/share/classes/javax/management/QueryExp.java b/jdk/src/share/classes/javax/management/QueryExp.java index 6ac9ef6854f..217db104249 100644 --- a/jdk/src/share/classes/javax/management/QueryExp.java +++ b/jdk/src/share/classes/javax/management/QueryExp.java @@ -30,9 +30,9 @@ import java.io.Serializable; /** - *

Represents relational constraints that can be used in database - * query "where clauses". Instances of QueryExp are returned by the - * static methods of the {@link Query} class.

+ *

Represents relational constraints similar to database query "where + * clauses". Instances of QueryExp are returned by the static methods of the + * {@link Query} class.

* *

It is possible, but not * recommended, to create custom queries by implementing this @@ -40,6 +40,7 @@ import java.io.Serializable; * QueryEval} class than to implement the interface directly, so that * the {@link #setMBeanServer} method works correctly. * + * @see MBeanServer#queryNames MBeanServer.queryNames * @since 1.5 */ public interface QueryExp extends Serializable { diff --git a/jdk/src/share/classes/javax/management/QueryParser.java b/jdk/src/share/classes/javax/management/QueryParser.java new file mode 100644 index 00000000000..5e24e3bfbd3 --- /dev/null +++ b/jdk/src/share/classes/javax/management/QueryParser.java @@ -0,0 +1,663 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package javax.management; + +import java.util.ArrayList; +import java.util.Formatter; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +/** + *

Parser for JMX queries represented in an SQL-like language.

+ */ +/* + * Note that if a query starts with ( then we don't know whether it is + * a predicate or just a value that is parenthesized. So, inefficiently, + * we try to parse a predicate and if that doesn't work we try to parse + * a value. + */ +class QueryParser { + // LEXER STARTS HERE + + private static class Token { + final String string; + Token(String s) { + this.string = s; + } + + @Override + public String toString() { + return string; + } + } + + private static final Token + END = new Token(""), + LPAR = new Token("("), RPAR = new Token(")"), + COMMA = new Token(","), DOT = new Token("."), SHARP = new Token("#"), + PLUS = new Token("+"), MINUS = new Token("-"), + TIMES = new Token("*"), DIVIDE = new Token("/"), + LT = new Token("<"), GT = new Token(">"), + LE = new Token("<="), GE = new Token(">="), + NE = new Token("<>"), EQ = new Token("="), + NOT = new Id("NOT"), INSTANCEOF = new Id("INSTANCEOF"), + FALSE = new Id("FALSE"), TRUE = new Id("TRUE"), + BETWEEN = new Id("BETWEEN"), AND = new Id("AND"), + OR = new Id("OR"), IN = new Id("IN"), + LIKE = new Id("LIKE"), CLASS = new Id("CLASS"); + + // Keywords that can appear where an identifier can appear. + // If an attribute is one of these, then it must be quoted when + // converting a query into a string. + // We use a TreeSet so we can look up case-insensitively. + private static final Set idKeywords = + new TreeSet(String.CASE_INSENSITIVE_ORDER); + static { + for (Token t : new Token[] {NOT, INSTANCEOF, FALSE, TRUE, LIKE, CLASS}) + idKeywords.add(t.string); + }; + + public static String quoteId(String id) { + if (id.contains("\"") || idKeywords.contains(id)) + return '"' + id.replace("\"", "\"\"") + '"'; + else + return id; + } + + private static class Id extends Token { + Id(String id) { + super(id); + } + + // All other tokens use object identity, which means e.g. that one + // occurrence of the string constant 'x' is not the same as another. + // For identifiers, we ignore case when testing for equality so that + // for a keyword such as AND you can also spell it as "And" or "and". + // But we keep the original case of the identifier, so if it's not + // a keyword we will distinguish between the attribute Foo and the + // attribute FOO. + @Override + public boolean equals(Object o) { + return (o instanceof Id && (((Id) o).toString().equalsIgnoreCase(toString()))); + } + } + + private static class QuotedId extends Token { + QuotedId(String id) { + super(id); + } + + @Override + public String toString() { + return '"' + string.replace("\"", "\"\"") + '"'; + } + } + + private static class StringLit extends Token { + StringLit(String s) { + super(s); + } + + @Override + public String toString() { + return '\'' + string.replace("'", "''") + '\''; + } + } + + private static class LongLit extends Token { + long number; + + LongLit(long number) { + super(Long.toString(number)); + this.number = number; + } + } + + private static class DoubleLit extends Token { + double number; + + DoubleLit(double number) { + super(Double.toString(number)); + this.number = number; + } + } + + private static class Tokenizer { + private final String s; + private final int len; + private int i = 0; + + Tokenizer(String s) { + this.s = s; + this.len = s.length(); + } + + private int thisChar() { + if (i == len) + return -1; + return s.codePointAt(i); + } + + private void advance() { + i += Character.charCount(thisChar()); + } + + private int thisCharAdvance() { + int c = thisChar(); + advance(); + return c; + } + + Token nextToken() { + // In this method, c is the character we're looking at, and + // thisChar() is the character after that. Everything must + // preserve these invariants. When we return we then have + // thisChar() being the start of the following token, so + // the next call to nextToken() will begin from there. + int c; + + // Skip space + do { + if (i == len) + return null; + c = thisCharAdvance(); + } while (Character.isWhitespace(c)); + + // Now c is the first character of the token, and tokenI points + // to the character after that. + switch (c) { + case '(': return LPAR; + case ')': return RPAR; + case ',': return COMMA; + case '.': return DOT; + case '#': return SHARP; + case '*': return TIMES; + case '/': return DIVIDE; + case '=': return EQ; + case '-': return MINUS; + case '+': return PLUS; + + case '>': + if (thisChar() == '=') { + advance(); + return GE; + } else + return GT; + + case '<': + c = thisChar(); + switch (c) { + case '=': advance(); return LE; + case '>': advance(); return NE; + default: return LT; + } + + case '!': + if (thisCharAdvance() != '=') + throw new IllegalArgumentException("'!' must be followed by '='"); + return NE; + + case '"': + case '\'': { + int quote = c; + StringBuilder sb = new StringBuilder(); + while (true) { + while ((c = thisChar()) != quote) { + if (c < 0) { + throw new IllegalArgumentException( + "Unterminated string constant"); + } + sb.appendCodePoint(thisCharAdvance()); + } + advance(); + if (thisChar() == quote) { + sb.appendCodePoint(quote); + advance(); + } else + break; + } + if (quote == '\'') + return new StringLit(sb.toString()); + else + return new QuotedId(sb.toString()); + } + } + + // Is it a numeric constant? + if (Character.isDigit(c) || c == '.') { + StringBuilder sb = new StringBuilder(); + int lastc = -1; + while (true) { + sb.appendCodePoint(c); + c = Character.toLowerCase(thisChar()); + if (c == '+' || c == '-') { + if (lastc != 'e') + break; + } else if (!Character.isDigit(c) && c != '.' && c != 'e') + break; + lastc = c; + advance(); + } + String s = sb.toString(); + if (s.indexOf('.') >= 0 || s.indexOf('e') >= 0) { + double d = parseDoubleCheckOverflow(s); + return new DoubleLit(d); + } else { + // Like the Java language, we allow the numeric constant + // x where -x = Long.MIN_VALUE, even though x is not + // representable as a long (it is Long.MAX_VALUE + 1). + // Code in the parser will reject this value if it is + // not the operand of unary minus. + long l = -Long.parseLong("-" + s); + return new LongLit(l); + } + } + + // It must be an identifier. + if (!Character.isJavaIdentifierStart(c)) { + StringBuilder sb = new StringBuilder(); + Formatter f = new Formatter(sb); + f.format("Bad character: %c (%04x)", c, c); + throw new IllegalArgumentException(sb.toString()); + } + + StringBuilder id = new StringBuilder(); + while (true) { // identifier + id.appendCodePoint(c); + c = thisChar(); + if (!Character.isJavaIdentifierPart(c)) + break; + advance(); + } + + return new Id(id.toString()); + } + } + + /* Parse a double as a Java compiler would do it, throwing an exception + * if the input does not fit in a double. We assume that the input + * string is not "Infinity" and does not have a leading sign. + */ + private static double parseDoubleCheckOverflow(String s) { + double d = Double.parseDouble(s); + if (Double.isInfinite(d)) + throw new NumberFormatException("Overflow: " + s); + if (d == 0.0) { // Underflow checking is hard! CR 6604864 + String ss = s; + int e = s.indexOf('e'); // we already forced E to lowercase + if (e > 0) + ss = s.substring(0, e); + ss = ss.replace("0", "").replace(".", ""); + if (!ss.isEmpty()) + throw new NumberFormatException("Underflow: " + s); + } + return d; + } + + // PARSER STARTS HERE + + private final List tokens; + private int tokenI; + // The current token is always tokens[tokenI]. + + QueryParser(String s) { + // Construct the complete list of tokens immediately and append + // a sentinel (END). + tokens = new ArrayList(); + Tokenizer tokenizer = new Tokenizer(s); + Token t; + while ((t = tokenizer.nextToken()) != null) + tokens.add(t); + tokens.add(END); + } + + private Token current() { + return tokens.get(tokenI); + } + + // If the current token is t, then skip it and return true. + // Otherwise, return false. + private boolean skip(Token t) { + if (t.equals(current())) { + tokenI++; + return true; + } + return false; + } + + // If the current token is one of the ones in 'tokens', then skip it + // and return its index in 'tokens'. Otherwise, return -1. + private int skipOne(Token... tokens) { + for (int i = 0; i < tokens.length; i++) { + if (skip(tokens[i])) + return i; + } + return -1; + } + + // If the current token is t, then skip it and return. + // Otherwise throw an exception. + private void expect(Token t) { + if (!skip(t)) + throw new IllegalArgumentException("Expected " + t + ", found " + current()); + } + + private void next() { + tokenI++; + } + + QueryExp parseQuery() { + QueryExp qe = query(); + if (current() != END) + throw new IllegalArgumentException("Junk at end of query: " + current()); + return qe; + } + + // The remainder of this class is a classical recursive-descent parser. + // We only need to violate the recursive-descent scheme in one place, + // where parentheses make the grammar not LL(1). + + private QueryExp query() { + QueryExp lhs = andquery(); + while (skip(OR)) + lhs = Query.or(lhs, andquery()); + return lhs; + } + + private QueryExp andquery() { + QueryExp lhs = predicate(); + while (skip(AND)) + lhs = Query.and(lhs, predicate()); + return lhs; + } + + private QueryExp predicate() { + // Grammar hack. If we see a paren, it might be (query) or + // it might be (value). We try to parse (query), and if that + // fails, we parse (value). For example, if the string is + // "(2+3)*4 < 5" then we will try to parse the query + // "2+3)*4 < 5", which will fail at the ), so we'll back up to + // the paren and let value() handle it. + if (skip(LPAR)) { + int parenIndex = tokenI - 1; + try { + QueryExp qe = query(); + expect(RPAR); + return qe; + } catch (IllegalArgumentException e) { + // OK: try parsing a value + } + tokenI = parenIndex; + } + + if (skip(NOT)) + return Query.not(predicate()); + + if (skip(INSTANCEOF)) + return Query.isInstanceOf(stringvalue()); + + if (skip(LIKE)) { + StringValueExp sve = stringvalue(); + String s = sve.getValue(); + try { + return new ObjectName(s); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException( + "Bad ObjectName pattern after LIKE: '" + s + "'", e); + } + } + + ValueExp lhs = value(); + + return predrhs(lhs); + } + + // The order of elements in the following arrays is important. The code + // in predrhs depends on integer indexes. Change with caution. + private static final Token[] relations = { + EQ, LT, GT, LE, GE, NE, + // 0, 1, 2, 3, 4, 5, + }; + private static final Token[] betweenLikeIn = { + BETWEEN, LIKE, IN + // 0, 1, 2, + }; + + private QueryExp predrhs(ValueExp lhs) { + Token start = current(); // for errors + + // Look for < > = etc + int i = skipOne(relations); + if (i >= 0) { + ValueExp rhs = value(); + switch (i) { + case 0: return Query.eq(lhs, rhs); + case 1: return Query.lt(lhs, rhs); + case 2: return Query.gt(lhs, rhs); + case 3: return Query.leq(lhs, rhs); + case 4: return Query.geq(lhs, rhs); + case 5: return Query.not(Query.eq(lhs, rhs)); + // There is no Query.ne so <> is shorthand for the above. + default: + throw new AssertionError(); + } + } + + // Must be BETWEEN LIKE or IN, optionally preceded by NOT + boolean not = skip(NOT); + i = skipOne(betweenLikeIn); + if (i < 0) + throw new IllegalArgumentException("Expected relation at " + start); + + QueryExp q; + switch (i) { + case 0: { // BETWEEN + ValueExp lower = value(); + expect(AND); + ValueExp upper = value(); + q = Query.between(lhs, lower, upper); + break; + } + + case 1: { // LIKE + if (!(lhs instanceof AttributeValueExp)) { + throw new IllegalArgumentException( + "Left-hand side of LIKE must be an attribute"); + } + AttributeValueExp alhs = (AttributeValueExp) lhs; + StringValueExp sve = stringvalue(); + String s = sve.getValue(); + q = Query.match(alhs, patternValueExp(s)); + break; + } + + case 2: { // IN + expect(LPAR); + List values = new ArrayList(); + values.add(value()); + while (skip(COMMA)) + values.add(value()); + expect(RPAR); + q = Query.in(lhs, values.toArray(new ValueExp[values.size()])); + break; + } + + default: + throw new AssertionError(); + } + + if (not) + q = Query.not(q); + + return q; + } + + private ValueExp value() { + ValueExp lhs = factor(); + int i; + while ((i = skipOne(PLUS, MINUS)) >= 0) { + ValueExp rhs = factor(); + if (i == 0) + lhs = Query.plus(lhs, rhs); + else + lhs = Query.minus(lhs, rhs); + } + return lhs; + } + + private ValueExp factor() { + ValueExp lhs = term(); + int i; + while ((i = skipOne(TIMES, DIVIDE)) >= 0) { + ValueExp rhs = term(); + if (i == 0) + lhs = Query.times(lhs, rhs); + else + lhs = Query.div(lhs, rhs); + } + return lhs; + } + + private ValueExp term() { + boolean signed = false; + int sign = +1; + if (skip(PLUS)) + signed = true; + else if (skip(MINUS)) { + signed = true; sign = -1; + } + + Token t = current(); + next(); + + if (t instanceof DoubleLit) + return Query.value(sign * ((DoubleLit) t).number); + if (t instanceof LongLit) { + long n = ((LongLit) t).number; + if (n == Long.MIN_VALUE && sign != -1) + throw new IllegalArgumentException("Illegal positive integer: " + n); + return Query.value(sign * n); + } + if (signed) + throw new IllegalArgumentException("Expected number after + or -"); + + if (t == LPAR) { + ValueExp v = value(); + expect(RPAR); + return v; + } + if (t.equals(FALSE) || t.equals(TRUE)) { + return Query.value(t.equals(TRUE)); + } + if (t.equals(CLASS)) + return Query.classattr(); + + if (t instanceof StringLit) + return Query.value(t.string); // Not toString(), which would requote ' + + // At this point, all that remains is something that will call Query.attr + + if (!(t instanceof Id) && !(t instanceof QuotedId)) + throw new IllegalArgumentException("Unexpected token " + t); + + String name1 = name(t); + + if (skip(SHARP)) { + Token t2 = current(); + next(); + String name2 = name(t2); + return Query.attr(name1, name2); + } + return Query.attr(name1); + } + + // Initially, t is the first token of a supposed name and current() + // is the second. + private String name(Token t) { + StringBuilder sb = new StringBuilder(); + while (true) { + if (!(t instanceof Id) && !(t instanceof QuotedId)) + throw new IllegalArgumentException("Unexpected token " + t); + sb.append(t.string); + if (current() != DOT) + break; + sb.append('.'); + next(); + t = current(); + next(); + } + return sb.toString(); + } + + private StringValueExp stringvalue() { + // Currently the only way to get a StringValueExp when constructing + // a QueryExp is via Query.value(String), so we only recognize + // string literals here. But if we expand queries in the future + // that might no longer be true. + Token t = current(); + next(); + if (!(t instanceof StringLit)) + throw new IllegalArgumentException("Expected string: " + t); + return Query.value(t.string); + } + + // Convert the SQL pattern syntax, using % and _, to the Query.match + // syntax, using * and ?. The tricky part is recognizing \% and + // \_ as literal values, and also not replacing them inside []. + // But Query.match does not recognize \ inside [], which makes our + // job a tad easier. + private StringValueExp patternValueExp(String s) { + int c; + for (int i = 0; i < s.length(); i += Character.charCount(c)) { + c = s.codePointAt(i); + switch (c) { + case '\\': + i++; // i += Character.charCount(c), but we know it's 1! + if (i >= s.length()) + throw new IllegalArgumentException("\\ at end of pattern"); + break; + case '[': + i = s.indexOf(']', i); + if (i < 0) + throw new IllegalArgumentException("[ without ]"); + break; + case '%': + s = s.substring(0, i) + "*" + s.substring(i + 1); + break; + case '_': + s = s.substring(0, i) + "?" + s.substring(i + 1); + break; + case '*': + case '?': + s = s.substring(0, i) + '\\' + (char) c + s.substring(i + 1); + i++; + break; + } + } + return Query.value(s); + } +} diff --git a/jdk/src/share/classes/javax/management/StringValueExp.java b/jdk/src/share/classes/javax/management/StringValueExp.java index 5e5202349f5..40a9b2364d8 100644 --- a/jdk/src/share/classes/javax/management/StringValueExp.java +++ b/jdk/src/share/classes/javax/management/StringValueExp.java @@ -73,7 +73,7 @@ public class StringValueExp implements ValueExp { * Returns the string representing the object. */ public String toString() { - return "'" + val + "'"; + return "'" + val.replace("'", "''") + "'"; } diff --git a/jdk/src/share/classes/javax/management/ToQueryString.java b/jdk/src/share/classes/javax/management/ToQueryString.java new file mode 100644 index 00000000000..be73bc5f377 --- /dev/null +++ b/jdk/src/share/classes/javax/management/ToQueryString.java @@ -0,0 +1,38 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package javax.management; + +/* QueryExp classes can extend this to get non-default treatment for + * Query.toString(q). We're reluctant to change the public toString() + * methods of the classes because people might be parsing them, even + * though that's rather fragile. But Query.toString(q) has no such + * constraint so it can use the new toQueryString() method defined here. + */ +class ToQueryString { + String toQueryString() { + return toString(); + } +} diff --git a/jdk/src/share/classes/javax/management/monitor/Monitor.java b/jdk/src/share/classes/javax/management/monitor/Monitor.java index 528e8c7fd1a..5df59a7a20e 100644 --- a/jdk/src/share/classes/javax/management/monitor/Monitor.java +++ b/jdk/src/share/classes/javax/management/monitor/Monitor.java @@ -27,13 +27,8 @@ package javax.management.monitor; import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER; import com.sun.jmx.mbeanserver.GetPropertyAction; -import com.sun.jmx.remote.util.EnvHelp; -import java.beans.BeanInfo; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; +import com.sun.jmx.mbeanserver.Introspector; import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; @@ -64,7 +59,6 @@ import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; import javax.management.ReflectionException; import static javax.management.monitor.MonitorNotification.*; -import javax.management.openmbean.CompositeData; /** * Defines the part common to all monitor MBeans. @@ -876,44 +870,13 @@ public abstract class Monitor if (isComplexTypeAttribute) { Object v = value; for (String attr : remainingAttributes) - v = introspect(object, attr, v); + v = Introspector.elementFromComplex(v, attr); return (Comparable) v; } else { return (Comparable) value; } } - Object introspect(ObjectName object, - String attribute, - Object value) - throws AttributeNotFoundException { - try { - if (value.getClass().isArray() && attribute.equals("length")) { - return Array.getLength(value); - } else if (value instanceof CompositeData) { - return ((CompositeData) value).get(attribute); - } else { - // Java Beans introspection - // - BeanInfo bi = Introspector.getBeanInfo(value.getClass()); - PropertyDescriptor[] pds = bi.getPropertyDescriptors(); - for (PropertyDescriptor pd : pds) - if (pd.getName().equals(attribute)) - return pd.getReadMethod().invoke(value); - throw new AttributeNotFoundException( - "Could not find the getter method for the property " + - attribute + " using the Java Beans introspector"); - } - } catch (InvocationTargetException e) { - throw new IllegalArgumentException(e); - } catch (AttributeNotFoundException e) { - throw e; - } catch (Exception e) { - throw EnvHelp.initCause( - new AttributeNotFoundException(e.getMessage()), e); - } - } - boolean isComparableTypeValid(ObjectName object, String attribute, Comparable value) { diff --git a/jdk/test/javax/management/query/QueryDottedAttrTest.java b/jdk/test/javax/management/query/QueryDottedAttrTest.java new file mode 100644 index 00000000000..956496db9b6 --- /dev/null +++ b/jdk/test/javax/management/query/QueryDottedAttrTest.java @@ -0,0 +1,192 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 QueryDottedAttrTest + * @bug 6602310 + * @summary Test that Query.attr can understand a.b etc. + * @author Eamonn McManus + */ + +import java.beans.ConstructorProperties; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Collections; +import java.util.Set; +import javax.management.AttributeNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.QueryExp; +import javax.management.ReflectionException; +import javax.management.StandardMBean; + +public class QueryDottedAttrTest { + public static class Complex { + private final double re, im; + + @ConstructorProperties({"real", "imaginary"}) + public Complex(double re, double im) { + this.re = re; + this.im = im; + } + + public double getRe() { + return re; + } + + public double getIm() { + return im; + } + } + + public static interface Intf { + Complex getComplex(); + int[] getIntArray(); + String[] getStringArray(); + } + + public static class Impl implements Intf { + public Complex getComplex() { + return new Complex(1.0, 1.0); + } + + public int[] getIntArray() { + return new int[] {1, 2, 3}; + } + + public String[] getStringArray() { + return new String[] {"one", "two", "three"}; + } + } + + public static interface TestMBean extends Intf {} + + public static class Test extends Impl implements TestMBean {} + + public static interface TestMXBean extends Intf {} + + public static class TestMX extends Impl implements TestMXBean {} + + public static class AttrWithDot extends StandardMBean { + public AttrWithDot(Object impl, Class intf) { + super(intf.cast(impl), intf, (intf == TestMXBean.class)); + } + + public Object getAttribute(String attribute) + throws AttributeNotFoundException, MBeanException, ReflectionException { + if (attribute.equals("Complex.re")) + return 2.0; + else + return super.getAttribute(attribute); + } + } + + private static final boolean[] booleans = {false, true}; + + private static final QueryExp[] alwaysTrueQueries = { + Query.eq(Query.attr("IntArray.length"), Query.value(3)), + Query.eq(Query.attr("StringArray.length"), Query.value(3)), + Query.eq(Query.attr("Complex.im"), Query.value(1.0)), + }; + + private static final QueryExp[] alwaysFalseQueries = { + Query.eq(Query.attr("IntArray.length"), Query.value("3")), + Query.eq(Query.attr("IntArray.length"), Query.value(2)), + Query.eq(Query.attr("Complex.im"), Query.value(-1.0)), + Query.eq(Query.attr("Complex.xxx"), Query.value(0)), + }; + + private static final QueryExp[] attrWithDotTrueQueries = { + Query.eq(Query.attr("Complex.re"), Query.value(2.0)), + }; + + private static final QueryExp[] attrWithDotFalseQueries = { + Query.eq(Query.attr("Complex.re"), Query.value(1.0)), + }; + + private static String failure; + + public static void main(String[] args) throws Exception { + ObjectName name = new ObjectName("a:b=c"); + for (boolean attrWithDot : booleans) { + for (boolean mx : booleans) { + String what = + (mx ? "MXBean" : "Standard MBean") + + (attrWithDot ? " having attribute with dot in its name" : ""); + System.out.println("Testing " + what); + Class intf = mx ? TestMXBean.class : TestMBean.class; + Object impl = mx ? new TestMX() : new Test(); + if (attrWithDot) + impl = new AttrWithDot(impl, intf); + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + mbs.registerMBean(impl, name); + boolean ismx = "true".equals( + mbs.getMBeanInfo(name).getDescriptor().getFieldValue("mxbean")); + if (mx != ismx) + fail("MBean should " + (mx ? "" : "not ") + "be MXBean"); + test(mbs, name, alwaysTrueQueries, true); + test(mbs, name, alwaysFalseQueries, false); + test(mbs, name, attrWithDotTrueQueries, attrWithDot); + test(mbs, name, attrWithDotFalseQueries, !attrWithDot); + } + } + if (failure != null) + throw new Exception("TEST FAILED: " + failure); + } + + private static void test( + MBeanServer mbs, ObjectName name, QueryExp[] queries, boolean expect) + throws Exception { + for (QueryExp query : queries) { + // Serialize and deserialize the query to ensure that its + // serialization is correct + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ObjectOutputStream oout = new ObjectOutputStream(bout); + oout.writeObject(query); + oout.close(); + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream oin = new ObjectInputStream(bin); + query = (QueryExp) oin.readObject(); + Set names = mbs.queryNames(null, query); + if (names.isEmpty()) { + if (expect) + fail("Query is false but should be true: " + query); + } else if (names.equals(Collections.singleton(name))) { + if (!expect) + fail("Query is true but should be false: " + query); + } else { + fail("Query returned unexpected set: " + names); + } + } + } + + private static void fail(String msg) { + failure = msg; + System.out.println("..." + msg); + } +} diff --git a/jdk/test/javax/management/query/QueryExpStringTest.java b/jdk/test/javax/management/query/QueryExpStringTest.java index 729a8e7ec95..be6a515b8fb 100644 --- a/jdk/test/javax/management/query/QueryExpStringTest.java +++ b/jdk/test/javax/management/query/QueryExpStringTest.java @@ -31,6 +31,10 @@ * @run main QueryExpStringTest */ +// This test is mostly obsolete, since we now have Query.fromString. +// The test includes its own parser, from which Query.fromString was derived. +// The parsers are not identical and the one here is no longer maintained. + import java.util.*; import javax.management.*; @@ -39,6 +43,11 @@ public class QueryExpStringTest { private static final ValueExp attr = Query.attr("attr"), qattr = Query.attr("className", "attr"), + aa = Query.attr("A"), + bb = Query.attr("B"), + cc = Query.attr("C"), + dd = Query.attr("D"), + zero = Query.value(0), classattr = Query.classattr(), simpleString = Query.value("simpleString"), complexString = Query.value("a'b\\'\""), @@ -66,10 +75,14 @@ public class QueryExpStringTest { (StringValueExp) simpleString), initialStar = Query.initialSubString((AttributeValueExp) attr, Query.value("*")), + initialPercent = Query.initialSubString((AttributeValueExp) attr, + Query.value("%")), any = Query.anySubString((AttributeValueExp) attr, (StringValueExp) simpleString), anyStar = Query.anySubString((AttributeValueExp) attr, Query.value("*")), + anyPercent = Query.anySubString((AttributeValueExp) attr, + Query.value("%")), ffinal = Query.finalSubString((AttributeValueExp) attr, (StringValueExp) simpleString), finalMagic = Query.finalSubString((AttributeValueExp) attr, @@ -77,16 +90,20 @@ public class QueryExpStringTest { in = Query.in(intValue, new ValueExp[] {intValue, floatValue}), and = Query.and(gt, lt), or = Query.or(gt, lt), - not = Query.not(gt); + not = Query.not(gt), + aPlusB_PlusC = Query.gt(Query.plus(Query.plus(aa, bb), cc), zero), + aPlus_BPlusC = Query.gt(Query.plus(aa, Query.plus(bb, cc)), zero); // Commented-out tests below require change to implementation private static final Object tests[] = { attr, "attr", - qattr, "className.attr", +// qattr, "className.attr", +// Preceding form now appears as className#attr, an incompatible change +// which we don't mind much because nobody uses the two-arg Query.attr. classattr, "Class", simpleString, "'simpleString'", -// complexString, "'a\\'b\\\\\\'\"'", + complexString, "'a''b\\\''\"'", intValue, "12345678", integerValue, "12345678", longValue, "12345678", @@ -104,16 +121,20 @@ public class QueryExpStringTest { eq, "(12345678) = (2.5)", between, "(12345678) between (2.5) and (2.5)", match, "attr like 'simpleString'", -// initial, "attr like 'simpleString*'", -// initialStar, "attr like '\\\\**'", -// any, "attr like '*simpleString*'", -// anyStar, "attr like '*\\\\**'", -// ffinal, "attr like '*simpleString'", -// finalMagic, "attr like '*\\\\?\\\\*\\\\[\\\\\\\\'", + initial, "attr like 'simpleString%'", + initialStar, "attr like '\\*%'", + initialPercent, "attr like '\\%%'", + any, "attr like '%simpleString%'", + anyStar, "attr like '%\\*%'", + anyPercent, "attr like '%\\%%'", + ffinal, "attr like '%simpleString'", + finalMagic, "attr like '%\\?\\*\\[\\\\'", in, "12345678 in (12345678, 2.5)", and, "((12345678) > (2.5)) and ((12345678) < (2.5))", or, "((12345678) > (2.5)) or ((12345678) < (2.5))", not, "not ((12345678) > (2.5))", + aPlusB_PlusC, "(A + B + C) > (0)", +// aPlus_BPlusC, "(A + (B + C)) > (0)", }; public static void main(String[] args) throws Exception { @@ -185,7 +206,9 @@ public class QueryExpStringTest { throw new Exception("Expected types `attr like string': " + exp + " like " + pat); } - return Query.match((AttributeValueExp) exp, (StringValueExp) pat); + StringValueExp spat = (StringValueExp) pat; + spat = Query.value(translateMatch(spat.getValue())); + return Query.match((AttributeValueExp) exp, spat); } if (skip(ss, " in (")) { @@ -203,6 +226,28 @@ public class QueryExpStringTest { throw new Exception("Expected in or like after expression"); } + private static String translateMatch(String s) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { // logic not correct for wide chars + char c = s.charAt(i); + switch (c) { + case '\\': + sb.append(c).append(s.charAt(++i)); break; + case '%': + sb.append('*'); break; + case '_': + sb.append('?'); break; + case '*': + sb.append("\\*"); break; + case '?': + sb.append("\\?"); break; + default: + sb.append(c); break; + } + } + return sb.toString(); + } + private static QueryExp parseQueryAfterParen(String[] ss) throws Exception { /* This is very ugly. We might have "(q1) and (q2)" here, or @@ -229,7 +274,7 @@ public class QueryExpStringTest { ss[0] = start; ValueExp lhs = parseExp(ss); if (!skip(ss, ") ")) - throw new Exception("Expected `) ' after subexpression"); + throw new Exception("Expected `) ' after subexpression: " + ss[0]); String op = scanWord(ss); if (!skip(ss, " (")) throw new Exception("Expected ` (' after `" + op + "'"); @@ -258,15 +303,16 @@ public class QueryExpStringTest { } private static ValueExp parseExp(String[] ss) throws Exception { - final ValueExp prim = parsePrimary(ss); + ValueExp lhs = parsePrimary(ss); + while (true) { /* Look ahead to see if we have an arithmetic operator. */ String back = ss[0]; if (!skip(ss, " ")) - return prim; + return lhs; if (ss[0].equals("") || "+-*/".indexOf(ss[0].charAt(0)) < 0) { ss[0] = back; - return prim; + return lhs; } final String op = scanWord(ss); @@ -276,15 +322,16 @@ public class QueryExpStringTest { throw new Exception("Unknown arithmetic operator: " + op); if (!skip(ss, " ")) throw new Exception("Expected space after arithmetic operator"); - ValueExp rhs = parseExp(ss); + ValueExp rhs = parsePrimary(ss); switch (op.charAt(0)) { - case '+': return Query.plus(prim, rhs); - case '-': return Query.minus(prim, rhs); - case '*': return Query.times(prim, rhs); - case '/': return Query.div(prim, rhs); + case '+': lhs = Query.plus(lhs, rhs); break; + case '-': lhs = Query.minus(lhs, rhs); break; + case '*': lhs = Query.times(lhs, rhs); break; + case '/': lhs = Query.div(lhs, rhs); break; default: throw new Exception("Can't happen: " + op.charAt(0)); } } + } private static ValueExp parsePrimary(String[] ss) throws Exception { String s = ss[0]; @@ -324,14 +371,19 @@ public class QueryExpStringTest { private static String scanWord(String[] ss) throws Exception { String s = ss[0]; int space = s.indexOf(' '); - if (space < 0) { + int rpar = s.indexOf(')'); + if (space < 0 && rpar < 0) { ss[0] = ""; return s; - } else { - String word = s.substring(0, space); - ss[0] = s.substring(space); - return word; } + int stop; + if (space >= 0 && rpar >= 0) // string has both space and ), stop at first + stop = Math.min(space, rpar); + else // string has only one, stop at it + stop = Math.max(space, rpar); + String word = s.substring(0, stop); + ss[0] = s.substring(stop); + return word; } private static boolean matchWord(String[] ss, String word) @@ -381,13 +433,11 @@ public class QueryExpStringTest { for (i = 0; i < len; i++) { char c = s.charAt(i); if (c == '\'') { - ss[0] = s.substring(i + 1); + ++i; + if (i >= len || s.charAt(i) != '\'') { + ss[0] = s.substring(i); return Query.value(buf.toString()); } - if (c == '\\') { - if (++i == len) - throw new Exception("\\ at end of string"); - c = s.charAt(i); } buf.append(c); } diff --git a/jdk/test/javax/management/query/QueryParseTest.java b/jdk/test/javax/management/query/QueryParseTest.java new file mode 100644 index 00000000000..a6004b5c150 --- /dev/null +++ b/jdk/test/javax/management/query/QueryParseTest.java @@ -0,0 +1,778 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 QueryParseTest + * @bug 6602310 6604768 + * @summary Test Query.fromString and Query.toString. + * @author Eamonn McManus + */ + +import java.util.Collections; +import java.util.Set; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServer; +import javax.management.MBeanServerDelegate; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.QueryExp; + +public class QueryParseTest { + // In this table, each string constant corresponds to a test case. + // The objects following the string up to the next string are MBeans. + // Each MBean must implement ExpectedValue to return true or false + // according as it should return that value for the query parsed + // from the given string. The test will parse the string into a + // a query and verify that the MBeans return the expected value + // for that query. Then it will convert the query back into a string + // and into a second query, and check that the MBeans return the + // expected value for that query too. The reason we need to do all + // this is that the spec talks about "equivalent queries", and gives + // the implementation wide scope to rearrange queries. So we cannot + // just compare string values. + // + // We could also write an implementation-dependent test that knew what + // the strings look like, and that would have to be changed if the + // implementation changed. But the approach here is cleaner. + // + // To simplify the creation of MBeans, most use the expectTrue or + // expectFalse methods. The parameters of these methods end up in + // attributes called "A", "B", "C", etc. + private static final Object[] queryTests = { + // RELATIONS + + "A < B", + expectTrue(1, 2), expectTrue(1.0, 2.0), expectTrue("one", "two"), + expectTrue(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY), + expectFalse(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY), + expectFalse(1, 1), expectFalse(1.0, 1.0), expectFalse("one", "one"), + expectFalse(2, 1), expectFalse(2.0, 1.0), expectFalse("two", "one"), + expectFalse(Double.NaN, Double.NaN), + + "One = two", + expectTrueOneTwo(1, 1), expectTrueOneTwo(1.0, 1.0), + expectFalseOneTwo(1, 2), expectFalseOneTwo(2, 1), + + "A <= B", + expectTrue(1, 1), expectTrue(1, 2), expectTrue("one", "one"), + expectTrue("one", "two"), + expectFalse(2, 1), expectFalse("two", "one"), + expectFalse(Double.NaN, Double.NaN), + + "A >= B", + expectTrue(1, 1), expectTrue(2, 1), expectTrue("two", "one"), + expectFalse(1, 2), expectFalse("one", "two"), + + "A > B", + expectTrue(2, 1), expectTrue("two", "one"), + expectFalse(2, 2), expectFalse(1, 2), expectFalse(1.0, 2.0), + expectFalse("one", "two"), + + "A <> B", + expectTrue(1, 2), expectTrue("foo", "bar"), + expectFalse(1, 1), expectFalse("foo", "foo"), + + "A != B", + expectTrue(1, 2), expectTrue("foo", "bar"), + expectFalse(1, 1), expectFalse("foo", "foo"), + + // PARENTHESES + + "(((A))) = (B)", + expectTrue(1, 1), expectFalse(1, 2), + + "(A = B)", + expectTrue(1, 1), expectFalse(1, 2), + + "(((A = (B))))", + expectTrue(1, 1), expectFalse(1, 2), + + // INTEGER LITERALS + + "A = 1234567890123456789", + expectTrue(1234567890123456789L), expectFalse(123456789L), + + "A = +1234567890123456789", + expectTrue(1234567890123456789L), expectFalse(123456789L), + + "A = -1234567890123456789", + expectTrue(-1234567890123456789L), expectFalse(-123456789L), + + + "A = + 1234567890123456789", + expectTrue(1234567890123456789L), expectFalse(123456789L), + + "A = - 1234567890123456789", + expectTrue(-1234567890123456789L), expectFalse(-123456789L), + + "A = " + Long.MAX_VALUE, + expectTrue(Long.MAX_VALUE), expectFalse(Long.MIN_VALUE), + + "A = " + Long.MIN_VALUE, + expectTrue(Long.MIN_VALUE), expectFalse(Long.MAX_VALUE), + + // DOUBLE LITERALS + + "A = 0.0", + expectTrue(0.0), expectFalse(1.0), + + "A = 0.0e23", + expectTrue(0.0), expectFalse(1.0), + + "A = 1.2e3", + expectTrue(1.2e3), expectFalse(1.2), + + "A = +1.2", + expectTrue(1.2), expectFalse(-1.2), + + "A = 1.2e+3", + expectTrue(1.2e3), expectFalse(1.2), + + "A = 1.2e-3", + expectTrue(1.2e-3), expectFalse(1.2), + + "A = 1.2E3", + expectTrue(1.2e3), expectFalse(1.2), + + "A = -1.2e3", + expectTrue(-1.2e3), expectFalse(1.2), + + "A = " + Double.MAX_VALUE, + expectTrue(Double.MAX_VALUE), expectFalse(Double.MIN_VALUE), + + "A = " + -Double.MAX_VALUE, + expectTrue(-Double.MAX_VALUE), expectFalse(-Double.MIN_VALUE), + + "A = " + Double.MIN_VALUE, + expectTrue(Double.MIN_VALUE), expectFalse(Double.MAX_VALUE), + + "A = " + -Double.MIN_VALUE, + expectTrue(-Double.MIN_VALUE), expectFalse(-Double.MAX_VALUE), + + Query.toString( // A = Infinity -> A = (1.0/0.0) + Query.eq(Query.attr("A"), Query.value(Double.POSITIVE_INFINITY))), + expectTrue(Double.POSITIVE_INFINITY), + expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY), + + Query.toString( // A = -Infinity -> A = (-1.0/0.0) + Query.eq(Query.attr("A"), Query.value(Double.NEGATIVE_INFINITY))), + expectTrue(Double.NEGATIVE_INFINITY), + expectFalse(0.0), expectFalse(Double.POSITIVE_INFINITY), + + Query.toString( // A < NaN -> A < (0.0/0.0) + Query.lt(Query.attr("A"), Query.value(Double.NaN))), + expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY), + expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN), + + Query.toString( // A >= NaN -> A < (0.0/0.0) + Query.geq(Query.attr("A"), Query.value(Double.NaN))), + expectFalse(0.0), expectFalse(Double.NEGATIVE_INFINITY), + expectFalse(Double.POSITIVE_INFINITY), expectFalse(Double.NaN), + + // STRING LITERALS + + "A = 'blim'", + expectTrue("blim"), expectFalse("blam"), + + "A = 'can''t'", + expectTrue("can't"), expectFalse("cant"), expectFalse("can''t"), + + "A = '''blim'''", + expectTrue("'blim'"), expectFalse("'blam'"), + + "A = ''", + expectTrue(""), expectFalse((Object) null), + + // BOOLEAN LITERALS + + "A = true", + expectTrue(true), expectFalse(false), expectFalse((Object) null), + + "A = TRUE", + expectTrue(true), expectFalse(false), + + "A = TrUe", + expectTrue(true), expectFalse(false), + + "A = false", + expectTrue(false), expectFalse(true), + + "A = fAlSe", + expectTrue(false), expectFalse(true), + + "A = \"true\"", // An attribute called "true" + expectFalse(true), expectFalse(false), expectFalse("\"true\""), + newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.2}, true), + newTester(new String[] {"A", "true"}, new Object[] {2.2, 2.3}, false), + + "A = \"False\"", + expectFalse(true), expectFalse(false), expectFalse("\"False\""), + newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.2}, true), + newTester(new String[] {"A", "False"}, new Object[] {2.2, 2.3}, false), + + // ARITHMETIC + + "A + B = 10", + expectTrue(4, 6), expectFalse(3, 8), + + "A + B = 'blim'", + expectTrue("bl", "im"), expectFalse("bl", "am"), + + "A - B = 10", + expectTrue(16, 6), expectFalse(16, 3), + + "A * B = 10", + expectTrue(2, 5), expectFalse(3, 3), + + "A / B = 10", + expectTrue(70, 7), expectTrue(70.0, 7), expectFalse(70.01, 7), + + "A + B + C = 10", + expectTrue(2, 3, 5), expectFalse(2, 4, 8), + + "A+B+C=10", + expectTrue(2, 3, 5), expectFalse(2, 4, 8), + + "A + B + C + D = 10", + expectTrue(1, 2, 3, 4), expectFalse(2, 3, 4, 5), + + "A + (B + C) = 10", + expectTrue(2, 3, 5), expectFalse(2, 4, 8), + + // It is not correct to rearrange A + (B + C) as A + B + C + // (which means (A + B) + C), because of overflow. + // In particular Query.toString must not do this. + "A + (B + C) = " + Double.MAX_VALUE, // ensure no false associativity + expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, -Double.MAX_VALUE), + expectFalse(-Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE), + + "A * (B * C) < " + Double.MAX_VALUE, // same test for multiplication + expectTrue(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE), + expectFalse(Double.MIN_VALUE, Double.MAX_VALUE, Double.MAX_VALUE), + + "A * B + C = 10", + expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3), + + "A*B+C=10", + expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3), + + "(A * B) + C = 10", + expectTrue(3, 3, 1), expectTrue(2, 4, 2), expectFalse(1, 2, 3), + + "A + B * C = 10", + expectTrue(1, 3, 3), expectTrue(2, 2, 4), expectFalse(1, 2, 3), + + "A - B * C = 10", + expectTrue(16, 2, 3), expectFalse(15, 2, 2), + + "A + B / C = 10", + expectTrue(5, 15, 3), expectFalse(5, 16, 4), + + "A - B / C = 10", + expectTrue(16, 12, 2), expectFalse(15, 10, 3), + + "A * (B + C) = 10", + expectTrue(2, 2, 3), expectFalse(1, 2, 3), + + "A / (B + C) = 10", + expectTrue(70, 4, 3), expectFalse(70, 3, 5), + + "A * (B - C) = 10", + expectTrue(2, 8, 3), expectFalse(2, 3, 8), + + "A / (B - C) = 10", + expectTrue(70, 11, 4), expectFalse(70, 4, 11), + + "A / B / C = 10", + expectTrue(140, 2, 7), expectFalse(100, 5, 5), + + "A / (B / C) = 10", + expectTrue(70, 14, 2), expectFalse(70, 10, 7), + + // LOGIC + + "A = B or C = D", + expectTrue(1, 1, 2, 3), expectTrue(1, 2, 3, 3), expectTrue(1, 1, 2, 2), + expectFalse(1, 2, 3, 4), expectFalse("!", "!!", "?", "??"), + + "A = B and C = D", + expectTrue(1, 1, 2, 2), + expectFalse(1, 1, 2, 3), expectFalse(1, 2, 3, 3), + + "A = 1 and B = 2 and C = 3", + expectTrue(1, 2, 3), expectFalse(1, 2, 4), + + "A = 1 or B = 2 or C = 3", + expectTrue(1, 2, 3), expectTrue(1, 0, 0), expectTrue(0, 0, 3), + expectFalse(2, 3, 4), + + // grouped as (a and b) or (c and d) + "A = 1 AND B = 2 OR C = 3 AND D = 4", + expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4), + expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1), + + "(A = 1 AND B = 2) OR (C = 3 AND D = 4)", + expectTrue(1, 2, 3, 4), expectTrue(1, 2, 1, 2), expectTrue(3, 4, 3, 4), + expectFalse(3, 4, 1, 2), expectFalse(1, 1, 1, 1), + + "(A = 1 or B = 2) AND (C = 3 or C = 4)", + expectTrue(1, 1, 3, 3), expectTrue(2, 2, 4, 4), expectTrue(1, 2, 3, 4), + expectFalse(1, 2, 1, 2), expectFalse(3, 4, 3, 4), + + // LIKE + + "A like 'b%m'", + expectTrue("blim"), expectTrue("bm"), + expectFalse(""), expectFalse("blimmo"), expectFalse("mmm"), + + "A not like 'b%m'", + expectFalse("blim"), expectFalse("bm"), + expectTrue(""), expectTrue("blimmo"), expectTrue("mmm"), + + "A like 'b_m'", + expectTrue("bim"), expectFalse("blim"), + + "A like '%can''t%'", + expectTrue("can't"), + expectTrue("I'm sorry Dave, I'm afraid I can't do that"), + expectFalse("cant"), expectFalse("can''t"), + + "A like '\\%%\\%'", + expectTrue("%blim%"), expectTrue("%%"), + expectFalse("blim"), expectFalse("%asdf"), expectFalse("asdf%"), + + "A LIKE '*%?_'", + expectTrue("*blim?!"), expectTrue("*?_"), + expectFalse("blim"), expectFalse("blim?"), + expectFalse("?*"), expectFalse("??"), expectFalse(""), expectFalse("?"), + + Query.toString( + Query.initialSubString(Query.attr("A"), Query.value("*?%_"))), + expectTrue("*?%_tiddly"), expectTrue("*?%_"), + expectFalse("?%_tiddly"), expectFalse("*!%_"), expectFalse("*??_"), + expectFalse("*?%!"), expectFalse("*?%!tiddly"), + + Query.toString( + Query.finalSubString(Query.attr("A"), Query.value("*?%_"))), + expectTrue("tiddly*?%_"), expectTrue("*?%_"), + expectFalse("tiddly?%_"), expectFalse("*!%_"), expectFalse("*??_"), + expectFalse("*?%!"), expectFalse("tiddly*?%!"), + + // BETWEEN + + "A between B and C", + expectTrue(1, 1, 2), expectTrue(2, 1, 2), expectTrue(2, 1, 3), + expectFalse(3, 1, 2), expectFalse(0, 1, 2), expectFalse(2, 3, 1), + expectTrue(1.0, 0.0, 2.0), expectFalse(2.0, 0.0, 1.0), + expectTrue(0.0, 0.0, 0.0), expectTrue(1.0, 0.0, 1.0), + expectTrue(1.0, 0.0, Double.POSITIVE_INFINITY), + expectFalse(1.0, Double.NEGATIVE_INFINITY, 0.0), + expectFalse(false, false, true), expectFalse(true, false, true), + expectTrue("jim", "fred", "sheila"), expectFalse("fred", "jim", "sheila"), + + "A between B and C and 1+2=3", + expectTrue(2, 1, 3), expectFalse(2, 3, 1), + + "A not between B and C", + expectTrue(1, 2, 3), expectFalse(2, 1, 3), + + // IN + + "A in (1, 2, 3)", + expectTrue(1), expectTrue(2), expectTrue(3), + expectFalse(0), expectFalse(4), + + "A in (1)", + expectTrue(1), expectFalse(0), + + "A in (1.2, 3.4)", + expectTrue(1.2), expectTrue(3.4), expectFalse(0.0), + + "A in ('foo', 'bar')", + expectTrue("foo"), expectTrue("bar"), expectFalse("baz"), + + "A in ('foo', 'bar') and 'bl'+'im'='blim'", + expectTrue("foo"), expectTrue("bar"), expectFalse("baz"), + + "A in (B, C, D)", // requires fix for CR 6604768 + expectTrue(1, 1, 2, 3), expectFalse(1, 2, 3, 4), + + "A not in (B, C, D)", + expectTrue(1, 2, 3, 4), expectFalse(1, 1, 2, 3), + + // QUOTING + + "\"LIKE\" = 1 and \"NOT\" = 2 and \"INSTANCEOF\" = 3 and " + + "\"TRUE\" = 4 and \"FALSE\" = 5", + newTester( + new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"}, + new Object[] {1, 2, 3, 4, 5}, + true), + newTester( + new String[] {"LIKE", "NOT", "INSTANCEOF", "TRUE", "FALSE"}, + new Object[] {5, 4, 3, 2, 1}, + false), + + "\"\"\"woo\"\"\" = 5", + newTester(new String[] {"\"woo\""}, new Object[] {5}, true), + newTester(new String[] {"\"woo\""}, new Object[] {4}, false), + expectFalse(), + + // INSTANCEOF + + "instanceof '" + Tester.class.getName() + "'", + expectTrue(), + + "instanceof '" + String.class.getName() + "'", + expectFalse(), + + // LIKE OBJECTNAME + + // The test MBean is registered as a:b=c + "like 'a:b=c'", expectTrue(), + "like 'a:*'", expectTrue(), + "like '*:b=c'", expectTrue(), + "like 'a:b=*'", expectTrue(), + "like 'a:b=?'", expectTrue(), + "like 'd:b=c'", expectFalse(), + "like 'a:b=??*'", expectFalse(), + "like 'a:b=\"can''t\"'", expectFalse(), + + // QUALIFIED ATTRIBUTE + + Tester.class.getName() + "#A = 5", + expectTrue(5), expectFalse(4), + + Tester.class.getName() + " # A = 5", + expectTrue(5), expectFalse(4), + + Tester.class.getSuperclass().getName() + "#A = 5", + expectFalse(5), + + DynamicMBean.class.getName() + "#A = 5", + expectFalse(5), + + Tester.class.getName() + "#A = 5", + new Tester(new String[] {"A"}, new Object[] {5}, false) {}, + // note the little {} at the end which means this is a subclass + // and therefore QualifiedAttributeValue should return false. + + MBeanServerDelegate.class.getName() + "#SpecificationName LIKE '%'", + new Wrapped(new MBeanServerDelegate(), true), + new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false), + + // DOTTED ATTRIBUTE + + "A.canonicalName = '" + + MBeanServerDelegate.DELEGATE_NAME.getCanonicalName() + "'", + expectTrue(MBeanServerDelegate.DELEGATE_NAME), + expectFalse(ObjectName.WILDCARD), + + "A.class.name = 'java.lang.String'", + expectTrue("blim"), expectFalse(95), expectFalse((Object) null), + + "A.canonicalName like 'JMImpl%:%'", + expectTrue(MBeanServerDelegate.DELEGATE_NAME), + expectFalse(ObjectName.WILDCARD), + + "A.true = 'blim'", + new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true), + new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false), + + "\"A.true\" = 'blim'", + new Tester(new String[] {"A.true"}, new Object[] {"blim"}, true), + new Tester(new String[] {"A.true"}, new Object[] {"blam"}, false), + + MBeanServerDelegate.class.getName() + + "#SpecificationName.class.name = 'java.lang.String'", + new Wrapped(new MBeanServerDelegate(), true), + new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false), + + MBeanServerDelegate.class.getName() + + " # SpecificationName.class.name = 'java.lang.String'", + new Wrapped(new MBeanServerDelegate(), true), + new Tester(new String[] {"SpecificationName"}, new Object[] {"JMX"}, false), + + // CLASS + + "class = '" + Tester.class.getName() + "'", + expectTrue(), + new Wrapped(new MBeanServerDelegate(), false), + + "Class = '" + Tester.class.getName() + "'", + expectTrue(), + new Wrapped(new MBeanServerDelegate(), false), + }; + + private static final String[] incorrectQueries = { + "", " ", "25", "()", "(a = b", "a = b)", "a.3 = 5", + "a = " + Long.MAX_VALUE + "0", + "a = " + Double.MAX_VALUE + "0", + "a = " + Double.MIN_VALUE + "0", + "a = 12a5", "a = 12e5e5", "a = 12.23.34", + "a = 'can't'", "a = 'unterminated", "a = 'asdf''", + "a = \"oops", "a = \"oops\"\"", + "a like 5", "true or false", + "a ! b", "? = 3", "a = @", "a##b", + "a between b , c", "a between and c", + "a in b, c", "a in 23", "a in (2, 3", "a in (2, 3x)", + "a like \"foo\"", "a like b", "a like 23", + "like \"foo\"", "like b", "like 23", "like 'a:b'", + "5 like 'a'", "'a' like '%'", + "a not= b", "a not = b", "a not b", "a not b c", + "a = +b", "a = +'b'", "a = +true", "a = -b", "a = -'b'", + "a#5 = b", "a#'b' = c", + "a instanceof b", "a instanceof 17", "a instanceof", + "a like 'oops\\'", "a like '[oops'", + + // Check that -Long.MIN_VALUE is an illegal constant. This is one more + // than Long.MAX_VALUE and, like the Java language, we only allow it + // if it is the operand of unary minus. + "a = " + Long.toString(Long.MIN_VALUE).substring(1), + }; + + public static void main(String[] args) throws Exception { + int nexti; + String failed = null; + + System.out.println("TESTING CORRECT QUERY STRINGS"); + for (int i = 0; i < queryTests.length; i = nexti) { + for (nexti = i + 1; nexti < queryTests.length; nexti++) { + if (queryTests[nexti] instanceof String) + break; + } + if (!(queryTests[i] instanceof String)) + throw new Exception("Test bug: should be string: " + queryTests[i]); + + String qs = (String) queryTests[i]; + System.out.println("Test: " + qs); + + QueryExp qe = Query.fromString(qs); + String qes = Query.toString(qe); + System.out.println("...parses to: " + qes); + final QueryExp[] queries; + if (qes.equals(qs)) + queries = new QueryExp[] {qe}; + else { + QueryExp qe2 = Query.fromString(qes); + String qes2 = Query.toString(qe2); + System.out.println("...which parses to: " + qes2); + if (qes.equals(qes2)) + queries = new QueryExp[] {qe}; + else + queries = new QueryExp[] {qe, qe2}; + } + + for (int j = i + 1; j < nexti; j++) { + Object mbean; + if (queryTests[j] instanceof Wrapped) + mbean = ((Wrapped) queryTests[j]).mbean(); + else + mbean = queryTests[j]; + boolean expect = ((ExpectedValue) queryTests[j]).expectedValue(); + for (QueryExp qet : queries) { + boolean actual = runQuery(qet, mbean); + boolean ok = (expect == actual); + System.out.println( + "..." + mbean + " -> " + actual + + (ok ? " (OK)" : " ####INCORRECT####")); + if (!ok) + failed = qs; + } + } + } + + System.out.println(); + System.out.println("TESTING INCORRECT QUERY STRINGS"); + for (String s : incorrectQueries) { + try { + QueryExp qe = Query.fromString(s); + System.out.println("###DID NOT GET ERROR:### \"" + s + "\""); + failed = s; + } catch (IllegalArgumentException e) { + String es = (e.getClass() == IllegalArgumentException.class) ? + e.getMessage() : e.toString(); + System.out.println("OK: exception for \"" + s + "\": " + es); + } + } + + if (failed == null) + System.out.println("TEST PASSED"); + else + throw new Exception("TEST FAILED: Last failure: " + failed); + } + + private static boolean runQuery(QueryExp qe, Object mbean) + throws Exception { + MBeanServer mbs = MBeanServerFactory.newMBeanServer(); + ObjectName name = new ObjectName("a:b=c"); + mbs.registerMBean(mbean, name); + Set names = mbs.queryNames(new ObjectName("a:*"), qe); + if (names.isEmpty()) + return false; + if (names.equals(Collections.singleton(name))) + return true; + throw new Exception("Unexpected query result set: " + names); + } + + private static interface ExpectedValue { + public boolean expectedValue(); + } + + private static class Wrapped implements ExpectedValue { + private final Object mbean; + private final boolean expect; + + Wrapped(Object mbean, boolean expect) { + this.mbean = mbean; + this.expect = expect; + } + + Object mbean() { + return mbean; + } + + public boolean expectedValue() { + return expect; + } + } + + private static class Tester implements DynamicMBean, ExpectedValue { + private final AttributeList attributes; + private final boolean expectedValue; + + Tester(AttributeList attributes, boolean expectedValue) { + this.attributes = attributes; + this.expectedValue = expectedValue; + } + + Tester(String[] names, Object[] values, boolean expectedValue) { + this(makeAttributeList(names, values), expectedValue); + } + + private static AttributeList makeAttributeList( + String[] names, Object[] values) { + if (names.length != values.length) + throw new Error("Test bug: names and values different length"); + AttributeList list = new AttributeList(); + for (int i = 0; i < names.length; i++) + list.add(new Attribute(names[i], values[i])); + return list; + } + + public Object getAttribute(String attribute) + throws AttributeNotFoundException { + for (Attribute a : attributes.asList()) { + if (a.getName().equals(attribute)) + return a.getValue(); + } + throw new AttributeNotFoundException(attribute); + } + + public void setAttribute(Attribute attribute) { + throw new UnsupportedOperationException(); + } + + public AttributeList getAttributes(String[] attributes) { + AttributeList list = new AttributeList(); + for (String attribute : attributes) { + try { + list.add(new Attribute(attribute, getAttribute(attribute))); + } catch (AttributeNotFoundException e) { + // OK: ignore, per semantics of getAttributes + } + } + return list; + } + + public AttributeList setAttributes(AttributeList attributes) { + throw new UnsupportedOperationException(); + } + + public Object invoke(String actionName, Object[] params, String[] signature) { + throw new UnsupportedOperationException(); + } + + public MBeanInfo getMBeanInfo() { + MBeanAttributeInfo mbais[] = new MBeanAttributeInfo[attributes.size()]; + for (int i = 0; i < mbais.length; i++) { + Attribute attr = attributes.asList().get(i); + String name = attr.getName(); + Object value = attr.getValue(); + String type = + ((value == null) ? new Object() : value).getClass().getName(); + mbais[i] = new MBeanAttributeInfo( + name, type, name, true, false, false); + } + return new MBeanInfo( + getClass().getName(), "descr", mbais, null, null, null); + } + + public boolean expectedValue() { + return expectedValue; + } + + @Override + public String toString() { + return attributes.toString(); + } + } + + // Method rather than field, to avoid circular init dependencies + private static String[] abcd() { + return new String[] {"A", "B", "C", "D"}; + } + + private static String[] onetwo() { + return new String[] {"One", "two"}; + } + + private static Object expectTrue(Object... attrs) { + return newTester(abcd(), attrs, true); + } + + private static Object expectFalse(Object... attrs) { + return newTester(abcd(), attrs, false); + } + + private static Object expectTrueOneTwo(Object... attrs) { + return newTester(onetwo(), attrs, true); + } + + private static Object expectFalseOneTwo(Object... attrs) { + return newTester(onetwo(), attrs, false); + } + + private static Object newTester(String[] names, Object[] attrs, boolean expect) { + AttributeList list = new AttributeList(); + for (int i = 0; i < attrs.length; i++) + list.add(new Attribute(names[i], attrs[i])); + return new Tester(list, expect); + } +} From c79ec66f1a02102662783fa610b3f769574147fd Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Mon, 3 Mar 2008 12:29:42 +0100 Subject: [PATCH 049/274] 6651382: The Java JVM SNMP provider reports incorrect stats when asked for multiple OIDs The JvmMemPoolEntryImpl must use the row index when caching data. Reviewed-by: jfdenise --- .../snmp/jvminstr/JvmMemPoolEntryImpl.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java index 156813969f9..0863148f916 100644 --- a/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java +++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java @@ -26,7 +26,6 @@ package sun.management.snmp.jvminstr; // java imports // -import java.io.Serializable; import java.util.Map; // jmx imports @@ -36,9 +35,7 @@ import com.sun.jmx.snmp.SnmpDefinitions; // jdmk imports // -import com.sun.jmx.snmp.agent.SnmpMib; -import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.lang.management.MemoryType; import java.lang.management.MemoryPoolMXBean; @@ -73,7 +70,9 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { "jvmMemPoolEntry.getCollectionUsage"; final static MemoryUsage ZEROS = new MemoryUsage(0,0,0,0); - + final String entryMemoryTag; + final String entryPeakMemoryTag; + final String entryCollectMemoryTag; MemoryUsage getMemoryUsage() { try { @@ -81,17 +80,17 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { if (m != null) { final MemoryUsage cached = (MemoryUsage) - m.get(memoryTag); + m.get(entryMemoryTag); if (cached != null) { - log.debug("getMemoryUsage", - "jvmMemPoolEntry.getUsage found in cache."); + log.debug("getMemoryUsage",entryMemoryTag+ + " found in cache."); return cached; } MemoryUsage u = pool.getUsage(); if (u == null) u = ZEROS; - m.put(memoryTag,u); + m.put(entryMemoryTag,u); return u; } // Should never come here. @@ -113,18 +112,18 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { if (m != null) { final MemoryUsage cached = (MemoryUsage) - m.get(peakMemoryTag); + m.get(entryPeakMemoryTag); if (cached != null) { if (log.isDebugOn()) log.debug("getPeakMemoryUsage", - peakMemoryTag + " found in cache."); + entryPeakMemoryTag + " found in cache."); return cached; } MemoryUsage u = pool.getPeakUsage(); if (u == null) u = ZEROS; - m.put(peakMemoryTag,u); + m.put(entryPeakMemoryTag,u); return u; } // Should never come here. @@ -146,18 +145,18 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { if (m != null) { final MemoryUsage cached = (MemoryUsage) - m.get(collectMemoryTag); + m.get(entryCollectMemoryTag); if (cached != null) { if (log.isDebugOn()) log.debug("getCollectMemoryUsage", - collectMemoryTag + " found in cache."); + entryCollectMemoryTag + " found in cache."); return cached; } MemoryUsage u = pool.getCollectionUsage(); if (u == null) u = ZEROS; - m.put(collectMemoryTag,u); + m.put(entryCollectMemoryTag,u); return u; } // Should never come here. @@ -179,9 +178,12 @@ public class JvmMemPoolEntryImpl implements JvmMemPoolEntryMBean { /** * Constructor for the "JvmMemPoolEntry" group. */ - public JvmMemPoolEntryImpl(MemoryPoolMXBean mp, int index) { + public JvmMemPoolEntryImpl(MemoryPoolMXBean mp, final int index) { this.pool=mp; this.jvmMemPoolIndex = index; + this.entryMemoryTag = memoryTag + "." + index; + this.entryPeakMemoryTag = peakMemoryTag + "." + index; + this.entryCollectMemoryTag = collectMemoryTag + "." + index; } /** From 8736cd2d59fd43897d5ced19df13bd6dac97923e Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Mon, 3 Mar 2008 15:28:40 +0100 Subject: [PATCH 050/274] 6607114: Make JMXServiceURL reconstructible in MXBeans Add @ConstructorProperties tag to JMXServiceURL Reviewed-by: dfuchs --- jdk/src/share/classes/javax/management/remote/JMXServiceURL.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java index 5d5c799774e..774f21441a6 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java +++ b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java @@ -274,6 +274,7 @@ public class JMXServiceURL implements Serializable { * is not possible to find the local host name, or if * port is negative. */ + @ConstructorProperties({"protocol", "host", "port", "URLPath"}) public JMXServiceURL(String protocol, String host, int port, String urlPath) throws MalformedURLException { From 5cd758db4c9631984e20ef2fd32c27643476bad8 Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Mon, 3 Mar 2008 15:44:50 +0100 Subject: [PATCH 051/274] 6670375: Missing unit test for 6607114 (Make JMXServiceURL reconstructible) Current setup doesn't allow two pushes with same CR number Reviewed-by: dfuchs --- .../management/remote/JMXServiceURL.java | 1 + .../management/mxbean/JMXServiceURLTest.java | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 jdk/test/javax/management/mxbean/JMXServiceURLTest.java diff --git a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java index 774f21441a6..3211c902b47 100644 --- a/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java +++ b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java @@ -30,6 +30,7 @@ package javax.management.remote; import com.sun.jmx.remote.util.ClassLogger; import com.sun.jmx.remote.util.EnvHelp; +import java.beans.ConstructorProperties; import java.io.Serializable; import java.net.InetAddress; import java.net.MalformedURLException; diff --git a/jdk/test/javax/management/mxbean/JMXServiceURLTest.java b/jdk/test/javax/management/mxbean/JMXServiceURLTest.java new file mode 100644 index 00000000000..dc796037c35 --- /dev/null +++ b/jdk/test/javax/management/mxbean/JMXServiceURLTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 JMXServiceURLTest + * @bug 6607114 6670375 + * @summary Test that JMXServiceURL works correctly in MXBeans + * @author Eamonn McManus + */ + +import java.lang.management.ManagementFactory; +import javax.management.JMX; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.remote.JMXServiceURL; + +public class JMXServiceURLTest { + public static interface UrlMXBean { + public JMXServiceURL getUrl(); + public void setUrl(JMXServiceURL url); + } + + public static class UrlImpl implements UrlMXBean { + volatile JMXServiceURL url; + + public JMXServiceURL getUrl() { + return url; + } + + public void setUrl(JMXServiceURL url) { + this.url = url; + } + } + + public static void main(String[] args) throws Exception { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + ObjectName name = new ObjectName("a:b=c"); + UrlImpl urlImpl = new UrlImpl(); + mbs.registerMBean(urlImpl, name); + + JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://host:8000/noddy"); + UrlMXBean proxy = JMX.newMXBeanProxy(mbs, name, UrlMXBean.class); + proxy.setUrl(url); + assertEquals(url, urlImpl.url); + JMXServiceURL url2 = proxy.getUrl(); + assertEquals(url, url2); + + CompositeData cd = (CompositeData) mbs.getAttribute(name, "Url"); + CompositeType ct = cd.getCompositeType(); + // Make sure it looks like what we expect. This will have to be + // changed if ever we add new properties to CompositeType. In that + // case this test should also check interoperability between the + // current version and the new version. + assertEquals(4, ct.keySet().size()); + Object[][] expectedItems = { + {"protocol", SimpleType.STRING, "rmi"}, + {"host", SimpleType.STRING, "host"}, + {"port", SimpleType.INTEGER, 8000}, + {"URLPath", SimpleType.STRING, "/noddy"}, + }; + for (Object[] expectedItem : expectedItems) { + String itemName = (String) expectedItem[0]; + OpenType expectedType = (OpenType) expectedItem[1]; + Object expectedValue = expectedItem[2]; + OpenType actualType = ct.getType(itemName); + assertEquals(expectedType, actualType); + Object actualValue = cd.get(itemName); + assertEquals(expectedValue, actualValue); + } + } + + private static void assertEquals(Object expect, Object actual) + throws Exception { + if (expect.equals(actual)) + System.out.println("Equal: " + expect); + else + throw new Exception("Expected " + expect + ", got " + actual); + } +} From 702926ba5566303ca2b0ba36937c900af22a06d0 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Mon, 3 Mar 2008 16:03:53 +0000 Subject: [PATCH 052/274] 6614974: javac successfully compiles code that throws java.lang.VerifyError when run Synthetic cast missing when translating autoboxing expressions Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Lower.java | 1 + .../test/tools/javac/boxing/T6614974.java | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 langtools/test/tools/javac/boxing/T6614974.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java index 0fdbbd40c26..6dc06546ed5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java @@ -1835,6 +1835,7 @@ public class Lower extends TreeTranslator { + "" + rval.hashCode()), type, currentMethodSym); + rval = convert(rval,type); JCVariableDecl def = make.VarDef(var, (JCExpression)rval); // XXX cast JCTree built = builder.build(make.Ident(var)); JCTree res = make.LetExpr(def, built); diff --git a/langtools/test/tools/javac/boxing/T6614974.java b/langtools/test/tools/javac/boxing/T6614974.java new file mode 100644 index 00000000000..a2da7c88fb6 --- /dev/null +++ b/langtools/test/tools/javac/boxing/T6614974.java @@ -0,0 +1,43 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6614974 + * @summary javac successfully compiles code that throws java.lang.VerifyError when run + * @author mcimadamore + */ +public class T6614974 { + + private T n; + + public void error() { + T6614974 val = new T6614974(); + val.n = 0; + Integer.toString(val.n++); + } + + public static void main(String[] args) { + T6614974.class.getMethods(); + } +} From 59cc274f16e67c317fbf2c1dc6750ea2e54f018b Mon Sep 17 00:00:00 2001 From: Steve Bohne Date: Mon, 3 Mar 2008 14:47:02 -0500 Subject: [PATCH 053/274] 6655385: Disable frame pointer omission in jvm.dll on Windows for better crash logs Add /Oy- C++ compiler option on Windows Reviewed-by: phh, never, ysr --- hotspot/build/windows/makefiles/compile.make | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/hotspot/build/windows/makefiles/compile.make b/hotspot/build/windows/makefiles/compile.make index 6bc4ed1ddce..7292774e1b5 100644 --- a/hotspot/build/windows/makefiles/compile.make +++ b/hotspot/build/windows/makefiles/compile.make @@ -44,6 +44,10 @@ CPP=cl.exe # /Od Disable all optimizations # # NOTE: Normally following any of the above with a '-' will turn off that flag +# +# 6655385: For VS2003/2005 we now specify /Oy- (disable frame pointer +# omission.) This has little to no effect on performance while vastly +# improving the quality of crash log stack traces involving jvm.dll. # These are always used in all compiles CPP_FLAGS=/nologo /W3 /WX @@ -141,14 +145,14 @@ DEBUG_OPT_OPTION = /Od !endif !if "$(COMPILER_NAME)" == "VS2003" -PRODUCT_OPT_OPTION = /O2 -FASTDEBUG_OPT_OPTION = /O2 +PRODUCT_OPT_OPTION = /O2 /Oy- +FASTDEBUG_OPT_OPTION = /O2 /Oy- DEBUG_OPT_OPTION = /Od !endif !if "$(COMPILER_NAME)" == "VS2005" -PRODUCT_OPT_OPTION = /O2 -FASTDEBUG_OPT_OPTION = /O2 +PRODUCT_OPT_OPTION = /O2 /Oy- +FASTDEBUG_OPT_OPTION = /O2 /Oy- DEBUG_OPT_OPTION = /Od GX_OPTION = /EHsc # This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib @@ -165,8 +169,8 @@ CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE # Compile for space above time. !if "$(Variant)" == "kernel" -PRODUCT_OPT_OPTION = /O1 -FASTDEBUG_OPT_OPTION = /O1 +PRODUCT_OPT_OPTION = /O1 /Oy- +FASTDEBUG_OPT_OPTION = /O1 /Oy- DEBUG_OPT_OPTION = /Od !endif From 9e5259f79285521737e67792da587460f5e8f4b9 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 4 Mar 2008 12:14:13 +0000 Subject: [PATCH 054/274] 6611449: Internal Error thrown during generic method/constructor invocation Type-inference should fail since lub is not defined for primitive types Reviewed-by: jjg --- .../com/sun/tools/javac/code/Types.java | 2 +- .../com/sun/tools/javac/comp/Infer.java | 6 +-- .../generics/inference/6611449/T6611449.java | 46 +++++++++++++++++++ .../generics/inference/6611449/T6611449.out | 5 ++ 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/javac/generics/inference/6611449/T6611449.java create mode 100644 langtools/test/tools/javac/generics/inference/6611449/T6611449.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 7a6498c7884..070bf9d541f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -2483,7 +2483,7 @@ public class Types { break; default: if (t.isPrimitive()) - return syms.botType; + return syms.errType; } } switch (boundkind) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 54c3714783d..071d2fc60f2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -194,14 +194,14 @@ public class Infer { if (that.lobounds.isEmpty()) that.inst = syms.botType; else if (that.lobounds.tail.isEmpty()) - that.inst = that.lobounds.head; + that.inst = that.lobounds.head.isPrimitive() ? syms.errType : that.lobounds.head; else { that.inst = types.lub(that.lobounds); - if (that.inst == null) + } + if (that.inst == null || that.inst == syms.errType) throw ambiguousNoInstanceException .setMessage("no.unique.minimal.instance.exists", that.qtype, that.lobounds); - } // VGJ: sort of inlined maximizeInst() below. Adding // bounds can cause lobounds that are above hibounds. if (that.hibounds.isEmpty()) diff --git a/langtools/test/tools/javac/generics/inference/6611449/T6611449.java b/langtools/test/tools/javac/generics/inference/6611449/T6611449.java new file mode 100644 index 00000000000..8f2378e1d5b --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.java @@ -0,0 +1,46 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6611449 + * @summary Internal Error thrown during generic method/constructor invocation + * @compile/fail/ref=T6611449.out -XDstdout -XDrawDiagnostics T6611449.java + */ +public class T6611449 { + + T6611449() {this(1);} + + T6611449(T t1) {this(t1, 1);} + + T6611449(T t1, T t2) {} + + void m(T t1) {} + + void m(T t1, T t2) {} + + void test() { + m1(1); + m2(1, 1); + } +} diff --git a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out new file mode 100644 index 00000000000..ed501cb48d6 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out @@ -0,0 +1,5 @@ +T6611449.java:32:17: compiler.err.cant.resolve.location: (- compiler.misc.kindname.constructor), T6611449, (int), , (- compiler.misc.kindname.class), T6611449 +T6611449.java:34:35: compiler.err.cant.resolve.location: (- compiler.misc.kindname.constructor), T6611449, (T,int), , (- compiler.misc.kindname.class), T6611449 +T6611449.java:43:9: compiler.err.cant.resolve.location: (- compiler.misc.kindname.method), m1, (int), , (- compiler.misc.kindname.class), T6611449 +T6611449.java:44:9: compiler.err.cant.resolve.location: (- compiler.misc.kindname.method), m2, (int,int), , (- compiler.misc.kindname.class), T6611449 +4 errors From 00c56207401b2c408ac63b1d6b7f8b52102f62c1 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 4 Mar 2008 13:00:08 +0000 Subject: [PATCH 055/274] 6660289: declared bound in inner class referring a type variable of the outer class NPE caused by a defect in type-variable attribution Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Attr.java | 10 +++--- .../test/tools/javac/generics/T6660289.java | 34 +++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 langtools/test/tools/javac/generics/T6660289.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 385ce3c6d6e..b754ae11511 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -465,12 +465,12 @@ public class Attr extends JCTree.Visitor { types.setBounds(a, List.of(syms.objectType)); } } + } + + void attribBounds(List typarams, Env env) { for (JCTypeParameter tvar : typarams) chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type); attribStats(typarams, env); - } - - void attribBounds(List typarams) { for (JCTypeParameter typaram : typarams) { Type bound = typaram.type.getUpperBound(); if (bound != null && bound.tsym instanceof ClassSymbol) { @@ -581,7 +581,7 @@ public class Attr extends JCTree.Visitor { try { chk.checkDeprecatedAnnotation(tree.pos(), m); - attribBounds(tree.typarams); + attribBounds(tree.typarams, env); // If we override any other methods, check that we do so properly. // JLS ??? @@ -2687,7 +2687,7 @@ public class Attr extends JCTree.Visitor { chk.validateAnnotations(tree.mods.annotations, c); // Validate type parameters, supertype and interfaces. - attribBounds(tree.typarams); + attribBounds(tree.typarams, env); chk.validateTypeParams(tree.typarams); chk.validate(tree.extending); chk.validate(tree.implementing); diff --git a/langtools/test/tools/javac/generics/T6660289.java b/langtools/test/tools/javac/generics/T6660289.java new file mode 100644 index 00000000000..3b948bedcde --- /dev/null +++ b/langtools/test/tools/javac/generics/T6660289.java @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6660289 + * @summary declared bound in inner class referring a type variable of the outer class + * @author Maurizio Cimadamore + * @compile T6660289.java + */ + +public class T6660289 { + class Inner {} +} From c953a1e7b819f2e85c90b538528bda2e2996888c Mon Sep 17 00:00:00 2001 From: Steve Bohne Date: Tue, 4 Mar 2008 09:44:24 -0500 Subject: [PATCH 056/274] 6666698: EnableBiasedLocking with BiasedLockingStartupDelay can block Watcher thread Enqueue VM_EnableBiasedLocking operation asynchronously Reviewed-by: never, xlu, kbr, acorn --- hotspot/src/share/vm/runtime/biasedLocking.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/biasedLocking.cpp b/hotspot/src/share/vm/runtime/biasedLocking.cpp index bfb3b790432..5d72f76749c 100644 --- a/hotspot/src/share/vm/runtime/biasedLocking.cpp +++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp @@ -38,8 +38,11 @@ static void enable_biased_locking(klassOop k) { class VM_EnableBiasedLocking: public VM_Operation { public: - VM_EnableBiasedLocking() {} - VMOp_Type type() const { return VMOp_EnableBiasedLocking; } + VM_EnableBiasedLocking() {} + VMOp_Type type() const { return VMOp_EnableBiasedLocking; } + Mode evaluation_mode() const { return _async_safepoint; } + bool is_cheap_allocated() const { return true; } + void doit() { // Iterate the system dictionary enabling biased locking for all // currently loaded classes @@ -62,8 +65,10 @@ class EnableBiasedLockingTask : public PeriodicTask { EnableBiasedLockingTask(size_t interval_time) : PeriodicTask(interval_time) {} virtual void task() { - VM_EnableBiasedLocking op; - VMThread::execute(&op); + // Use async VM operation to avoid blocking the Watcher thread. + // VM Thread will free C heap storage. + VM_EnableBiasedLocking *op = new VM_EnableBiasedLocking(); + VMThread::execute(op); // Reclaim our storage and disenroll ourself delete this; From 6350088352fd9e39f4e37f92a24c499a1472c113 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 4 Mar 2008 15:19:06 +0000 Subject: [PATCH 057/274] 6608214: Exception throw while analysing a file with error Bad error-recovery after bad type-variable bound is detected Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Attr.java | 1 + .../tools/javac/api/6608214/T6608214.java | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 langtools/test/tools/javac/api/6608214/T6608214.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index b754ae11511..bf06b95c51c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2514,6 +2514,7 @@ public class Attr extends JCTree.Visitor { log.error(tree.bounds.tail.head.pos(), "type.var.may.not.be.followed.by.other.bounds"); tree.bounds = List.of(tree.bounds.head); + a.bound = bs.head; } } else { // if first bound was a class or interface, accept only interfaces diff --git a/langtools/test/tools/javac/api/6608214/T6608214.java b/langtools/test/tools/javac/api/6608214/T6608214.java new file mode 100644 index 00000000000..a1e5ceaed6e --- /dev/null +++ b/langtools/test/tools/javac/api/6608214/T6608214.java @@ -0,0 +1,56 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6608214 + * @summary Exception throw while analysing a file with error + * @author Maurizio Cimadamore + */ + +import com.sun.source.util.JavacTask; +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; +import static javax.tools.JavaFileObject.Kind; + +public class T6608214 { + public static void main(String[] args) throws IOException { + JavaFileObject sfo = new SimpleJavaFileObject(URI.create(""),Kind.SOURCE) { + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return "class Test { void test(){}}"; + } + }; + List files = Arrays.asList(sfo); + String bootPath = System.getProperty("sun.boot.class.path"); + List opts = Arrays.asList("-bootclasspath", bootPath, "-Xjcov"); + JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); + JavacTask ct = (JavacTask)tool.getTask(null, null, null,opts,null,files); + ct.analyze(); + } +} From e82f62558354b1366e6ad061d88d5ce1fb240007 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 4 Mar 2008 15:45:20 +0000 Subject: [PATCH 058/274] 6663588: Compiler goes into infinite loop for Cyclic Inheritance test case Interplay between cyclic inheritance and tvar bounds hangs javac Reviewed-by: jjg --- .../com/sun/tools/javac/comp/MemberEnter.java | 4 +-- langtools/test/tools/javac/T6663588.java | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javac/T6663588.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 5a2f188b5bc..5c698ac16a7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -901,10 +901,10 @@ public class MemberEnter extends JCTree.Visitor implements Completer { c.flags_field |= DEPRECATED; annotateLater(tree.mods.annotations, baseEnv, c); - attr.attribTypeVariables(tree.typarams, baseEnv); - chk.checkNonCyclic(tree.pos(), c.type); + attr.attribTypeVariables(tree.typarams, baseEnv); + // Add default constructor if needed. if ((c.flags() & INTERFACE) == 0 && !TreeInfo.hasConstructors(tree.defs)) { diff --git a/langtools/test/tools/javac/T6663588.java b/langtools/test/tools/javac/T6663588.java new file mode 100644 index 00000000000..9c1dfa9202e --- /dev/null +++ b/langtools/test/tools/javac/T6663588.java @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6663588 + * @summary Compiler goes into infinite loop for Cyclic Inheritance test case + * @author Maurizio Cimadamore + * @compile/fail T6663588.java + */ + +public class T6663588 extends T6663588 { + class Inner extends T6663588.Inner {} +} From 6797bd9fb23a0be3f574378fc6829e815a913849 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 4 Mar 2008 17:09:09 +0000 Subject: [PATCH 059/274] 6638560: APPCRASH in "SPNEGO_HTTP_AUTH/PROXY_FALLBACK" test case with 64 bit JDK on Win2008 x64, VinVista x64 Remove incorrect free from native code Reviewed-by: jccollet --- .../sun/net/www/protocol/http/NTLMAuthSequence.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c b/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c index 29c0a2b3b70..4d4e56ee807 100644 --- a/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c +++ b/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c @@ -52,7 +52,7 @@ static INITIALIZE_SECURITY_CONTEXT_FN pInitializeSecurityContext; static COMPLETE_AUTH_TOKEN_FN pCompleteAuthToken; static DELETE_SECURITY_CONTEXT_FN pDeleteSecurityContext; -static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, SecBufferDesc OutBuffDesc); +static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle); static jfieldID ntlm_ctxHandleID; static jfieldID ntlm_crdHandleID; @@ -247,7 +247,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get } if (ss < 0) { - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); return 0; } @@ -255,7 +255,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get ss = pCompleteAuthToken( pCtx, &OutBuffDesc ); if (ss < 0) { - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); return 0; } } @@ -265,25 +265,23 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get (*env)->SetByteArrayRegion(env, ret, 0, OutSecBuff.cbBuffer, OutSecBuff.pvBuffer); if (lastToken != 0) // 2nd stage - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); result = ret; } if ((ss != SEC_I_CONTINUE_NEEDED) && (ss == SEC_I_COMPLETE_AND_CONTINUE)) { - endSequence (pCred, pCtx, OutBuffDesc); + endSequence (pCred, pCtx); } return result; } -static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, SecBufferDesc OutBuffDesc) { +static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle) { if (credHand != 0) { pFreeCredentialsHandle (credHand); free (credHand); } - pFreeContextBuffer (&OutBuffDesc); - if (ctxHandle != 0) { pDeleteSecurityContext(ctxHandle); free (ctxHandle); From e467c731a73a22b867cf4b5066b25712a04aa888 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 4 Mar 2008 09:47:43 -0800 Subject: [PATCH 060/274] 6654456: OpenJDK build problem with freetype makefiles Ifdef test on OPENJDK before it gets set based on source tree contents Reviewed-by: xdono --- jdk/make/common/shared/Platform.gmk | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/jdk/make/common/shared/Platform.gmk b/jdk/make/common/shared/Platform.gmk index f9f229a8548..915454a940c 100644 --- a/jdk/make/common/shared/Platform.gmk +++ b/jdk/make/common/shared/Platform.gmk @@ -93,10 +93,8 @@ SYSTEM_UNAME := $(shell uname) # Normal boot jdk is previous release, but a hard requirement is a 1.5 boot REQUIRED_BOOT_VER = 1.5 -#This is specific to OpenJDK build -ifdef OPENJDK - REQUIRED_FREETYPE_VERSION=2.3.0 -endif +# If we are using freetype, this is the required version +REQUIRED_FREETYPE_VERSION=2.3.0 # # Prune out all known SCM (Source Code Management) directories From 05b8e8fbfdca459acffbf2b94c927db5651fafa7 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 4 Mar 2008 09:49:22 -0800 Subject: [PATCH 061/274] 6637583: Build failure on latest Solaris, source missing include of resource.h? The include of sys/resource.h must be explicit Reviewed-by: xdono --- jdk/src/solaris/hpi/native_threads/src/sys_api_td.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/jdk/src/solaris/hpi/native_threads/src/sys_api_td.c b/jdk/src/solaris/hpi/native_threads/src/sys_api_td.c index 37b098aae43..c61324a4d0f 100644 --- a/jdk/src/solaris/hpi/native_threads/src/sys_api_td.c +++ b/jdk/src/solaris/hpi/native_threads/src/sys_api_td.c @@ -63,15 +63,8 @@ #define CLOSEIO #endif /* NO_INTERRUPTIBLE_IO */ -/* - * Linux does not define rlim_t (solaris - * does). THIS IS PROBABLY NOT THE RIGHT THING TO DO, so - * somebody please fix this. - */ -#ifdef __linux__ -typedef int rlim_t ; -#endif - +/* Get typedef for rlim_t */ +#include #ifdef CLOSEIO From 962e1ab78eaf27a94f0ad1c68abb558a4ae158b6 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 4 Mar 2008 09:50:30 -0800 Subject: [PATCH 062/274] 6638571: Fix freetype sanity check to work on solaris 64bit Missing -xarch options to build for 64bit Reviewed-by: xdono --- jdk/make/tools/freetypecheck/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jdk/make/tools/freetypecheck/Makefile b/jdk/make/tools/freetypecheck/Makefile index c2a3e644ba7..7bcfe6300c1 100644 --- a/jdk/make/tools/freetypecheck/Makefile +++ b/jdk/make/tools/freetypecheck/Makefile @@ -38,7 +38,14 @@ FT_TEST_PATH = $(TEMPDIR)/$(FT_TEST) all: $(FT_TEST_PATH) -FT_OPTIONS = -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2 +# Start with CFLAGS (which gets us the required -xarch setting on solaris) +ifeq ($(PLATFORM), windows) + FT_OPTIONS = +else + FT_OPTIONS = $(CFLAGS) +endif + +FT_OPTIONS += -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2 FT_OPTIONS += $(XARCH) #add runtime library search path From c13218442ae82fdf73b658e2b3889fdeae134736 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 4 Mar 2008 09:51:25 -0800 Subject: [PATCH 063/274] 6638060: Build failed with GNU make 3.81 (part of latest Solaris 'gmake') Changes to the way GNU make 3.81 deals with the env variable SHELL Reviewed-by: xdono --- jdk/make/java/nio/Makefile | 10 +++++----- jdk/make/java/nio/genCharsetProvider.sh | 2 +- jdk/make/java/nio/genExceptions.sh | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/jdk/make/java/nio/Makefile b/jdk/make/java/nio/Makefile index 98a838831a2..0a9070f8257 100644 --- a/jdk/make/java/nio/Makefile +++ b/jdk/make/java/nio/Makefile @@ -191,7 +191,7 @@ sources: $(SPP) $(FILES_genout) GEN_BUFFER_SH = genBuffer.sh -GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) \ +GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) SH=$(SH) \ $(SH) $(GEN_BUFFER_SH) # Public abstract buffer classes @@ -582,7 +582,7 @@ $(BUF_GEN)/ByteBufferAsDoubleBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.jav GEN_CODER_SH = genCoder.sh -GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) $(SH) $(GEN_CODER_SH) +GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_CODER_SH) $(CS_GEN)/CharsetDecoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH) $(prep-target) @@ -602,7 +602,7 @@ $(CS_GEN)/CharsetEncoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH) GEN_EX_SH = genExceptions.sh -GEN_EX_CMD = NAWK=$(NAWK) $(SHELL) $(GEN_EX_SH) +GEN_EX_CMD = NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_EX_SH) $(CH_GEN)/%Exception.java: genExceptions.sh $(CH_SRC)/exceptions $(prep-target) @@ -635,8 +635,8 @@ $(SCS_GEN)/StandardCharsets.java: genCharsetProvider.sh \ $(HASHER_JARFILE) $(SCS_SRC)/standard-charsets $(prep-target) @$(RM) $@.temp - NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) \ + NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) SH=$(SH) \ HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \ - $(SHELL) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN) + $(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN) .PHONY: sources diff --git a/jdk/make/java/nio/genCharsetProvider.sh b/jdk/make/java/nio/genCharsetProvider.sh index 1c344dacabd..574722fb4a9 100644 --- a/jdk/make/java/nio/genCharsetProvider.sh +++ b/jdk/make/java/nio/genCharsetProvider.sh @@ -48,7 +48,7 @@ echo '-->' $OUT # Header # -$SHELL addNotices.sh "$COPYRIGHT_YEARS" > $OUT +$SH ./addNotices.sh "$COPYRIGHT_YEARS" > $OUT cat <<__END__ >>$OUT diff --git a/jdk/make/java/nio/genExceptions.sh b/jdk/make/java/nio/genExceptions.sh index 0e2020c2c1f..2de5e9cd784 100644 --- a/jdk/make/java/nio/genExceptions.sh +++ b/jdk/make/java/nio/genExceptions.sh @@ -41,7 +41,7 @@ gen() { echo '-->' $DST/$ID.java out=$DST/${ID}.java - $SHELL addNotices.sh "$COPYRIGHT_YEARS" > $out + $SH ./addNotices.sh "$COPYRIGHT_YEARS" > $out cat >>$out <<__END__ From 4b49c996b425daeee0dfc07f2b677bc394b4ede7 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 4 Mar 2008 09:52:54 -0800 Subject: [PATCH 064/274] 6668781: Openjdk windows cygwin build failure: no rule to make linker_md.obj target Use of GNU make vpath breaks on windows with C:/ style fullpaths Reviewed-by: xdono --- jdk/make/common/Defs-linux.gmk | 4 ++-- jdk/make/common/Defs-solaris.gmk | 4 ++-- jdk/make/common/Defs-windows.gmk | 6 +++--- jdk/make/common/Defs.gmk | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/jdk/make/common/Defs-linux.gmk b/jdk/make/common/Defs-linux.gmk index 51d638f96ab..674b6f6a0e6 100644 --- a/jdk/make/common/Defs-linux.gmk +++ b/jdk/make/common/Defs-linux.gmk @@ -50,13 +50,13 @@ CC_DEPEND = -MM CC_DEPEND_FILTER = $(SED) -e 's!$*\.$(OBJECT_SUFFIX)!$(dir $@)& $(dir $@)$*.$(DEPEND_SUFFIX)!g' ifndef PLATFORM_SRC - PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris + PLATFORM_SRC = $(BUILDDIR)/../src/solaris endif # PLATFORM_SRC # Platform specific closed sources ifndef OPENJDK ifndef CLOSED_PLATFORM_SRC - CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris + CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris endif endif diff --git a/jdk/make/common/Defs-solaris.gmk b/jdk/make/common/Defs-solaris.gmk index 800c0b75ddb..052c0c88fc8 100644 --- a/jdk/make/common/Defs-solaris.gmk +++ b/jdk/make/common/Defs-solaris.gmk @@ -45,13 +45,13 @@ include $(JDK_MAKE_SHARED_DIR)/Defs.gmk ifndef PLATFORM_SRC -PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris +PLATFORM_SRC = $(BUILDDIR)/../src/solaris endif # PLATFORM_SRC # Platform specific closed sources ifndef OPENJDK ifndef CLOSED_PLATFORM_SRC - CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris + CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris endif endif diff --git a/jdk/make/common/Defs-windows.gmk b/jdk/make/common/Defs-windows.gmk index 6f53eb72f3b..e9bdea85278 100644 --- a/jdk/make/common/Defs-windows.gmk +++ b/jdk/make/common/Defs-windows.gmk @@ -51,13 +51,13 @@ ifndef LIB_LOCATION endif # LIB_LOCATION ifndef PLATFORM_SRC - PLATFORM_SRC = $(JDK_TOPDIR)/src/windows + PLATFORM_SRC = $(BUILDDIR)/../src/windows endif # PLATFORM_SRC # Platform specific closed sources ifndef OPENJDK ifndef CLOSED_PLATFORM_SRC - CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/windows + CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/windows endif endif @@ -367,7 +367,7 @@ else endif # Settings for the VERSIONINFO tap on windows. -VERSIONINFO_RESOURCE = $(JDK_TOPDIR)/src/windows/resource/version.rc +VERSIONINFO_RESOURCE = $(BUILDDIR)/../src/windows/resource/version.rc ifneq ($(JDK_BUILD_NUMBER),) COOKED_BUILD_NUMBER = $(shell $(ECHO) $(JDK_BUILD_NUMBER) | $(SED) -e 's/^b//' -e 's/^0//') diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 9dd781b2f7e..6048744384e 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -59,13 +59,13 @@ include $(JDK_TOPDIR)/make/common/CancelImplicits.gmk # there yet. # ifndef SHARE_SRC - SHARE_SRC = $(JDK_TOPDIR)/src/share + SHARE_SRC = $(BUILDDIR)/../src/share endif # Files that cannot be included in the OpenJDK distribution are # collected under a parent directory which contains just those files. ifndef CLOSED_SRC - CLOSED_SRC = $(JDK_TOPDIR)/src/closed + CLOSED_SRC = $(BUILDDIR)/../src/closed endif # If we have no closed directory, force it to an openjdk build From 12028b6de1242f5e8f0c58c51099fd178559fd47 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 4 Mar 2008 10:58:04 -0800 Subject: [PATCH 065/274] 6652588: Fix broken JPRT makefile target, no bundle saved Jprt make rules missing the bundle up of the output Reviewed-by: xdono --- jaxp/make/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jaxp/make/Makefile b/jaxp/make/Makefile index 9e72148a928..6de97e7e673 100644 --- a/jaxp/make/Makefile +++ b/jaxp/make/Makefile @@ -90,7 +90,6 @@ ifdef ALT_OUTPUTDIR else OUTPUTDIR = .. endif -ABS_OUTPUTDIR = $(call FullPath,$(OUTPUTDIR)) ifdef ALT_LANGTOOLS_DIST ANT_OPTIONS += -Dbootstrap.dir=$(ALT_LANGTOOLS_DIST)/bootstrap @@ -127,7 +126,11 @@ $(ANT_TARGETS): $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@ # Targets for Sun's internal JPRT build system +JPRT_ARCHIVE_BUNDLE=$(OUTPUTDIR)/jprt.zip jprt_build_product jprt_build_debug jprt_build_fastdebug: all + $(RM) $(JPRT_ARCHIVE_BUNDLE) + ( cd $(OUTPUTDIR)/dist && \ + zip -q -r $(JPRT_ARCHIVE_BUNDLE) . ) # Declare these phony (not filenames) .PHONY: $(ANT_TARGETS) all clobber \ From fc9ffa52c48ef8cf8549262cf92bf348f2389dde Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 4 Mar 2008 10:58:50 -0800 Subject: [PATCH 066/274] 6652588: Fix broken JPRT makefile target, no bundle saved Jprt make rules were missing the bundle logic Reviewed-by: xdono --- jaxws/make/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jaxws/make/Makefile b/jaxws/make/Makefile index 3dab62bec74..3dc17bfa39f 100644 --- a/jaxws/make/Makefile +++ b/jaxws/make/Makefile @@ -69,7 +69,7 @@ else endif endif -# Note: j2se/make/common/Defs.gmk uses LANGUAGE_VERSION (-source NN) +# Note: jdk/make/common/Defs.gmk uses LANGUAGE_VERSION (-source NN) # and the somewhat misnamed CLASS_VERSION (-target NN) ifdef TARGET_CLASS_VERSION ANT_OPTIONS += -Djavac.target=$(TARGET_CLASS_VERSION) @@ -90,7 +90,6 @@ ifdef ALT_OUTPUTDIR else OUTPUTDIR = .. endif -ABS_OUTPUTDIR = $(call FullPath,$(OUTPUTDIR)) ifdef ALT_LANGTOOLS_DIST ANT_OPTIONS += -Dbootstrap.dir=$(ALT_LANGTOOLS_DIST)/bootstrap @@ -127,7 +126,11 @@ $(ANT_TARGETS): $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@ # Targets for Sun's internal JPRT build system +JPRT_ARCHIVE_BUNDLE=$(OUTPUTDIR)/jprt.zip jprt_build_product jprt_build_debug jprt_build_fastdebug: all + $(RM) $(JPRT_ARCHIVE_BUNDLE) + ( cd $(OUTPUTDIR)/dist && \ + zip -q -r $(JPRT_ARCHIVE_BUNDLE) . ) # Declare these phony (not filenames) .PHONY: $(ANT_TARGETS) all clobber \ From 0f960354ea2506d0c7daa4e90d1523d43c89c5ec Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 5 Mar 2008 09:52:50 +0800 Subject: [PATCH 067/274] 6641312: Fix krb5 codes indentation problems Reviewed-by: xuelei, valeriep, wetmore --- .../classes/sun/security/krb5/KrbTgsReq.java | 194 ++-- .../sun/security/krb5/internal/APRep.java | 133 ++- .../sun/security/krb5/internal/APReq.java | 160 +-- .../sun/security/krb5/internal/ASRep.java | 44 +- .../sun/security/krb5/internal/ASReq.java | 23 +- .../security/krb5/internal/Authenticator.java | 251 ++-- .../krb5/internal/AuthorizationData.java | 176 ++- .../krb5/internal/AuthorizationDataEntry.java | 144 +-- .../security/krb5/internal/EncAPRepPart.java | 180 +-- .../security/krb5/internal/EncASRepPart.java | 94 +- .../security/krb5/internal/EncKDCRepPart.java | 273 +++-- .../krb5/internal/EncKrbCredPart.java | 267 ++--- .../krb5/internal/EncKrbPrivPart.java | 197 ++-- .../security/krb5/internal/EncTGSRepPart.java | 91 +- .../security/krb5/internal/EncTicketPart.java | 247 ++-- .../sun/security/krb5/internal/KDCRep.java | 294 ++--- .../sun/security/krb5/internal/KDCReq.java | 267 ++--- .../sun/security/krb5/internal/KRBCred.java | 214 ++-- .../security/krb5/internal/KrbCredInfo.java | 22 +- .../krb5/internal/ccache/Credentials.java | 293 ++--- .../native/sun/security/krb5/NativeCreds.c | 1018 ++++++++--------- 21 files changed, 2337 insertions(+), 2245 deletions(-) diff --git a/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java b/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java index 328e255e0d6..0cc54e17c45 100644 --- a/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java +++ b/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java @@ -75,107 +75,107 @@ public class KrbTgsReq extends KrbKdcReq { null); // EncryptionKey subSessionKey } - // Called by Credentials, KrbCred - KrbTgsReq( - KDCOptions options, - Credentials asCreds, - PrincipalName sname, - KerberosTime from, - KerberosTime till, - KerberosTime rtime, - int[] eTypes, - HostAddresses addresses, - AuthorizationData authorizationData, - Ticket[] additionalTickets, - EncryptionKey subKey) throws KrbException, IOException { + // Called by Credentials, KrbCred + KrbTgsReq( + KDCOptions options, + Credentials asCreds, + PrincipalName sname, + KerberosTime from, + KerberosTime till, + KerberosTime rtime, + int[] eTypes, + HostAddresses addresses, + AuthorizationData authorizationData, + Ticket[] additionalTickets, + EncryptionKey subKey) throws KrbException, IOException { - princName = asCreds.client; - servName = sname; - ctime = new KerberosTime(KerberosTime.NOW); - - - // check if they are valid arguments. The optional fields - // should be consistent with settings in KDCOptions. - if (options.get(KDCOptions.FORWARDABLE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.FORWARDED)) { - if (!(asCreds.flags.get(KDCOptions.FORWARDABLE))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.PROXIABLE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_PROXIABLE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.PROXY)) { - if (!(asCreds.flags.get(KDCOptions.PROXIABLE))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.ALLOW_POSTDATE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_MAY_POSTDATE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - if (options.get(KDCOptions.RENEWABLE) && - (!(asCreds.flags.get(Krb5.TKT_OPTS_RENEWABLE)))) { - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } - - if (options.get(KDCOptions.POSTDATED)) { - if (!(asCreds.flags.get(KDCOptions.POSTDATED))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } else { - if (from != null) from = null; - } - if (options.get(KDCOptions.RENEWABLE)) { - if (!(asCreds.flags.get(KDCOptions.RENEWABLE))) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - } else { - if (rtime != null) rtime = null; - } - if (options.get(KDCOptions.ENC_TKT_IN_SKEY)) { - if (additionalTickets == null) - throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); - // in TGS_REQ there could be more than one additional - // tickets, but in file-based credential cache, - // there is only one additional ticket field. - secondTicket = additionalTickets[0]; - } else { - if (additionalTickets != null) - additionalTickets = null; - } - - tgsReqMessg = createRequest( - options, - asCreds.ticket, - asCreds.key, - ctime, - princName, - princName.getRealm(), - servName, - from, - till, - rtime, - eTypes, - addresses, - authorizationData, - additionalTickets, - subKey); - obuf = tgsReqMessg.asn1Encode(); - - // XXX We need to revisit this to see if can't move it - // up such that FORWARDED flag set in the options - // is included in the marshaled request. - /* - * If this is based on a forwarded ticket, record that in the - * options, because the returned TgsRep will contain the - * FORWARDED flag set. - */ - if (asCreds.flags.get(KDCOptions.FORWARDED)) - options.set(KDCOptions.FORWARDED, true); + princName = asCreds.client; + servName = sname; + ctime = new KerberosTime(KerberosTime.NOW); + // check if they are valid arguments. The optional fields + // should be consistent with settings in KDCOptions. + if (options.get(KDCOptions.FORWARDABLE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); } + if (options.get(KDCOptions.FORWARDED)) { + if (!(asCreds.flags.get(KDCOptions.FORWARDABLE))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.PROXIABLE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_PROXIABLE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.PROXY)) { + if (!(asCreds.flags.get(KDCOptions.PROXIABLE))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.ALLOW_POSTDATE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_MAY_POSTDATE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + if (options.get(KDCOptions.RENEWABLE) && + (!(asCreds.flags.get(Krb5.TKT_OPTS_RENEWABLE)))) { + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } + + if (options.get(KDCOptions.POSTDATED)) { + if (!(asCreds.flags.get(KDCOptions.POSTDATED))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } else { + if (from != null) from = null; + } + if (options.get(KDCOptions.RENEWABLE)) { + if (!(asCreds.flags.get(KDCOptions.RENEWABLE))) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + } else { + if (rtime != null) rtime = null; + } + if (options.get(KDCOptions.ENC_TKT_IN_SKEY)) { + if (additionalTickets == null) + throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS); + // in TGS_REQ there could be more than one additional + // tickets, but in file-based credential cache, + // there is only one additional ticket field. + secondTicket = additionalTickets[0]; + } else { + if (additionalTickets != null) + additionalTickets = null; + } + + tgsReqMessg = createRequest( + options, + asCreds.ticket, + asCreds.key, + ctime, + princName, + princName.getRealm(), + servName, + from, + till, + rtime, + eTypes, + addresses, + authorizationData, + additionalTickets, + subKey); + obuf = tgsReqMessg.asn1Encode(); + + // XXX We need to revisit this to see if can't move it + // up such that FORWARDED flag set in the options + // is included in the marshaled request. + /* + * If this is based on a forwarded ticket, record that in the + * options, because the returned TgsRep will contain the + * FORWARDED flag set. + */ + if (asCreds.flags.get(KDCOptions.FORWARDED)) + options.set(KDCOptions.FORWARDED, true); + + + } /** * Sends a TGS request to the realm of the target. diff --git a/jdk/src/share/classes/sun/security/krb5/internal/APRep.java b/jdk/src/share/classes/sun/security/krb5/internal/APRep.java index 17aeb89797c..53c3b58eaac 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/APRep.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/APRep.java @@ -54,81 +54,88 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class APRep { - public int pvno; - public int msgType; - public EncryptedData encPart; - public APRep(EncryptedData new_encPart) { - pvno = Krb5.PVNO; - msgType = Krb5.KRB_AP_REP; - encPart = new_encPart; - } + public int pvno; + public int msgType; + public EncryptedData encPart; - public APRep(byte[] data) throws Asn1Exception, - KrbApErrException, IOException { - init(new DerValue(data)); - } + public APRep(EncryptedData new_encPart) { + pvno = Krb5.PVNO; + msgType = Krb5.KRB_AP_REP; + encPart = new_encPart; + } + + public APRep(byte[] data) throws Asn1Exception, + KrbApErrException, IOException { + init(new DerValue(data)); + } public APRep(DerValue encoding) throws Asn1Exception, - KrbApErrException, IOException { - init(encoding); - } + KrbApErrException, IOException { + init(encoding); + } - /** - * Initializes an APRep object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data - * stream does not match the pre-defined value. - */ + /** + * Initializes an APRep object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data + * stream does not match the pre-defined value. + */ private void init(DerValue encoding) throws Asn1Exception, - KrbApErrException, IOException { + KrbApErrException, IOException { - if (((encoding.getTag() & (byte)(0x1F)) != Krb5.KRB_AP_REP) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - DerValue der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + if (((encoding.getTag() & (byte) (0x1F)) != Krb5.KRB_AP_REP) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - DerValue subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x00) + } + DerValue der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + DerValue subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x01) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != Krb5.KRB_AP_REP) - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - encPart = EncryptedData.parse(der.getData(), (byte)0x02, false); - if (der.getData().available() > 0) + if (pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != Krb5.KRB_AP_REP) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + encPart = EncryptedData.parse(der.getData(), (byte) 0x02, false); + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an APRep object. - * @return byte array of encoded APRep object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an APRep object. + * @return byte array of encoded APRep object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), encPart.asn1Encode()); - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - DerOutputStream aprep = new DerOutputStream(); - aprep.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x0F), temp); - return aprep.toByteArray(); - } - + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), encPart.asn1Encode()); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + DerOutputStream aprep = new DerOutputStream(); + aprep.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0F), temp); + return aprep.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/APReq.java b/jdk/src/share/classes/sun/security/krb5/internal/APReq.java index 328f833df62..3a1dc7c2222 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/APReq.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/APReq.java @@ -54,94 +54,98 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class APReq { - public int pvno; - public int msgType; - public APOptions apOptions; - public Ticket ticket; - public EncryptedData authenticator; - public APReq( - APOptions new_apOptions, - Ticket new_ticket, - EncryptedData new_authenticator - ) { - pvno = Krb5.PVNO; - msgType = Krb5.KRB_AP_REQ; - apOptions = new_apOptions; - ticket = new_ticket; - authenticator = new_authenticator; - } + public int pvno; + public int msgType; + public APOptions apOptions; + public Ticket ticket; + public EncryptedData authenticator; - public APReq(byte[] data) throws Asn1Exception,IOException, KrbApErrException, RealmException { + public APReq( + APOptions new_apOptions, + Ticket new_ticket, + EncryptedData new_authenticator) { + pvno = Krb5.PVNO; + msgType = Krb5.KRB_AP_REQ; + apOptions = new_apOptions; + ticket = new_ticket; + authenticator = new_authenticator; + } + + public APReq(byte[] data) throws Asn1Exception, IOException, KrbApErrException, RealmException { init(new DerValue(data)); - } + } public APReq(DerValue encoding) throws Asn1Exception, IOException, KrbApErrException, RealmException { - init(encoding); - } + init(encoding); + } - /** - * Initializes an APReq object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) throws Asn1Exception, - IOException, KrbApErrException, RealmException { - DerValue der, subDer; - if (((encoding.getTag() & (byte)0x1F) != Krb5.KRB_AP_REQ) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x00) + /** + * Initializes an APReq object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) throws Asn1Exception, + IOException, KrbApErrException, RealmException { + DerValue der, subDer; + if (((encoding.getTag() & (byte) 0x1F) != Krb5.KRB_AP_REQ) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x01) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != Krb5.KRB_AP_REQ) - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - apOptions = APOptions.parse(der.getData(), (byte)0x02, false); - ticket = Ticket.parse(der.getData(), (byte)0x03, false); - authenticator = EncryptedData.parse(der.getData(), (byte)0x04, false); - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + if (pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x01) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != Krb5.KRB_AP_REQ) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + apOptions = APOptions.parse(der.getData(), (byte) 0x02, false); + ticket = Ticket.parse(der.getData(), (byte) 0x03, false); + authenticator = EncryptedData.parse(der.getData(), (byte) 0x04, false); + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an APReq object. - * @return byte array of encoded APReq object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an APReq object. + * @return byte array of encoded APReq object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), apOptions.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), ticket.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authenticator.asn1Encode()); - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - DerOutputStream apreq = new DerOutputStream(); - apreq.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x0E), temp); - return apreq.toByteArray(); - - } - + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), apOptions.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), ticket.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), authenticator.asn1Encode()); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + DerOutputStream apreq = new DerOutputStream(); + apreq.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x0E), temp); + return apreq.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ASRep.java b/jdk/src/share/classes/sun/security/krb5/internal/ASRep.java index df0ebac6550..a59811d97f9 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ASRep.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ASRep.java @@ -40,30 +40,28 @@ import java.io.IOException; public class ASRep extends KDCRep { - public ASRep( - PAData[] new_pAData, - Realm new_crealm, - PrincipalName new_cname, - Ticket new_ticket, - EncryptedData new_encPart - ) throws IOException { - super(new_pAData, new_crealm, new_cname, new_ticket, - new_encPart, Krb5.KRB_AS_REP); - } + public ASRep( + PAData[] new_pAData, + Realm new_crealm, + PrincipalName new_cname, + Ticket new_ticket, + EncryptedData new_encPart) throws IOException { + super(new_pAData, new_crealm, new_cname, new_ticket, + new_encPart, Krb5.KRB_AS_REP); + } - public ASRep(byte[] data) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(new DerValue(data)); - } + public ASRep(byte[] data) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(new DerValue(data)); + } - public ASRep(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding); - } - - private void init(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding, Krb5.KRB_AS_REP); - } + public ASRep(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding); + } + private void init(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding, Krb5.KRB_AS_REP); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ASReq.java b/jdk/src/share/classes/sun/security/krb5/internal/ASReq.java index 743316c6c0c..b5907398bf7 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ASReq.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ASReq.java @@ -36,20 +36,19 @@ import java.io.IOException; public class ASReq extends KDCReq { - public ASReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException { - super(new_pAData, new_reqBody, Krb5.KRB_AS_REQ); - } + public ASReq(PAData[] new_pAData, KDCReqBody new_reqBody) throws IOException { + super(new_pAData, new_reqBody, Krb5.KRB_AS_REQ); + } - public ASReq(byte[] data) throws Asn1Exception, KrbException, IOException { - init(new DerValue(data)); - } + public ASReq(byte[] data) throws Asn1Exception, KrbException, IOException { + init(new DerValue(data)); + } public ASReq(DerValue encoding) throws Asn1Exception, KrbException, IOException { - init(encoding); - } - - private void init(DerValue encoding) throws Asn1Exception, IOException, KrbException { - super.init(encoding, Krb5.KRB_AS_REQ); - } + init(encoding); + } + private void init(DerValue encoding) throws Asn1Exception, IOException, KrbException { + super.init(encoding, Krb5.KRB_AS_REQ); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/Authenticator.java b/jdk/src/share/classes/sun/security/krb5/internal/Authenticator.java index 57b6156c0e5..49cf1709ee2 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/Authenticator.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/Authenticator.java @@ -34,6 +34,7 @@ import sun.security.util.*; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 Authenticator type. * @@ -58,6 +59,7 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class Authenticator { + public int authenticator_vno; public Realm crealm; public PrincipalName cname; @@ -68,137 +70,145 @@ public class Authenticator { Integer seqNumber; //optional public AuthorizationData authorizationData; //optional - public Authenticator ( - Realm new_crealm, - PrincipalName new_cname, - Checksum new_cksum, - int new_cusec, - KerberosTime new_ctime, - EncryptionKey new_subKey, - Integer new_seqNumber, - AuthorizationData new_authorizationData - ) { - authenticator_vno = Krb5.AUTHNETICATOR_VNO; - crealm = new_crealm; - cname = new_cname; - cksum = new_cksum; - cusec = new_cusec; - ctime = new_ctime; - subKey = new_subKey; - seqNumber = new_seqNumber; - authorizationData = new_authorizationData; - } + public Authenticator( + Realm new_crealm, + PrincipalName new_cname, + Checksum new_cksum, + int new_cusec, + KerberosTime new_ctime, + EncryptionKey new_subKey, + Integer new_seqNumber, + AuthorizationData new_authorizationData) { + authenticator_vno = Krb5.AUTHNETICATOR_VNO; + crealm = new_crealm; + cname = new_cname; + cksum = new_cksum; + cusec = new_cusec; + ctime = new_ctime; + subKey = new_subKey; + seqNumber = new_seqNumber; + authorizationData = new_authorizationData; + } - public Authenticator(byte[] data) - throws Asn1Exception, IOException, KrbApErrException, RealmException { - init(new DerValue(data)); - } + public Authenticator(byte[] data) + throws Asn1Exception, IOException, KrbApErrException, RealmException { + init(new DerValue(data)); + } - public Authenticator(DerValue encoding) - throws Asn1Exception,IOException, KrbApErrException, RealmException { - init(encoding); - } + public Authenticator(DerValue encoding) + throws Asn1Exception, IOException, KrbApErrException, RealmException { + init(encoding); + } - /** - * Initializes an Authenticator object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data - * stream does not match the pre-defined value. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) - throws Asn1Exception, IOException, KrbApErrException, RealmException { - DerValue der, subDer; - //may not be the correct error code for a tag - //mismatch on an encrypted structure - if (((encoding.getTag() & (byte)0x1F) != (byte)0x02) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + /** + * Initializes an Authenticator object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data + * stream does not match the pre-defined value. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) + throws Asn1Exception, IOException, KrbApErrException, RealmException { + DerValue der, subDer; + //may not be the correct error code for a tag + //mismatch on an encrypted structure + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x02) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) != (byte)0x00) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) != (byte) 0x00) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } authenticator_vno = subDer.getData().getBigInteger().intValue(); - if (authenticator_vno != 5) + if (authenticator_vno != 5) { throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - crealm = Realm.parse(der.getData(), (byte)0x01, false); - cname = PrincipalName.parse(der.getData(), (byte)0x02, false); - cksum = Checksum.parse(der.getData(), (byte)0x03, true); + } + crealm = Realm.parse(der.getData(), (byte) 0x01, false); + cname = PrincipalName.parse(der.getData(), (byte) 0x02, false); + cksum = Checksum.parse(der.getData(), (byte) 0x03, true); + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == 0x04) { + cusec = subDer.getData().getBigInteger().intValue(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + ctime = KerberosTime.parse(der.getData(), (byte) 0x05, false); + if (der.getData().available() > 0) { + subKey = EncryptionKey.parse(der.getData(), (byte) 0x06, true); + } else { + subKey = null; + seqNumber = null; + authorizationData = null; + } + if (der.getData().available() > 0) { + if ((der.getData().peekByte() & 0x1F) == 0x07) { subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == 0x04) { - cusec = subDer.getData().getBigInteger().intValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x07) { + seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); } - else throw new Asn1Exception(Krb5.ASN1_BAD_ID); - ctime = KerberosTime.parse(der.getData(), (byte)0x05, false); - if (der.getData().available() > 0) { - subKey = EncryptionKey.parse(der.getData(), (byte)0x06, true); - } - else { - subKey = null; - seqNumber = null; - authorizationData = null; - } - if (der.getData().available() > 0) { - if ((der.getData().peekByte() & 0x1F) == 0x07) { - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x07) - seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); - } - } - else { - seqNumber = null; - authorizationData = null; - } - if (der.getData().available() > 0) { - authorizationData = AuthorizationData.parse(der.getData(), (byte)0x08, true); - } - else authorizationData = null; - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } else { + seqNumber = null; + authorizationData = null; } + if (der.getData().available() > 0) { + authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x08, true); + } else { + authorizationData = null; + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an Authenticator object. - * @return byte array of encoded Authenticator object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { - Vector v = new Vector (); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(authenticator_vno)); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp.toByteArray())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), crealm.asn1Encode())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), cname.asn1Encode())); - if (cksum != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), cksum.asn1Encode())); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(cusec)); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), temp.toByteArray())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), ctime.asn1Encode())); - if (subKey != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), subKey.asn1Encode())); - if (seqNumber != null) { - temp = new DerOutputStream(); - // encode as an unsigned integer (UInt32) - temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), temp.toByteArray())); - } - if (authorizationData != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), authorizationData.asn1Encode())); - DerValue der[] = new DerValue[v.size()]; - v.copyInto(der); - temp = new DerOutputStream(); - temp.putSequence(der); - DerOutputStream out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x02), temp); - return out.toByteArray(); + /** + * Encodes an Authenticator object. + * @return byte array of encoded Authenticator object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + Vector v = new Vector(); + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(authenticator_vno)); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp.toByteArray())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), crealm.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), cname.asn1Encode())); + if (cksum != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), cksum.asn1Encode())); } + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(cusec)); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), temp.toByteArray())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), ctime.asn1Encode())); + if (subKey != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x06), subKey.asn1Encode())); + } + if (seqNumber != null) { + temp = new DerOutputStream(); + // encode as an unsigned integer (UInt32) + temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x07), temp.toByteArray())); + } + if (authorizationData != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x08), authorizationData.asn1Encode())); + } + DerValue der[] = new DerValue[v.size()]; + v.copyInto(der); + temp = new DerOutputStream(); + temp.putSequence(der); + DerOutputStream out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x02), temp); + return out.toByteArray(); + } public final Checksum getChecksum() { return cksum; @@ -211,5 +221,4 @@ public class Authenticator { public final EncryptionKey getSubKey() { return subKey; } - } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java index d6f04d748b5..269edec71a1 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java @@ -53,82 +53,81 @@ import sun.security.krb5.internal.ccache.CCacheOutputStream; * } */ public class AuthorizationData implements Cloneable { - private AuthorizationDataEntry[] entry = null; - private AuthorizationData() { - } + private AuthorizationDataEntry[] entry = null; - public AuthorizationData( - AuthorizationDataEntry[] new_entries - ) throws IOException { - if (new_entries != null) { - entry = new AuthorizationDataEntry[new_entries.length]; - for (int i = 0; i < new_entries.length; i++) { - if (new_entries[i] == null) { - throw new IOException("Cannot create an AuthorizationData"); - } else { - entry[i] = (AuthorizationDataEntry)new_entries[i].clone(); - } - } - } - } + private AuthorizationData() { + } - public AuthorizationData( - AuthorizationDataEntry new_entry - ) { - entry = new AuthorizationDataEntry[1]; - entry[0] = new_entry; + public AuthorizationData(AuthorizationDataEntry[] new_entries) + throws IOException { + if (new_entries != null) { + entry = new AuthorizationDataEntry[new_entries.length]; + for (int i = 0; i < new_entries.length; i++) { + if (new_entries[i] == null) { + throw new IOException("Cannot create an AuthorizationData"); + } else { + entry[i] = (AuthorizationDataEntry) new_entries[i].clone(); + } + } } + } - public Object clone() { - AuthorizationData new_authorizationData = - new AuthorizationData(); - if (entry != null) { - new_authorizationData.entry = - new AuthorizationDataEntry[entry.length]; - for (int i = 0; i < entry.length; i++) - new_authorizationData.entry[i] = - (AuthorizationDataEntry)entry[i].clone(); - } - return new_authorizationData; - } + public AuthorizationData(AuthorizationDataEntry new_entry) { + entry = new AuthorizationDataEntry[1]; + entry[0] = new_entry; + } - /** - * Constructs a new AuthorizationData, instance. - * @param der a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public AuthorizationData(DerValue der) throws Asn1Exception, IOException { - Vector v = - new Vector (); - if (der.getTag() != DerValue.tag_Sequence) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - while (der.getData().available() > 0) { - v.addElement(new AuthorizationDataEntry(der.getData().getDerValue())); - } - if (v.size() > 0) { - entry = new AuthorizationDataEntry[v.size()]; - v.copyInto(entry); - } + public Object clone() { + AuthorizationData new_authorizationData = + new AuthorizationData(); + if (entry != null) { + new_authorizationData.entry = + new AuthorizationDataEntry[entry.length]; + for (int i = 0; i < entry.length; i++) { + new_authorizationData.entry[i] = + (AuthorizationDataEntry) entry[i].clone(); + } } + return new_authorizationData; + } - /** - * Encodes an AuthorizationData object. - * @return byte array of encoded AuthorizationData object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { - DerOutputStream bytes = new DerOutputStream(); - DerValue der[] = new DerValue[entry.length]; - for (int i = 0; i < entry.length; i++) { - der[i] = new DerValue(entry[i].asn1Encode()); - } - bytes.putSequence(der); - return bytes.toByteArray(); + /** + * Constructs a new AuthorizationData, instance. + * @param der a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public AuthorizationData(DerValue der) throws Asn1Exception, IOException { + Vector v = + new Vector(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + while (der.getData().available() > 0) { + v.addElement(new AuthorizationDataEntry(der.getData().getDerValue())); + } + if (v.size() > 0) { + entry = new AuthorizationDataEntry[v.size()]; + v.copyInto(entry); + } + } + + /** + * Encodes an AuthorizationData object. + * @return byte array of encoded AuthorizationData object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + DerOutputStream bytes = new DerOutputStream(); + DerValue der[] = new DerValue[entry.length]; + for (int i = 0; i < entry.length; i++) { + der[i] = new DerValue(entry[i].asn1Encode()); + } + bytes.putSequence(der); + return bytes.toByteArray(); + } /** * Parse (unmarshal) an AuthorizationData object from a DER input stream. @@ -143,31 +142,30 @@ public class AuthorizationData implements Cloneable { * @return an instance of AuthorizationData. * */ - public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException{ - if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag)) { - return null; - } - DerValue der = data.getDerValue(); - if (explicitTag != (der.getTag() & (byte)0x1F)) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - else { - DerValue subDer = der.getData().getDerValue(); - return new AuthorizationData(subDer); - } + public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException { + if ((optional) && (((byte) data.peekByte() & (byte) 0x1F) != explicitTag)) { + return null; } + DerValue der = data.getDerValue(); + if (explicitTag != (der.getTag() & (byte) 0x1F)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } else { + DerValue subDer = der.getData().getDerValue(); + return new AuthorizationData(subDer); + } + } - /** - * Writes AuthorizationData data fields to a output stream. - * - * @param cos a CCacheOutputStream to be written to. - * @exception IOException if an I/O exception occurs. - */ - public void writeAuth(CCacheOutputStream cos) throws IOException { - for (int i = 0; i < entry.length; i++) { - entry[i].writeEntry(cos); - } + /** + * Writes AuthorizationData data fields to a output stream. + * + * @param cos a CCacheOutputStream to be written to. + * @exception IOException if an I/O exception occurs. + */ + public void writeAuth(CCacheOutputStream cos) throws IOException { + for (int i = 0; i < entry.length; i++) { + entry[i].writeEntry(cos); } + } public String toString() { String retVal = "AuthorizationData:\n"; diff --git a/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java index 3ad64576175..e159c85fc00 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java @@ -35,90 +35,90 @@ import sun.security.krb5.Asn1Exception; import sun.security.krb5.internal.ccache.CCacheOutputStream; public class AuthorizationDataEntry implements Cloneable { - public int adType; - public byte[] adData; - private AuthorizationDataEntry() { + public int adType; + public byte[] adData; + + private AuthorizationDataEntry() { + } + + public AuthorizationDataEntry( + int new_adType, + byte[] new_adData) { + adType = new_adType; + adData = new_adData; + } + + public Object clone() { + AuthorizationDataEntry new_authorizationDataEntry = + new AuthorizationDataEntry(); + new_authorizationDataEntry.adType = adType; + if (adData != null) { + new_authorizationDataEntry.adData = new byte[adData.length]; + System.arraycopy(adData, 0, + new_authorizationDataEntry.adData, 0, adData.length); } + return new_authorizationDataEntry; + } - public AuthorizationDataEntry( - int new_adType, - byte[] new_adData - ) { - adType = new_adType; - adData = new_adData; - } - - public Object clone() { - AuthorizationDataEntry new_authorizationDataEntry = - new AuthorizationDataEntry(); - new_authorizationDataEntry.adType = adType; - if (adData != null) { - new_authorizationDataEntry.adData = new byte[adData.length]; - System.arraycopy(adData, 0, - new_authorizationDataEntry.adData, 0, adData.length); - } - return new_authorizationDataEntry; - } - - /** - * Constructs an instance of AuthorizationDataEntry. - * @param encoding a single DER-encoded value. - */ - public AuthorizationDataEntry(DerValue encoding) throws Asn1Exception, IOException { - DerValue der; + /** + * Constructs an instance of AuthorizationDataEntry. + * @param encoding a single DER-encoded value. + */ + public AuthorizationDataEntry(DerValue encoding) throws Asn1Exception, IOException { + DerValue der; if (encoding.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - der = encoding.getData().getDerValue(); - if ((der.getTag() & (byte)0x1F) == (byte)0x00) { - adType = der.getData().getBigInteger().intValue(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } der = encoding.getData().getDerValue(); - if ((der.getTag() & (byte)0x1F) == (byte)0x01) { - adData = der.getData().getOctetString(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - if (encoding.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + if ((der.getTag() & (byte) 0x1F) == (byte) 0x00) { + adType = der.getData().getBigInteger().intValue(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + der = encoding.getData().getDerValue(); + if ((der.getTag() & (byte) 0x1F) == (byte) 0x01) { + adData = der.getData().getOctetString(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if (encoding.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an AuthorizationDataEntry object. - * @return byte array of encoded AuthorizationDataEntry object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an AuthorizationDataEntry object. + * @return byte array of encoded AuthorizationDataEntry object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(adType); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putOctetString(adData); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - return temp.toByteArray(); - } + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(adType); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putOctetString(adData); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), temp); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + return temp.toByteArray(); + } - /** - * Writes the entry's data fields in FCC format to an output stream. - * - * @param cos a CCacheOutputStream. - * @exception IOException if an I/O exception occurs. - */ - public void writeEntry(CCacheOutputStream cos) throws IOException { - cos.write16(adType); - cos.write32(adData.length); - cos.write(adData, 0, adData.length); - } + /** + * Writes the entry's data fields in FCC format to an output stream. + * + * @param cos a CCacheOutputStream. + * @exception IOException if an I/O exception occurs. + */ + public void writeEntry(CCacheOutputStream cos) throws IOException { + cos.write16(adType); + cos.write32(adData.length); + cos.write(adData, 0, adData.length); + } public String toString() { return ("adType=" + adType + " adData.length=" + adData.length); } - } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java index 1d3381797e0..b3dcf144159 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java @@ -55,102 +55,111 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncAPRepPart { - public KerberosTime ctime; - public int cusec; + + public KerberosTime ctime; + public int cusec; EncryptionKey subKey; //optional Integer seqNumber; //optional - public EncAPRepPart( - KerberosTime new_ctime, - int new_cusec, - EncryptionKey new_subKey, - Integer new_seqNumber - ) { - ctime = new_ctime; - cusec = new_cusec; - subKey = new_subKey; - seqNumber = new_seqNumber; - } + public EncAPRepPart( + KerberosTime new_ctime, + int new_cusec, + EncryptionKey new_subKey, + Integer new_seqNumber) { + ctime = new_ctime; + cusec = new_cusec; + subKey = new_subKey; + seqNumber = new_seqNumber; + } - public EncAPRepPart(byte[] data) - throws Asn1Exception, IOException { - init(new DerValue(data)); - } + public EncAPRepPart(byte[] data) + throws Asn1Exception, IOException { + init(new DerValue(data)); + } - public EncAPRepPart(DerValue encoding) - throws Asn1Exception, IOException { - init(encoding); - } + public EncAPRepPart(DerValue encoding) + throws Asn1Exception, IOException { + init(encoding); + } - /** - * Initializes an EncaPRepPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - private void init(DerValue encoding) throws Asn1Exception, IOException { - DerValue der, subDer; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x1B) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + /** + * Initializes an EncaPRepPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + private void init(DerValue encoding) throws Asn1Exception, IOException { + DerValue der, subDer; + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1B) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - ctime = KerberosTime.parse(der.getData(), (byte)0x00, true); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x01) { - cusec = subDer.getData().getBigInteger().intValue(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - if (der.getData().available() > 0) { - subKey = EncryptionKey.parse(der.getData(), (byte)0x02, true); - } - else { - subKey = null; - seqNumber = null; - } - if (der.getData().available() > 0) { - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) != 0x03) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); - } - else seqNumber = null; - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + ctime = KerberosTime.parse(der.getData(), (byte) 0x00, true); + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x01) { + cusec = subDer.getData().getBigInteger().intValue(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if (der.getData().available() > 0) { + subKey = EncryptionKey.parse(der.getData(), (byte) 0x02, true); + } else { + subKey = null; + seqNumber = null; + } + if (der.getData().available() > 0) { + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) != 0x03) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); + } else { + seqNumber = null; + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an EncAPRepPart object. - * @return byte array of encoded EncAPRepPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException{ - Vector v = new Vector (); + /** + * Encodes an EncAPRepPart object. + * @return byte array of encoded EncAPRepPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + Vector v = new Vector(); DerOutputStream temp = new DerOutputStream(); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), ctime.asn1Encode())); - temp.putInteger(BigInteger.valueOf(cusec)); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp.toByteArray())); - if (subKey != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), subKey.asn1Encode())); - if (seqNumber != null) { - temp = new DerOutputStream(); - // encode as an unsigned integer (UInt32) - temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp.toByteArray())); - } - DerValue der[] = new DerValue[v.size()]; - v.copyInto(der); - temp = new DerOutputStream(); - temp.putSequence(der); - DerOutputStream out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1B), temp); - return out.toByteArray(); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), ctime.asn1Encode())); + temp.putInteger(BigInteger.valueOf(cusec)); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp.toByteArray())); + if (subKey != null) { + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), subKey.asn1Encode())); } + if (seqNumber != null) { + temp = new DerOutputStream(); + // encode as an unsigned integer (UInt32) + temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), temp.toByteArray())); + } + DerValue der[] = new DerValue[v.size()]; + v.copyInto(der); + temp = new DerOutputStream(); + temp.putSequence(der); + DerOutputStream out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x1B), temp); + return out.toByteArray(); + } public final EncryptionKey getSubKey() { return subKey; @@ -159,5 +168,4 @@ public class EncAPRepPart { public final Integer getSeqNumber() { return seqNumber; } - } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java index b5526e8014d..b71238fef51 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java @@ -36,57 +36,55 @@ import java.io.IOException; public class EncASRepPart extends EncKDCRepPart { - public EncASRepPart( - EncryptionKey new_key, - LastReq new_lastReq, - int new_nonce, - KerberosTime new_keyExpiration, - TicketFlags new_flags, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - Realm new_srealm, - PrincipalName new_sname, - HostAddresses new_caddr - ) { - super( - new_key, - new_lastReq, - new_nonce, - new_keyExpiration, - new_flags, - new_authtime, - new_starttime, - new_endtime, - new_renewTill, - new_srealm, - new_sname, - new_caddr, - Krb5.KRB_ENC_AS_REP_PART - //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic - //behavior of other implementaions, instead of above + public EncASRepPart( + EncryptionKey new_key, + LastReq new_lastReq, + int new_nonce, + KerberosTime new_keyExpiration, + TicketFlags new_flags, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + Realm new_srealm, + PrincipalName new_sname, + HostAddresses new_caddr) { + super( + new_key, + new_lastReq, + new_nonce, + new_keyExpiration, + new_flags, + new_authtime, + new_starttime, + new_endtime, + new_renewTill, + new_srealm, + new_sname, + new_caddr, + Krb5.KRB_ENC_AS_REP_PART ); - } + //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic + //behavior of other implementaions, instead of above + } - public EncASRepPart(byte[] data) throws Asn1Exception, - IOException, KrbException { - init(new DerValue(data)); - } + public EncASRepPart(byte[] data) throws Asn1Exception, + IOException, KrbException { + init(new DerValue(data)); + } - public EncASRepPart(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding); - } + public EncASRepPart(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding); + } - private void init(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding, Krb5.KRB_ENC_AS_REP_PART); - } - - public byte[] asn1Encode() throws Asn1Exception, - IOException { - return asn1Encode(Krb5.KRB_ENC_AS_REP_PART); - } + private void init(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding, Krb5.KRB_ENC_AS_REP_PART); + } + public byte[] asn1Encode() throws Asn1Exception, + IOException { + return asn1Encode(Krb5.KRB_ENC_AS_REP_PART); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java index 35081a0051c..e7723a41c42 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java @@ -36,6 +36,7 @@ import sun.security.util.*; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 EncKDCRepPart type. * @@ -63,143 +64,163 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncKDCRepPart { - public EncryptionKey key; - public LastReq lastReq; - public int nonce; - public KerberosTime keyExpiration; //optional - public TicketFlags flags; - public KerberosTime authtime; - public KerberosTime starttime; //optional - public KerberosTime endtime; - public KerberosTime renewTill; //optional - public Realm srealm; - public PrincipalName sname; - public HostAddresses caddr; //optional - public int msgType; //not included in sequence - public EncKDCRepPart( - EncryptionKey new_key, - LastReq new_lastReq, - int new_nonce, - KerberosTime new_keyExpiration, - TicketFlags new_flags, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - Realm new_srealm, - PrincipalName new_sname, - HostAddresses new_caddr, - int new_msgType - ) { - key = new_key; - lastReq = new_lastReq; - nonce = new_nonce; - keyExpiration = new_keyExpiration; - flags = new_flags; - authtime = new_authtime; - starttime = new_starttime; - endtime = new_endtime; - renewTill = new_renewTill; - srealm = new_srealm; - sname = new_sname; - caddr = new_caddr; - msgType = new_msgType; - } + public EncryptionKey key; + public LastReq lastReq; + public int nonce; + public KerberosTime keyExpiration; //optional + public TicketFlags flags; + public KerberosTime authtime; + public KerberosTime starttime; //optional + public KerberosTime endtime; + public KerberosTime renewTill; //optional + public Realm srealm; + public PrincipalName sname; + public HostAddresses caddr; //optional + public int msgType; //not included in sequence - public EncKDCRepPart() { - } + public EncKDCRepPart( + EncryptionKey new_key, + LastReq new_lastReq, + int new_nonce, + KerberosTime new_keyExpiration, + TicketFlags new_flags, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + Realm new_srealm, + PrincipalName new_sname, + HostAddresses new_caddr, + int new_msgType) { + key = new_key; + lastReq = new_lastReq; + nonce = new_nonce; + keyExpiration = new_keyExpiration; + flags = new_flags; + authtime = new_authtime; + starttime = new_starttime; + endtime = new_endtime; + renewTill = new_renewTill; + srealm = new_srealm; + sname = new_sname; + caddr = new_caddr; + msgType = new_msgType; + } - public EncKDCRepPart(byte[] data, int rep_type) - throws Asn1Exception, IOException, RealmException{ - init(new DerValue(data), rep_type); - } + public EncKDCRepPart() { + } - public EncKDCRepPart(DerValue encoding, int rep_type) - throws Asn1Exception, IOException, RealmException - { - init(encoding, rep_type); - } + public EncKDCRepPart(byte[] data, int rep_type) + throws Asn1Exception, IOException, RealmException { + init(new DerValue(data), rep_type); + } - /** - * Initializes an EncKDCRepPart object. - * - * @param encoding a single DER-encoded value. - * @param rep_type type of the encrypted reply message. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while decoding an Realm object. - */ - protected void init(DerValue encoding, int rep_type) - throws Asn1Exception, IOException, RealmException - { - DerValue der, subDer; - //implementations return the incorrect tag value, so - //we don't use the above line; instead we use the following - msgType = (encoding.getTag() & (byte)0x1F); + public EncKDCRepPart(DerValue encoding, int rep_type) + throws Asn1Exception, IOException, RealmException { + init(encoding, rep_type); + } + + /** + * Initializes an EncKDCRepPart object. + * + * @param encoding a single DER-encoded value. + * @param rep_type type of the encrypted reply message. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while decoding an Realm object. + */ + protected void init(DerValue encoding, int rep_type) + throws Asn1Exception, IOException, RealmException { + DerValue der, subDer; + //implementations return the incorrect tag value, so + //we don't use the above line; instead we use the following + msgType = (encoding.getTag() & (byte) 0x1F); if (msgType != Krb5.KRB_ENC_AS_REP_PART && - msgType != Krb5.KRB_ENC_TGS_REP_PART) + msgType != Krb5.KRB_ENC_TGS_REP_PART) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - key = EncryptionKey.parse(der.getData(), (byte)0x00, false); - lastReq = LastReq.parse(der.getData(), (byte)0x01, false); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x02) - nonce = subDer.getData().getBigInteger().intValue(); - else throw new Asn1Exception(Krb5.ASN1_BAD_ID); - keyExpiration = KerberosTime.parse(der.getData(), (byte)0x03, true); - flags = TicketFlags.parse(der.getData(), (byte)0x04, false); - authtime = KerberosTime.parse(der.getData(), (byte)0x05, false); - starttime = KerberosTime.parse(der.getData(), (byte)0x06, true); - endtime = KerberosTime.parse(der.getData(), (byte)0x07, false); - renewTill = KerberosTime.parse(der.getData(), (byte)0x08, true); - srealm = Realm.parse(der.getData(), (byte)0x09, false); - sname = PrincipalName.parse(der.getData(), (byte)0x0A, false); - if (der.getData().available() > 0) - caddr = HostAddresses.parse(der.getData(), (byte)0x0B, true); - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + key = EncryptionKey.parse(der.getData(), (byte) 0x00, false); + lastReq = LastReq.parse(der.getData(), (byte) 0x01, false); + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x02) { + nonce = subDer.getData().getBigInteger().intValue(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + keyExpiration = KerberosTime.parse(der.getData(), (byte) 0x03, true); + flags = TicketFlags.parse(der.getData(), (byte) 0x04, false); + authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false); + starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true); + endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false); + renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true); + srealm = Realm.parse(der.getData(), (byte) 0x09, false); + sname = PrincipalName.parse(der.getData(), (byte) 0x0A, false); + if (der.getData().available() > 0) { + caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true); + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an EncKDCRepPart object. - * @param rep_type type of encrypted reply message. - * @return byte array of encoded EncKDCRepPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode(int rep_type) throws Asn1Exception, - IOException { + /** + * Encodes an EncKDCRepPart object. + * @param rep_type type of encrypted reply message. + * @return byte array of encoded EncKDCRepPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode(int rep_type) throws Asn1Exception, + IOException { DerOutputStream temp = new DerOutputStream(); DerOutputStream bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), key.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), lastReq.asn1Encode()); - temp.putInteger(BigInteger.valueOf(nonce)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), key.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), lastReq.asn1Encode()); + temp.putInteger(BigInteger.valueOf(nonce)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), temp); - if (keyExpiration != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), keyExpiration.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), flags.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), authtime.asn1Encode()); - if (starttime != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), starttime.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), endtime.asn1Encode()); - if (renewTill != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), renewTill.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), srealm.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), sname.asn1Encode()); - if (caddr != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0B), caddr.asn1Encode()); - //should use the rep_type to build the encoding - //but other implementations do not; it is ignored and - //the cached msgType is used instead - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)msgType), temp); - return bytes.toByteArray(); + if (keyExpiration != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), keyExpiration.asn1Encode()); } - + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), flags.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), authtime.asn1Encode()); + if (starttime != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x06), starttime.asn1Encode()); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x07), endtime.asn1Encode()); + if (renewTill != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x08), renewTill.asn1Encode()); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x09), srealm.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x0A), sname.asn1Encode()); + if (caddr != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x0B), caddr.asn1Encode()); + } + //should use the rep_type to build the encoding + //but other implementations do not; it is ignored and + //the cached msgType is used instead + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) msgType), temp); + return bytes.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java index f37f252bbaa..c5acf6d2b1c 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java @@ -36,6 +36,7 @@ import sun.security.krb5.RealmException; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 EncKrbCredPart type. * @@ -57,148 +58,158 @@ import java.math.BigInteger; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncKrbCredPart { - public KrbCredInfo[] ticketInfo = null; - public KerberosTime timeStamp; //optional - private Integer nonce; //optional - private Integer usec; //optional - private HostAddress sAddress; //optional - private HostAddresses rAddress; //optional + public KrbCredInfo[] ticketInfo = null; + public KerberosTime timeStamp; //optional + private Integer nonce; //optional + private Integer usec; //optional + private HostAddress sAddress; //optional + private HostAddresses rAddress; //optional - public EncKrbCredPart( - KrbCredInfo[] new_ticketInfo, - KerberosTime new_timeStamp, - Integer new_usec, - Integer new_nonce, - HostAddress new_sAddress, - HostAddresses new_rAddress - ) throws IOException { - if (new_ticketInfo != null) { - ticketInfo = new KrbCredInfo[new_ticketInfo.length]; - for (int i = 0; i < new_ticketInfo.length; i++) { - if (new_ticketInfo[i] == null) { - throw new IOException("Cannot create a EncKrbCredPart"); - } else { - ticketInfo[i] = (KrbCredInfo)new_ticketInfo[i].clone(); - } - } + public EncKrbCredPart( + KrbCredInfo[] new_ticketInfo, + KerberosTime new_timeStamp, + Integer new_usec, + Integer new_nonce, + HostAddress new_sAddress, + HostAddresses new_rAddress) throws IOException { + if (new_ticketInfo != null) { + ticketInfo = new KrbCredInfo[new_ticketInfo.length]; + for (int i = 0; i < new_ticketInfo.length; i++) { + if (new_ticketInfo[i] == null) { + throw new IOException("Cannot create a EncKrbCredPart"); + } else { + ticketInfo[i] = (KrbCredInfo) new_ticketInfo[i].clone(); } - timeStamp = new_timeStamp; - usec = new_usec; - nonce = new_nonce; - sAddress = new_sAddress; - rAddress = new_rAddress; + } } + timeStamp = new_timeStamp; + usec = new_usec; + nonce = new_nonce; + sAddress = new_sAddress; + rAddress = new_rAddress; + } - public EncKrbCredPart(byte[] data) throws Asn1Exception, - IOException, RealmException { - init(new DerValue(data)); - } + public EncKrbCredPart(byte[] data) throws Asn1Exception, + IOException, RealmException { + init(new DerValue(data)); + } - public EncKrbCredPart(DerValue encoding) throws Asn1Exception, - IOException, RealmException { - init(encoding); - } + public EncKrbCredPart(DerValue encoding) throws Asn1Exception, + IOException, RealmException { + init(encoding); + } - /** - * Initializes an EncKrbCredPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) throws Asn1Exception, - IOException, RealmException { - DerValue der, subDer; - //may not be the correct error code for a tag - //mismatch on an encrypted structure - nonce = null; - timeStamp = null; - usec= null; + /** + * Initializes an EncKrbCredPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) throws Asn1Exception, + IOException, RealmException { + DerValue der, subDer; + //may not be the correct error code for a tag + //mismatch on an encrypted structure + nonce = null; + timeStamp = null; + usec = null; sAddress = null; rAddress = null; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x1D) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1D) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) { + DerValue derValues[] = subDer.getData().getSequence(1); + ticketInfo = new KrbCredInfo[derValues.length]; + for (int i = 0; i < derValues.length; i++) { + ticketInfo[i] = new KrbCredInfo(derValues[i]); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if (der.getData().available() > 0) { + if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x01) { subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x00) { - DerValue derValues[] = subDer.getData().getSequence(1); - ticketInfo = new KrbCredInfo[derValues.length]; - for (int i = 0; i < derValues.length; i++) { - ticketInfo[i] = new KrbCredInfo(derValues[i]); - } - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - if (der.getData().available() > 0) { - if (((byte)(der.getData().peekByte()) & (byte)0x1F) == (byte)0x01) { - subDer = der.getData().getDerValue(); - nonce = new Integer(subDer.getData().getBigInteger().intValue()); - } - } - if (der.getData().available() >0) { - timeStamp = KerberosTime.parse(der.getData(), (byte)0x02, true); - } - if (der.getData().available() >0) { - if (((byte)(der.getData().peekByte()) & (byte)0x1F) == (byte)0x03) { - subDer = der.getData().getDerValue(); - usec = new Integer(subDer.getData().getBigInteger().intValue()); - } - } - if (der.getData().available() >0) { - sAddress = HostAddress.parse(der.getData(), (byte)0x04, true); - } - if (der.getData().available() >0) { - rAddress = HostAddresses.parse(der.getData(), (byte)0x05, true); - } - if (der.getData().available() >0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + nonce = new Integer(subDer.getData().getBigInteger().intValue()); + } } + if (der.getData().available() > 0) { + timeStamp = KerberosTime.parse(der.getData(), (byte) 0x02, true); + } + if (der.getData().available() > 0) { + if (((byte) (der.getData().peekByte()) & (byte) 0x1F) == (byte) 0x03) { + subDer = der.getData().getDerValue(); + usec = new Integer(subDer.getData().getBigInteger().intValue()); + } + } + if (der.getData().available() > 0) { + sAddress = HostAddress.parse(der.getData(), (byte) 0x04, true); + } + if (der.getData().available() > 0) { + rAddress = HostAddresses.parse(der.getData(), (byte) 0x05, true); + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an EncKrbCredPart object. - * @return byte array of encoded EncKrbCredPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * - */ - public byte[] asn1Encode() throws Asn1Exception, IOException{ + /** + * Encodes an EncKrbCredPart object. + * @return byte array of encoded EncKrbCredPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - DerValue[] tickets = new DerValue[ticketInfo.length]; - for (int i = 0; i < ticketInfo.length; i++) - tickets[i] = new DerValue(ticketInfo[i].asn1Encode()); - temp.putSequence(tickets); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - - if (nonce != null) { - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(nonce.intValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - } - if (timeStamp != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), timeStamp.asn1Encode()); - } - if (usec != null) { - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(usec.intValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp); - } - if (sAddress != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sAddress.asn1Encode()); - } - if (rAddress != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), rAddress.asn1Encode()); - } - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1D), temp); - return bytes.toByteArray(); + DerOutputStream temp = new DerOutputStream(); + DerValue[] tickets = new DerValue[ticketInfo.length]; + for (int i = 0; i < ticketInfo.length; i++) { + tickets[i] = new DerValue(ticketInfo[i].asn1Encode()); } + temp.putSequence(tickets); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), temp); + + if (nonce != null) { + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(nonce.intValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + } + if (timeStamp != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), timeStamp.asn1Encode()); + } + if (usec != null) { + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(usec.intValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), temp); + } + if (sAddress != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), sAddress.asn1Encode()); + } + if (rAddress != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), rAddress.asn1Encode()); + } + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x1D), temp); + return bytes.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java index e4ed50b4ba1..292dd58be3b 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java @@ -55,114 +55,119 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class EncKrbPrivPart { - public byte[] userData = null; - public KerberosTime timestamp; //optional - public Integer usec; //optional - public Integer seqNumber; //optional - public HostAddress sAddress; //optional - public HostAddress rAddress; //optional - public EncKrbPrivPart( - byte[] new_userData, - KerberosTime new_timestamp, - Integer new_usec, - Integer new_seqNumber, - HostAddress new_sAddress, - HostAddress new_rAddress - ) { - if (new_userData != null) { - userData = new_userData.clone(); - } - timestamp = new_timestamp; - usec = new_usec; - seqNumber = new_seqNumber; - sAddress = new_sAddress; - rAddress = new_rAddress; + public byte[] userData = null; + public KerberosTime timestamp; //optional + public Integer usec; //optional + public Integer seqNumber; //optional + public HostAddress sAddress; //optional + public HostAddress rAddress; //optional + + public EncKrbPrivPart( + byte[] new_userData, + KerberosTime new_timestamp, + Integer new_usec, + Integer new_seqNumber, + HostAddress new_sAddress, + HostAddress new_rAddress) { + if (new_userData != null) { + userData = new_userData.clone(); } + timestamp = new_timestamp; + usec = new_usec; + seqNumber = new_seqNumber; + sAddress = new_sAddress; + rAddress = new_rAddress; + } - public EncKrbPrivPart(byte[] data) throws Asn1Exception, IOException { - init(new DerValue(data)); - } + public EncKrbPrivPart(byte[] data) throws Asn1Exception, IOException { + init(new DerValue(data)); + } - public EncKrbPrivPart(DerValue encoding) throws Asn1Exception, IOException { - init(encoding); - } + public EncKrbPrivPart(DerValue encoding) throws Asn1Exception, IOException { + init(encoding); + } - /** - * Initializes an EncKrbPrivPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - private void init(DerValue encoding) throws Asn1Exception, IOException { + /** + * Initializes an EncKrbPrivPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + private void init(DerValue encoding) throws Asn1Exception, IOException { DerValue der, subDer; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x1C) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x1C) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & (byte)0x1F) == (byte)0x00) { - userData = subDer.getData().getOctetString(); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - timestamp = KerberosTime.parse(der.getData(), (byte)0x01, true); - if ((der.getData().peekByte() & 0x1F) == 0x02) { - subDer = der.getData().getDerValue(); - usec = new Integer(subDer.getData().getBigInteger().intValue()); - } - else usec = null; - if ((der.getData().peekByte() & 0x1F) == 0x03 ) { - subDer = der.getData().getDerValue(); - seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); - } - else seqNumber = null; - sAddress = HostAddress.parse(der.getData(), (byte)0x04, false); - if (der.getData().available() > 0) { - rAddress = HostAddress.parse(der.getData(), (byte)0x05, true); - } - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & (byte) 0x1F) == (byte) 0x00) { + userData = subDer.getData().getOctetString(); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + timestamp = KerberosTime.parse(der.getData(), (byte) 0x01, true); + if ((der.getData().peekByte() & 0x1F) == 0x02) { + subDer = der.getData().getDerValue(); + usec = new Integer(subDer.getData().getBigInteger().intValue()); + } else { + usec = null; + } + if ((der.getData().peekByte() & 0x1F) == 0x03) { + subDer = der.getData().getDerValue(); + seqNumber = new Integer(subDer.getData().getBigInteger().intValue()); + } else { + seqNumber = null; + } + sAddress = HostAddress.parse(der.getData(), (byte) 0x04, false); + if (der.getData().available() > 0) { + rAddress = HostAddress.parse(der.getData(), (byte) 0x05, true); + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an EncKrbPrivPart object. - * @return byte array of encoded EncKrbPrivPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an EncKrbPrivPart object. + * @return byte array of encoded EncKrbPrivPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream temp = new DerOutputStream(); DerOutputStream bytes = new DerOutputStream(); - temp.putOctetString(userData); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - if (timestamp != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), timestamp.asn1Encode()); - if (usec != null) { - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(usec.intValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); - } - if (seqNumber != null) { - temp = new DerOutputStream(); - // encode as an unsigned integer (UInt32) - temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), temp); - } - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), sAddress.asn1Encode()); - if (rAddress != null) { - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), rAddress.asn1Encode()); - } - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x1C), temp); - return bytes.toByteArray(); + temp.putOctetString(userData); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x00), temp); + if (timestamp != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x01), timestamp.asn1Encode()); } + if (usec != null) { + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(usec.intValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x02), temp); + } + if (seqNumber != null) { + temp = new DerOutputStream(); + // encode as an unsigned integer (UInt32) + temp.putInteger(BigInteger.valueOf(seqNumber.longValue())); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x03), temp); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x04), sAddress.asn1Encode()); + if (rAddress != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte) 0x05), rAddress.asn1Encode()); + } + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte) 0x1C), temp); + return bytes.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java index 95c100a020a..864115e52e9 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java @@ -35,55 +35,52 @@ import java.io.IOException; public class EncTGSRepPart extends EncKDCRepPart { - public EncTGSRepPart( - EncryptionKey new_key, - LastReq new_lastReq, - int new_nonce, - KerberosTime new_keyExpiration, - TicketFlags new_flags, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - Realm new_srealm, - PrincipalName new_sname, - HostAddresses new_caddr - ) { - super( - new_key, - new_lastReq, - new_nonce, - new_keyExpiration, - new_flags, - new_authtime, - new_starttime, - new_endtime, - new_renewTill, - new_srealm, - new_sname, - new_caddr, - Krb5.KRB_ENC_TGS_REP_PART - ); - } + public EncTGSRepPart( + EncryptionKey new_key, + LastReq new_lastReq, + int new_nonce, + KerberosTime new_keyExpiration, + TicketFlags new_flags, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + Realm new_srealm, + PrincipalName new_sname, + HostAddresses new_caddr) { + super( + new_key, + new_lastReq, + new_nonce, + new_keyExpiration, + new_flags, + new_authtime, + new_starttime, + new_endtime, + new_renewTill, + new_srealm, + new_sname, + new_caddr, + Krb5.KRB_ENC_TGS_REP_PART); + } - public EncTGSRepPart(byte[] data) throws Asn1Exception, - IOException, KrbException { - init(new DerValue(data)); - } + public EncTGSRepPart(byte[] data) throws Asn1Exception, + IOException, KrbException { + init(new DerValue(data)); + } - public EncTGSRepPart(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding); - } + public EncTGSRepPart(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding); + } - private void init(DerValue encoding) throws Asn1Exception, - IOException, KrbException { - init(encoding, Krb5.KRB_ENC_TGS_REP_PART); - } - - public byte[] asn1Encode() throws Asn1Exception, - IOException { - return asn1Encode(Krb5.KRB_ENC_TGS_REP_PART); - } + private void init(DerValue encoding) throws Asn1Exception, + IOException, KrbException { + init(encoding, Krb5.KRB_ENC_TGS_REP_PART); + } + public byte[] asn1Encode() throws Asn1Exception, + IOException { + return asn1Encode(Krb5.KRB_ENC_TGS_REP_PART); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/EncTicketPart.java b/jdk/src/share/classes/sun/security/krb5/internal/EncTicketPart.java index 5f315095825..73eb814445b 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/EncTicketPart.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/EncTicketPart.java @@ -62,69 +62,68 @@ import java.io.*; * http://www.ietf.org/rfc/rfc4120.txt. */ public class EncTicketPart { - public TicketFlags flags; - public EncryptionKey key; - public Realm crealm; - public PrincipalName cname; - public TransitedEncoding transited; - public KerberosTime authtime; - public KerberosTime starttime; //optional - public KerberosTime endtime; - public KerberosTime renewTill; //optional - public HostAddresses caddr; //optional - public AuthorizationData authorizationData; //optional - public EncTicketPart( - TicketFlags new_flags, - EncryptionKey new_key, - Realm new_crealm, - PrincipalName new_cname, - TransitedEncoding new_transited, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - HostAddresses new_caddr, - AuthorizationData new_authorizationData - ) { - flags = new_flags; - key = new_key; - crealm = new_crealm; - cname = new_cname; - transited = new_transited; - authtime = new_authtime; - starttime = new_starttime; - endtime = new_endtime; - renewTill = new_renewTill; - caddr = new_caddr; - authorizationData = new_authorizationData; - } + public TicketFlags flags; + public EncryptionKey key; + public Realm crealm; + public PrincipalName cname; + public TransitedEncoding transited; + public KerberosTime authtime; + public KerberosTime starttime; //optional + public KerberosTime endtime; + public KerberosTime renewTill; //optional + public HostAddresses caddr; //optional + public AuthorizationData authorizationData; //optional - public EncTicketPart(byte[] data) - throws Asn1Exception, KrbException, IOException { - init(new DerValue(data)); - } + public EncTicketPart( + TicketFlags new_flags, + EncryptionKey new_key, + Realm new_crealm, + PrincipalName new_cname, + TransitedEncoding new_transited, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + HostAddresses new_caddr, + AuthorizationData new_authorizationData) { + flags = new_flags; + key = new_key; + crealm = new_crealm; + cname = new_cname; + transited = new_transited; + authtime = new_authtime; + starttime = new_starttime; + endtime = new_endtime; + renewTill = new_renewTill; + caddr = new_caddr; + authorizationData = new_authorizationData; + } - public EncTicketPart(DerValue encoding) - throws Asn1Exception, KrbException, IOException { - init(encoding); - } + public EncTicketPart(byte[] data) + throws Asn1Exception, KrbException, IOException { + init(new DerValue(data)); + } - /** - * Initializes an EncTicketPart object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while parsing a Realm object. - */ + public EncTicketPart(DerValue encoding) + throws Asn1Exception, KrbException, IOException { + init(encoding); + } + /** + * Initializes an EncTicketPart object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while parsing a Realm object. + */ private static String getHexBytes(byte[] bytes, int len) - throws IOException { + throws IOException { StringBuffer sb = new StringBuffer(); for (int i = 0; i < len; i++) { - int b1 = (bytes[i]>>4) & 0x0f; + int b1 = (bytes[i] >> 4) & 0x0f; int b2 = bytes[i] & 0x0f; sb.append(Integer.toHexString(b1)); @@ -134,73 +133,91 @@ public class EncTicketPart { return sb.toString(); } - private void init(DerValue encoding) - throws Asn1Exception, IOException, RealmException { - DerValue der, subDer; + private void init(DerValue encoding) + throws Asn1Exception, IOException, RealmException { + DerValue der, subDer; - renewTill = null; - caddr = null; - authorizationData = null; - if (((encoding.getTag() & (byte)0x1F) != (byte)0x03) + renewTill = null; + caddr = null; + authorizationData = null; + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x03) || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - flags = TicketFlags.parse(der.getData(), (byte)0x00, false); - key = EncryptionKey.parse(der.getData(), (byte)0x01, false); - crealm = Realm.parse(der.getData(), (byte)0x02, false); - cname = PrincipalName.parse(der.getData(), (byte)0x03, false); - transited = TransitedEncoding.parse(der.getData(), (byte)0x04, false); - authtime = KerberosTime.parse(der.getData(), (byte)0x05, false); - starttime = KerberosTime.parse(der.getData(), (byte)0x06, true); - endtime = KerberosTime.parse(der.getData(), (byte)0x07, false); - if (der.getData().available() > 0) { - renewTill = KerberosTime.parse(der.getData(), (byte)0x08, true); - } - if (der.getData().available() > 0) { - caddr = HostAddresses.parse(der.getData(), (byte)0x09, true); - } - if (der.getData().available() > 0) { - authorizationData = AuthorizationData.parse(der.getData(), (byte)0x0A, true); - } - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + flags = TicketFlags.parse(der.getData(), (byte) 0x00, false); + key = EncryptionKey.parse(der.getData(), (byte) 0x01, false); + crealm = Realm.parse(der.getData(), (byte) 0x02, false); + cname = PrincipalName.parse(der.getData(), (byte) 0x03, false); + transited = TransitedEncoding.parse(der.getData(), (byte) 0x04, false); + authtime = KerberosTime.parse(der.getData(), (byte) 0x05, false); + starttime = KerberosTime.parse(der.getData(), (byte) 0x06, true); + endtime = KerberosTime.parse(der.getData(), (byte) 0x07, false); + if (der.getData().available() > 0) { + renewTill = KerberosTime.parse(der.getData(), (byte) 0x08, true); + } + if (der.getData().available() > 0) { + caddr = HostAddresses.parse(der.getData(), (byte) 0x09, true); + } + if (der.getData().available() > 0) { + authorizationData = AuthorizationData.parse(der.getData(), (byte) 0x0A, true); + } + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } - /** - * Encodes an EncTicketPart object. - * @return byte array of encoded EncTicketPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ + } - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an EncTicketPart object. + * @return byte array of encoded EncTicketPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), flags.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), key.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), crealm.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), cname.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), transited.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), authtime.asn1Encode()); - if (starttime != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), starttime.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), endtime.asn1Encode()); - - if (renewTill != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), renewTill.asn1Encode()); - - if (caddr != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), caddr.asn1Encode()); - - if (authorizationData != null) - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), authorizationData.asn1Encode()); - temp.write(DerValue.tag_Sequence, bytes); - bytes = new DerOutputStream(); - bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x03), temp); - return bytes.toByteArray(); + DerOutputStream temp = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), flags.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), key.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), crealm.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), cname.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), transited.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), authtime.asn1Encode()); + if (starttime != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x06), starttime.asn1Encode()); } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x07), endtime.asn1Encode()); + + if (renewTill != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x08), renewTill.asn1Encode()); + } + + if (caddr != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x09), caddr.asn1Encode()); + } + + if (authorizationData != null) { + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x0A), authorizationData.asn1Encode()); + } + temp.write(DerValue.tag_Sequence, bytes); + bytes = new DerOutputStream(); + bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x03), temp); + return bytes.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KDCRep.java b/jdk/src/share/classes/sun/security/krb5/internal/KDCRep.java index ca1d777ed23..f7cc7180082 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/KDCRep.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/KDCRep.java @@ -35,6 +35,7 @@ import sun.security.util.*; import java.util.Vector; import java.io.IOException; import java.math.BigInteger; + /** * Implements the ASN.1 KDC-REP type. * @@ -59,163 +60,168 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class KDCRep { - public Realm crealm; - public PrincipalName cname; - public Ticket ticket; - public EncryptedData encPart; - public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding - private int pvno; - private int msgType; - private PAData[] pAData = null; //optional - private boolean DEBUG = Krb5.DEBUG; + public Realm crealm; + public PrincipalName cname; + public Ticket ticket; + public EncryptedData encPart; + public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding + private int pvno; + private int msgType; + private PAData[] pAData = null; //optional + private boolean DEBUG = Krb5.DEBUG; - public KDCRep( - PAData[] new_pAData, - Realm new_crealm, - PrincipalName new_cname, - Ticket new_ticket, - EncryptedData new_encPart, - int req_type - ) throws IOException { - pvno = Krb5.PVNO; - msgType = req_type; - if (new_pAData != null) { - pAData = new PAData[new_pAData.length]; - for (int i = 0; i < new_pAData.length; i++) { - if (new_pAData[i] == null) { - throw new IOException("Cannot create a KDCRep"); - } else { - pAData[i] = (PAData)new_pAData[i].clone(); - } - } + public KDCRep( + PAData[] new_pAData, + Realm new_crealm, + PrincipalName new_cname, + Ticket new_ticket, + EncryptedData new_encPart, + int req_type) throws IOException { + pvno = Krb5.PVNO; + msgType = req_type; + if (new_pAData != null) { + pAData = new PAData[new_pAData.length]; + for (int i = 0; i < new_pAData.length; i++) { + if (new_pAData[i] == null) { + throw new IOException("Cannot create a KDCRep"); + } else { + pAData[i] = (PAData) new_pAData[i].clone(); } - crealm = new_crealm; - cname = new_cname; - ticket = new_ticket; - encPart = new_encPart; + } } + crealm = new_crealm; + cname = new_cname; + ticket = new_ticket; + encPart = new_encPart; + } - public KDCRep() { - } + public KDCRep() { + } - public KDCRep(byte[] data, int req_type) throws Asn1Exception, KrbApErrException, RealmException, IOException { - init(new DerValue(data), req_type); - } + public KDCRep(byte[] data, int req_type) throws Asn1Exception, + KrbApErrException, RealmException, IOException { + init(new DerValue(data), req_type); + } - public KDCRep(DerValue encoding, int req_type) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding, req_type); - } + public KDCRep(DerValue encoding, int req_type) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding, req_type); + } /* // Not used? Don't know what keyusage to use here %%% - - public void decrypt(EncryptionKey key) throws Asn1Exception, - IOException, KrbException, RealmException { - encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), - msgType); - } -*/ - - /** - * Initializes an KDCRep object. - * - * @param encoding a single DER-encoded value. - * @param req_type reply message type. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception RealmException if an error occurs while constructing a Realm object from DER-encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value. - * - */ - protected void init(DerValue encoding, int req_type) + public void decrypt(EncryptionKey key) throws Asn1Exception, + IOException, KrbException, RealmException { + encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), msgType); + } + */ + /** + * Initializes an KDCRep object. + * + * @param encoding a single DER-encoded value. + * @param req_type reply message type. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception RealmException if an error occurs while constructing + * a Realm object from DER-encoded data. + * @exception KrbApErrException if the value read from the DER-encoded + * data stream does not match the pre-defined value. + * + */ + protected void init(DerValue encoding, int req_type) throws Asn1Exception, RealmException, IOException, - KrbApErrException { - DerValue der, subDer; - if ((encoding.getTag() & 0x1F) != req_type) { - if (DEBUG) { - System.out.println(">>> KDCRep: init() " + - "encoding tag is " + - encoding.getTag() + - " req type is " + req_type); - } - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x00) { - pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - } else { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x01) { - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != req_type) { - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - } - } else { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - if ((der.getData().peekByte() & 0x1F) == 0x02) { - subDer = der.getData().getDerValue(); - DerValue[] padata = subDer.getData().getSequence(1); - pAData = new PAData[padata.length]; - for (int i = 0; i < padata.length; i++) { - pAData[i] = new PAData(padata[i]); - } - } else { - pAData = null; - } - crealm = Realm.parse(der.getData(), (byte)0x03, false); - cname = PrincipalName.parse(der.getData(), (byte)0x04, false); - ticket = Ticket.parse(der.getData(), (byte)0x05, false); - encPart = EncryptedData.parse(der.getData(), (byte)0x06, false); - if (der.getData().available() > 0) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + KrbApErrException { + DerValue der, subDer; + if ((encoding.getTag() & 0x1F) != req_type) { + if (DEBUG) { + System.out.println(">>> KDCRep: init() " + + "encoding tag is " + + encoding.getTag() + + " req type is " + req_type); } + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } - - - /** - * Encodes this object to a byte array. - * @return byte array of encoded APReq object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { - - DerOutputStream bytes = new DerOutputStream(); - DerOutputStream temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - if (pAData != null && pAData.length > 0) { - DerOutputStream padata_stream = new DerOutputStream(); - for (int i = 0; i < pAData.length; i++) { - padata_stream.write(pAData[i].asn1Encode()); - } - temp = new DerOutputStream(); - temp.write(DerValue.tag_SequenceOf, padata_stream); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); - } - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), crealm.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), cname.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), ticket.asn1Encode()); - bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), encPart.asn1Encode()); - temp = new DerOutputStream(); - temp.write(DerValue.tag_Sequence, bytes); - return temp.toByteArray(); + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x00) { + pvno = subDer.getData().getBigInteger().intValue(); + if (pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x01) { + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != req_type) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + if ((der.getData().peekByte() & 0x1F) == 0x02) { + subDer = der.getData().getDerValue(); + DerValue[] padata = subDer.getData().getSequence(1); + pAData = new PAData[padata.length]; + for (int i = 0; i < padata.length; i++) { + pAData[i] = new PAData(padata[i]); + } + } else { + pAData = null; + } + crealm = Realm.parse(der.getData(), (byte) 0x03, false); + cname = PrincipalName.parse(der.getData(), (byte) 0x04, false); + ticket = Ticket.parse(der.getData(), (byte) 0x05, false); + encPart = EncryptedData.parse(der.getData(), (byte) 0x06, false); + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } + + /** + * Encodes this object to a byte array. + * @return byte array of encoded APReq object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { + + DerOutputStream bytes = new DerOutputStream(); + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + if (pAData != null && pAData.length > 0) { + DerOutputStream padata_stream = new DerOutputStream(); + for (int i = 0; i < pAData.length; i++) { + padata_stream.write(pAData[i].asn1Encode()); + } + temp = new DerOutputStream(); + temp.write(DerValue.tag_SequenceOf, padata_stream); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), temp); + } + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), crealm.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), cname.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x05), ticket.asn1Encode()); + bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x06), encPart.asn1Encode()); + temp = new DerOutputStream(); + temp.write(DerValue.tag_Sequence, bytes); + return temp.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java b/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java index 2f049895695..fee4567c3c6 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java @@ -56,155 +56,160 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class KDCReq { - public KDCReqBody reqBody; - private int pvno; - private int msgType; - private PAData[] pAData = null; //optional + public KDCReqBody reqBody; + private int pvno; + private int msgType; + private PAData[] pAData = null; //optional - public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody, - int req_type) throws IOException { - pvno = Krb5.PVNO; - msgType = req_type; - if (new_pAData != null) { - pAData = new PAData[new_pAData.length]; - for (int i = 0; i < new_pAData.length; i++) { - if (new_pAData[i] == null) { - throw new IOException("Cannot create a KDCRep"); - } else { - pAData[i] = (PAData)new_pAData[i].clone(); - } - } + public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody, + int req_type) throws IOException { + pvno = Krb5.PVNO; + msgType = req_type; + if (new_pAData != null) { + pAData = new PAData[new_pAData.length]; + for (int i = 0; i < new_pAData.length; i++) { + if (new_pAData[i] == null) { + throw new IOException("Cannot create a KDCRep"); + } else { + pAData[i] = (PAData) new_pAData[i].clone(); } - reqBody = new_reqBody; + } } + reqBody = new_reqBody; + } - public KDCReq() { - } + public KDCReq() { + } - public KDCReq(byte[] data, int req_type) throws Asn1Exception, - IOException, KrbException { + public KDCReq(byte[] data, int req_type) throws Asn1Exception, + IOException, KrbException { init(new DerValue(data), req_type); - } + } /** - * Creates an KDCReq object from a DerValue object and asn1 type. - * - * @param der a DER value of an KDCReq object. - * @param req_type a encoded asn1 type value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exceptoin KrbErrException - */ + * Creates an KDCReq object from a DerValue object and asn1 type. + * + * @param der a DER value of an KDCReq object. + * @param req_type a encoded asn1 type value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exceptoin KrbErrException + */ public KDCReq(DerValue der, int req_type) throws Asn1Exception, - IOException, KrbException { - init(der, req_type); - } + IOException, KrbException { + init(der, req_type); + } - /** - * Initializes a KDCReq object from a DerValue. The DER encoding - * must be in the format specified by the KRB_KDC_REQ ASN.1 notation. - * - * @param encoding a DER-encoded KDCReq object. - * @param req_type an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbException if an error occurs while constructing a Realm object, - * or a Krb object from DER-encoded data. - */ + /** + * Initializes a KDCReq object from a DerValue. The DER encoding + * must be in the format specified by the KRB_KDC_REQ ASN.1 notation. + * + * @param encoding a DER-encoded KDCReq object. + * @param req_type an int indicating whether it's KRB_AS_REQ or KRB_TGS_REQ type + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbException if an error occurs while constructing a Realm object, + * or a Krb object from DER-encoded data. + */ protected void init(DerValue encoding, int req_type) throws Asn1Exception, - IOException, KrbException { - DerValue der, subDer; - BigInteger bint; - if ((encoding.getTag() & 0x1F) != req_type) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) { + IOException, KrbException { + DerValue der, subDer; + BigInteger bint; + if ((encoding.getTag() & 0x1F) != req_type) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x01) { - bint = subDer.getData().getBigInteger(); - this.pvno = bint.intValue(); - if (this.pvno != Krb5.PVNO) - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x02) { - bint = subDer.getData().getBigInteger(); - this.msgType = bint.intValue(); - if (this.msgType != req_type) - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x03) { - DerValue subsubDer = subDer.getData().getDerValue(); - if (subsubDer.getTag() != DerValue.tag_SequenceOf) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - Vector v = new Vector (); - while (subsubDer.getData().available() > 0) { - v.addElement(new PAData(subsubDer.getData().getDerValue())); - } - if (v.size() > 0) { - pAData = new PAData[v.size()]; - v.copyInto(pAData); - } - } - else pAData = null; - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x04) { - DerValue subsubDer = subDer.getData().getDerValue(); - reqBody = new KDCReqBody(subsubDer, msgType); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x01F) == 0x01) { + bint = subDer.getData().getBigInteger(); + this.pvno = bint.intValue(); + if (this.pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x01F) == 0x02) { + bint = subDer.getData().getBigInteger(); + this.msgType = bint.intValue(); + if (this.msgType != req_type) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x01F) == 0x03) { + DerValue subsubDer = subDer.getData().getDerValue(); + if (subsubDer.getTag() != DerValue.tag_SequenceOf) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + Vector v = new Vector(); + while (subsubDer.getData().available() > 0) { + v.addElement(new PAData(subsubDer.getData().getDerValue())); + } + if (v.size() > 0) { + pAData = new PAData[v.size()]; + v.copyInto(pAData); + } + } else { + pAData = null; + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x01F) == 0x04) { + DerValue subsubDer = subDer.getData().getDerValue(); + reqBody = new KDCReqBody(subsubDer, msgType); + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes this object to a byte array. - * - * @return an byte array of encoded data. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * - */ + /** + * Encodes this object to a byte array. + * + * @return an byte array of encoded data. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * + */ public byte[] asn1Encode() throws Asn1Exception, IOException { - DerOutputStream temp, bytes, out; - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(pvno)); - out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); + DerOutputStream temp, bytes, out; + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(pvno)); + out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + temp = new DerOutputStream(); + temp.putInteger(BigInteger.valueOf(msgType)); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), temp); if (pAData != null && pAData.length > 0) { - temp = new DerOutputStream(); - for (int i = 0; i < pAData.length; i++) { - temp.write(pAData[i].asn1Encode()); - } - bytes = new DerOutputStream(); - bytes.write(DerValue.tag_SequenceOf, temp); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), bytes); - } - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), reqBody.asn1Encode(msgType)); - bytes = new DerOutputStream(); - bytes.write(DerValue.tag_Sequence, out); - out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)msgType), bytes); - return out.toByteArray(); - } - - public byte[] asn1EncodeReqBody() throws Asn1Exception, IOException - { - return reqBody.asn1Encode(msgType); + temp = new DerOutputStream(); + for (int i = 0; i < pAData.length; i++) { + temp.write(pAData[i].asn1Encode()); + } + bytes = new DerOutputStream(); + bytes.write(DerValue.tag_SequenceOf, temp); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), bytes); } + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x04), reqBody.asn1Encode(msgType)); + bytes = new DerOutputStream(); + bytes.write(DerValue.tag_Sequence, out); + out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) msgType), bytes); + return out.toByteArray(); + } + public byte[] asn1EncodeReqBody() throws Asn1Exception, IOException { + return reqBody.asn1Encode(msgType); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KRBCred.java b/jdk/src/share/classes/sun/security/krb5/internal/KRBCred.java index 2c364e834b0..a30ca6d2929 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/KRBCred.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/KRBCred.java @@ -56,128 +56,134 @@ import java.math.BigInteger; * * http://www.ietf.org/rfc/rfc4120.txt. */ - public class KRBCred { - public Ticket[] tickets = null; - public EncryptedData encPart; - private int pvno; - private int msgType; + public Ticket[] tickets = null; + public EncryptedData encPart; + private int pvno; + private int msgType; - public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException { - pvno = Krb5.PVNO; - msgType = Krb5.KRB_CRED; - if (new_tickets != null) { - tickets = new Ticket[new_tickets.length]; - for (int i = 0; i < new_tickets.length; i++) { - if (new_tickets[i] == null) { - throw new IOException("Cannot create a KRBCred"); - } else { - tickets[i] = (Ticket)new_tickets[i].clone(); - } - } + public KRBCred(Ticket[] new_tickets, EncryptedData new_encPart) throws IOException { + pvno = Krb5.PVNO; + msgType = Krb5.KRB_CRED; + if (new_tickets != null) { + tickets = new Ticket[new_tickets.length]; + for (int i = 0; i < new_tickets.length; i++) { + if (new_tickets[i] == null) { + throw new IOException("Cannot create a KRBCred"); + } else { + tickets[i] = (Ticket) new_tickets[i].clone(); } - encPart = new_encPart; + } } + encPart = new_encPart; + } - public KRBCred(byte[] data) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(new DerValue(data)); + public KRBCred(byte[] data) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(new DerValue(data)); + } + + public KRBCred(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + init(encoding); + } + + /** + * Initializes an KRBCred object. + * @param encoding a single DER-encoded value. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + * @exception KrbApErrException if the value read from the DER-encoded data + * stream does not match the pre-defined value. + * @exception RealmException if an error occurs while parsing a Realm object. + */ + private void init(DerValue encoding) throws Asn1Exception, + RealmException, KrbApErrException, IOException { + if (((encoding.getTag() & (byte) 0x1F) != (byte) 0x16) + || (encoding.isApplication() != true) + || (encoding.isConstructed() != true)) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } - - public KRBCred(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - init(encoding); - } - - /** - * Initializes an KRBCred object. - * @param encoding a single DER-encoded value. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - * @exception KrbApErrException if the value read from the DER-encoded data - * stream does not match the pre-defined value. - * @exception RealmException if an error occurs while parsing a Realm object. - */ - private void init(DerValue encoding) throws Asn1Exception, - RealmException, KrbApErrException, IOException { - if (((encoding.getTag() & (byte)0x1F) != (byte)0x16) - || (encoding.isApplication() != true) - || (encoding.isConstructed() != true)) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); DerValue der, subDer; - der = encoding.getData().getDerValue(); - if (der.getTag() != DerValue.tag_Sequence) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x00) { - pvno = subDer.getData().getBigInteger().intValue(); - if (pvno != Krb5.PVNO) { - throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); - } - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x01) { - msgType = subDer.getData().getBigInteger().intValue(); - if (msgType != Krb5.KRB_CRED) - throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x1F) == 0x02) { - DerValue subsubDer = subDer.getData().getDerValue(); - if (subsubDer.getTag() != DerValue.tag_SequenceOf) { - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - } - Vector v = new Vector (); - while (subsubDer.getData().available() > 0) { - v.addElement(new Ticket(subsubDer.getData().getDerValue())); - } - if (v.size() > 0) { - tickets = new Ticket[v.size()]; - v.copyInto(tickets); - } - } - else - throw new Asn1Exception(Krb5.ASN1_BAD_ID); - encPart = EncryptedData.parse(der.getData(), (byte)0x03, false); - - if (der.getData().available() > 0) - throw new Asn1Exception(Krb5.ASN1_BAD_ID); + der = encoding.getData().getDerValue(); + if (der.getTag() != DerValue.tag_Sequence) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x00) { + pvno = subDer.getData().getBigInteger().intValue(); + if (pvno != Krb5.PVNO) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x01) { + msgType = subDer.getData().getBigInteger().intValue(); + if (msgType != Krb5.KRB_CRED) { + throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + subDer = der.getData().getDerValue(); + if ((subDer.getTag() & 0x1F) == 0x02) { + DerValue subsubDer = subDer.getData().getDerValue(); + if (subsubDer.getTag() != DerValue.tag_SequenceOf) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + Vector v = new Vector(); + while (subsubDer.getData().available() > 0) { + v.addElement(new Ticket(subsubDer.getData().getDerValue())); + } + if (v.size() > 0) { + tickets = new Ticket[v.size()]; + v.copyInto(tickets); + } + } else { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + encPart = EncryptedData.parse(der.getData(), (byte) 0x03, false); + if (der.getData().available() > 0) { + throw new Asn1Exception(Krb5.ASN1_BAD_ID); + } + } - /** - * Encodes an KRBCred object. - * @return the data of encoded EncAPRepPart object. - * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. - * @exception IOException if an I/O error occurs while reading encoded data. - */ - public byte[] asn1Encode() throws Asn1Exception, IOException { + /** + * Encodes an KRBCred object. + * @return the data of encoded EncAPRepPart object. + * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. + * @exception IOException if an I/O error occurs while reading encoded data. + */ + public byte[] asn1Encode() throws Asn1Exception, IOException { DerOutputStream temp, bytes, out; temp = new DerOutputStream(); temp.putInteger(BigInteger.valueOf(pvno)); out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); - temp = new DerOutputStream(); - temp.putInteger(BigInteger.valueOf(msgType)); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x00), temp); temp = new DerOutputStream(); - for (int i = 0; i < tickets.length; i++) { - temp.write(tickets[i].asn1Encode()); - } + temp.putInteger(BigInteger.valueOf(msgType)); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x01), temp); + temp = new DerOutputStream(); + for (int i = 0; i < tickets.length; i++) { + temp.write(tickets[i].asn1Encode()); + } bytes = new DerOutputStream(); bytes.write(DerValue.tag_SequenceOf, temp); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), bytes); - out.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), encPart.asn1Encode()); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x02), bytes); + out.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0x03), encPart.asn1Encode()); bytes = new DerOutputStream(); bytes.write(DerValue.tag_Sequence, out); - out = new DerOutputStream(); - out.write(DerValue.createTag(DerValue.TAG_APPLICATION, true, (byte)0x16), bytes); - return out.toByteArray(); - } - + out = new DerOutputStream(); + out.write(DerValue.createTag(DerValue.TAG_APPLICATION, + true, (byte) 0x16), bytes); + return out.toByteArray(); + } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java b/jdk/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java index 3853ab579cc..08a21b66589 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java @@ -111,7 +111,7 @@ public class KrbCredInfo { * @exception RealmException if an error occurs while parsing a Realm object. */ public KrbCredInfo(DerValue encoding) - throws Asn1Exception, IOException, RealmException{ + throws Asn1Exception, IOException, RealmException{ if (encoding.getTag() != DerValue.tag_Sequence) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); } @@ -160,25 +160,25 @@ public class KrbCredInfo { Vector v = new Vector (); v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), key.asn1Encode())); if (prealm != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), prealm.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), prealm.asn1Encode())); if (pname != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), pname.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), pname.asn1Encode())); if (flags != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), flags.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), flags.asn1Encode())); if (authtime != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authtime.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), authtime.asn1Encode())); if (starttime != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), starttime.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), starttime.asn1Encode())); if (endtime != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), endtime.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), endtime.asn1Encode())); if (renewTill != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), renewTill.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x07), renewTill.asn1Encode())); if (srealm != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), srealm.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x08), srealm.asn1Encode())); if (sname != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x09), sname.asn1Encode())); if (caddr != null) - v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), caddr.asn1Encode())); + v.addElement(new DerValue(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0A), caddr.asn1Encode())); DerValue der[] = new DerValue[v.size()]; v.copyInto(der); DerOutputStream out = new DerOutputStream(); diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java b/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java index 4665d9f63dc..0c7b1ed32b2 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java @@ -34,168 +34,171 @@ import sun.security.krb5.*; import sun.security.krb5.internal.*; public class Credentials { - PrincipalName cname; - Realm crealm; + + PrincipalName cname; + Realm crealm; PrincipalName sname; - Realm srealm; - EncryptionKey key; - KerberosTime authtime; - KerberosTime starttime;//optional - KerberosTime endtime; - KerberosTime renewTill; //optional - HostAddresses caddr; //optional; for proxied tickets only + Realm srealm; + EncryptionKey key; + KerberosTime authtime; + KerberosTime starttime;//optional + KerberosTime endtime; + KerberosTime renewTill; //optional + HostAddresses caddr; //optional; for proxied tickets only AuthorizationData authorizationData; //optional, not being actually used public boolean isEncInSKey; // true if ticket is encrypted in another ticket's skey - TicketFlags flags; + TicketFlags flags; Ticket ticket; - Ticket secondTicket; //optional - private boolean DEBUG = Krb5.DEBUG; + Ticket secondTicket; //optional + private boolean DEBUG = Krb5.DEBUG; - public Credentials( - PrincipalName new_cname, - PrincipalName new_sname, - EncryptionKey new_key, - KerberosTime new_authtime, - KerberosTime new_starttime, - KerberosTime new_endtime, - KerberosTime new_renewTill, - boolean new_isEncInSKey, - TicketFlags new_flags, - HostAddresses new_caddr, - AuthorizationData new_authData, - Ticket new_ticket, - Ticket new_secondTicket) { - cname = (PrincipalName)new_cname.clone(); - if (new_cname.getRealm() != null) - crealm = (Realm)new_cname.getRealm().clone(); - - sname = (PrincipalName)new_sname.clone(); - if (new_sname.getRealm() != null) - srealm = (Realm)new_sname.getRealm().clone(); - - key = (EncryptionKey)new_key.clone(); - - authtime = (KerberosTime)new_authtime.clone(); - starttime = (KerberosTime)new_starttime.clone(); - endtime = (KerberosTime)new_endtime.clone(); - renewTill = (KerberosTime)new_renewTill.clone(); - if (new_caddr != null) - caddr = (HostAddresses)new_caddr.clone(); - if (new_authData != null) { - authorizationData - = (AuthorizationData)new_authData.clone(); - } - - isEncInSKey = new_isEncInSKey; - flags = (TicketFlags)new_flags.clone(); - ticket = (Ticket)(new_ticket.clone()); - if (new_secondTicket != null) - secondTicket = (Ticket)new_secondTicket.clone(); + public Credentials( + PrincipalName new_cname, + PrincipalName new_sname, + EncryptionKey new_key, + KerberosTime new_authtime, + KerberosTime new_starttime, + KerberosTime new_endtime, + KerberosTime new_renewTill, + boolean new_isEncInSKey, + TicketFlags new_flags, + HostAddresses new_caddr, + AuthorizationData new_authData, + Ticket new_ticket, + Ticket new_secondTicket) { + cname = (PrincipalName) new_cname.clone(); + if (new_cname.getRealm() != null) { + crealm = (Realm) new_cname.getRealm().clone(); } - - - public Credentials( - KDCRep kdcRep, - Ticket new_secondTicket, - AuthorizationData new_authorizationData, - boolean new_isEncInSKey - ) { - if (kdcRep.encKDCRepPart == null) //can't store while encrypted - return; - crealm = (Realm)kdcRep.crealm.clone(); - cname = (PrincipalName)kdcRep.cname.clone(); - ticket = (Ticket)kdcRep.ticket.clone(); - key = (EncryptionKey)kdcRep.encKDCRepPart.key.clone(); - flags = (TicketFlags)kdcRep.encKDCRepPart.flags.clone(); - authtime = (KerberosTime)kdcRep.encKDCRepPart.authtime.clone(); - starttime = (KerberosTime)kdcRep.encKDCRepPart.starttime.clone(); - endtime = (KerberosTime)kdcRep.encKDCRepPart.endtime.clone(); - renewTill = (KerberosTime)kdcRep.encKDCRepPart.renewTill.clone(); - srealm = (Realm)kdcRep.encKDCRepPart.srealm.clone(); - sname = (PrincipalName)kdcRep.encKDCRepPart.sname.clone(); - caddr = (HostAddresses)kdcRep.encKDCRepPart.caddr.clone(); - secondTicket = (Ticket)new_secondTicket.clone(); - authorizationData = - (AuthorizationData)new_authorizationData.clone(); - isEncInSKey = new_isEncInSKey; + sname = (PrincipalName) new_sname.clone(); + if (new_sname.getRealm() != null) { + srealm = (Realm) new_sname.getRealm().clone(); } - public Credentials(KDCRep kdcRep) { - this(kdcRep, null); + key = (EncryptionKey) new_key.clone(); + + authtime = (KerberosTime) new_authtime.clone(); + starttime = (KerberosTime) new_starttime.clone(); + endtime = (KerberosTime) new_endtime.clone(); + renewTill = (KerberosTime) new_renewTill.clone(); + if (new_caddr != null) { + caddr = (HostAddresses) new_caddr.clone(); + } + if (new_authData != null) { + authorizationData = (AuthorizationData) new_authData.clone(); } - public Credentials(KDCRep kdcRep, Ticket new_ticket) { - sname = (PrincipalName)kdcRep.encKDCRepPart.sname.clone(); - srealm = (Realm)kdcRep.encKDCRepPart.srealm.clone(); - try { - sname.setRealm(srealm); - } - catch (RealmException e) { - } - cname = (PrincipalName)kdcRep.cname.clone(); - crealm = (Realm)kdcRep.crealm.clone(); - try { - cname.setRealm(crealm); - } - catch (RealmException e) { - } - key = (EncryptionKey)kdcRep.encKDCRepPart.key.clone(); - authtime = (KerberosTime)kdcRep.encKDCRepPart.authtime.clone(); - if (kdcRep.encKDCRepPart.starttime != null) { - starttime = (KerberosTime)kdcRep.encKDCRepPart.starttime.clone(); - } - else starttime = null; - endtime = (KerberosTime)kdcRep.encKDCRepPart.endtime.clone(); - if (kdcRep.encKDCRepPart.renewTill != null) { - renewTill = (KerberosTime)kdcRep.encKDCRepPart.renewTill.clone(); - } - else renewTill = null; - // if (kdcRep.msgType == Krb5.KRB_AS_REP) { - // isEncInSKey = false; - // secondTicket = null; - // } - flags = kdcRep.encKDCRepPart.flags; - if (kdcRep.encKDCRepPart.caddr != null) - caddr = (HostAddresses)kdcRep.encKDCRepPart.caddr.clone(); - else caddr = null; - ticket = (Ticket)kdcRep.ticket.clone(); - if (new_ticket != null) { - secondTicket = (Ticket)new_ticket.clone(); - isEncInSKey = true; - } else { - secondTicket = null; - isEncInSKey = false; - } + isEncInSKey = new_isEncInSKey; + flags = (TicketFlags) new_flags.clone(); + ticket = (Ticket) (new_ticket.clone()); + if (new_secondTicket != null) { + secondTicket = (Ticket) new_secondTicket.clone(); } + } - /** - * Checks if this credential is expired - */ - public boolean isValid() { - boolean valid = true; - if (endtime.getTime() < System.currentTimeMillis()) { - valid = false; - } - else if ((starttime.getTime() > System.currentTimeMillis()) - || ((starttime == null) && (authtime.getTime() > System.currentTimeMillis()))) - { - valid = false; - } - return valid; + public Credentials( + KDCRep kdcRep, + Ticket new_secondTicket, + AuthorizationData new_authorizationData, + boolean new_isEncInSKey) { + if (kdcRep.encKDCRepPart == null) //can't store while encrypted + { + return; } + crealm = (Realm) kdcRep.crealm.clone(); + cname = (PrincipalName) kdcRep.cname.clone(); + ticket = (Ticket) kdcRep.ticket.clone(); + key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone(); + flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone(); + authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone(); + starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); + endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone(); + renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone(); + srealm = (Realm) kdcRep.encKDCRepPart.srealm.clone(); + sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone(); + caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone(); + secondTicket = (Ticket) new_secondTicket.clone(); + authorizationData = + (AuthorizationData) new_authorizationData.clone(); + isEncInSKey = new_isEncInSKey; + } - public PrincipalName getServicePrincipal() throws RealmException{ - if (sname.getRealm() == null) { - sname.setRealm(srealm); - } - return sname; - } + public Credentials(KDCRep kdcRep) { + this(kdcRep, null); + } - public sun.security.krb5.Credentials setKrbCreds() { - return new sun.security.krb5.Credentials(ticket, - cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr); + public Credentials(KDCRep kdcRep, Ticket new_ticket) { + sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone(); + srealm = (Realm) kdcRep.encKDCRepPart.srealm.clone(); + try { + sname.setRealm(srealm); + } catch (RealmException e) { } + cname = (PrincipalName) kdcRep.cname.clone(); + crealm = (Realm) kdcRep.crealm.clone(); + try { + cname.setRealm(crealm); + } catch (RealmException e) { + } + key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone(); + authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone(); + if (kdcRep.encKDCRepPart.starttime != null) { + starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); + } else { + starttime = null; + } + endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone(); + if (kdcRep.encKDCRepPart.renewTill != null) { + renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone(); + } else { + renewTill = null; + } + // if (kdcRep.msgType == Krb5.KRB_AS_REP) { + // isEncInSKey = false; + // secondTicket = null; + // } + flags = kdcRep.encKDCRepPart.flags; + if (kdcRep.encKDCRepPart.caddr != null) { + caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone(); + } else { + caddr = null; + } + ticket = (Ticket) kdcRep.ticket.clone(); + if (new_ticket != null) { + secondTicket = (Ticket) new_ticket.clone(); + isEncInSKey = true; + } else { + secondTicket = null; + isEncInSKey = false; + } + } + + /** + * Checks if this credential is expired + */ + public boolean isValid() { + boolean valid = true; + if (endtime.getTime() < System.currentTimeMillis()) { + valid = false; + } else if ((starttime.getTime() > System.currentTimeMillis()) + || ((starttime == null) && (authtime.getTime() > System.currentTimeMillis()))) { + valid = false; + } + return valid; + } + + public PrincipalName getServicePrincipal() throws RealmException { + if (sname.getRealm() == null) { + sname.setRealm(srealm); + } + return sname; + } + + public sun.security.krb5.Credentials setKrbCreds() { + return new sun.security.krb5.Credentials(ticket, + cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr); + } public KerberosTime getAuthTime() { return authtime; diff --git a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c index 879dab47388..5d2365a415a 100644 --- a/jdk/src/windows/native/sun/security/krb5/NativeCreds.c +++ b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c @@ -88,9 +88,9 @@ VOID ShowNTError(LPSTR,NTSTATUS); VOID InitUnicodeString( - PUNICODE_STRING DestinationString, + PUNICODE_STRING DestinationString, PCWSTR SourceString OPTIONAL - ); +); jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize); @@ -108,215 +108,215 @@ jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime); */ JNIEXPORT jint JNICALL JNI_OnLoad( - JavaVM *jvm, - void *reserved) { + JavaVM *jvm, + void *reserved) { - jclass cls; - JNIEnv *env; + jclass cls; + JNIEnv *env; - if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { - return JNI_EVERSION; /* JNI version not supported */ - } + if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { + return JNI_EVERSION; /* JNI version not supported */ + } - cls = (*env)->FindClass(env,"sun/security/krb5/internal/Ticket"); + cls = (*env)->FindClass(env,"sun/security/krb5/internal/Ticket"); - if (cls == NULL) { - printf("Couldn't find Ticket\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found Ticket\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find Ticket\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found Ticket\n"); + #endif /* DEBUG */ - ticketClass = (*env)->NewWeakGlobalRef(env,cls); - if (ticketClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + ticketClass = (*env)->NewWeakGlobalRef(env,cls); + if (ticketClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env, "sun/security/krb5/PrincipalName"); + cls = (*env)->FindClass(env, "sun/security/krb5/PrincipalName"); - if (cls == NULL) { - printf("Couldn't find PrincipalName\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found PrincipalName\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find PrincipalName\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found PrincipalName\n"); + #endif /* DEBUG */ - principalNameClass = (*env)->NewWeakGlobalRef(env,cls); - if (principalNameClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + principalNameClass = (*env)->NewWeakGlobalRef(env,cls); + if (principalNameClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"sun/security/util/DerValue"); + cls = (*env)->FindClass(env,"sun/security/util/DerValue"); - if (cls == NULL) { - printf("Couldn't find DerValue\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found DerValue\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find DerValue\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found DerValue\n"); + #endif /* DEBUG */ - derValueClass = (*env)->NewWeakGlobalRef(env,cls); - if (derValueClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + derValueClass = (*env)->NewWeakGlobalRef(env,cls); + if (derValueClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"sun/security/krb5/EncryptionKey"); + cls = (*env)->FindClass(env,"sun/security/krb5/EncryptionKey"); - if (cls == NULL) { - printf("Couldn't find EncryptionKey\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found EncryptionKey\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find EncryptionKey\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found EncryptionKey\n"); + #endif /* DEBUG */ - encryptionKeyClass = (*env)->NewWeakGlobalRef(env,cls); - if (encryptionKeyClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + encryptionKeyClass = (*env)->NewWeakGlobalRef(env,cls); + if (encryptionKeyClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"sun/security/krb5/internal/TicketFlags"); + cls = (*env)->FindClass(env,"sun/security/krb5/internal/TicketFlags"); - if (cls == NULL) { - printf("Couldn't find TicketFlags\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found TicketFlags\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find TicketFlags\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found TicketFlags\n"); + #endif /* DEBUG */ - ticketFlagsClass = (*env)->NewWeakGlobalRef(env,cls); - if (ticketFlagsClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + ticketFlagsClass = (*env)->NewWeakGlobalRef(env,cls); + if (ticketFlagsClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"sun/security/krb5/internal/KerberosTime"); + cls = (*env)->FindClass(env,"sun/security/krb5/internal/KerberosTime"); - if (cls == NULL) { - printf("Couldn't find KerberosTime\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found KerberosTime\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find KerberosTime\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found KerberosTime\n"); + #endif /* DEBUG */ - kerberosTimeClass = (*env)->NewWeakGlobalRef(env,cls); - if (kerberosTimeClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + kerberosTimeClass = (*env)->NewWeakGlobalRef(env,cls); + if (kerberosTimeClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - cls = (*env)->FindClass(env,"java/lang/String"); + cls = (*env)->FindClass(env,"java/lang/String"); - if (cls == NULL) { - printf("Couldn't find String\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found String\n"); - #endif /* DEBUG */ + if (cls == NULL) { + printf("Couldn't find String\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found String\n"); + #endif /* DEBUG */ - javaLangStringClass = (*env)->NewWeakGlobalRef(env,cls); - if (javaLangStringClass == NULL) { - return JNI_ERR; - } - #ifdef DEBUG - printf("Made NewWeakGlobalRef\n"); - #endif /* DEBUG */ + javaLangStringClass = (*env)->NewWeakGlobalRef(env,cls); + if (javaLangStringClass == NULL) { + return JNI_ERR; + } + #ifdef DEBUG + printf("Made NewWeakGlobalRef\n"); + #endif /* DEBUG */ - derValueConstructor = (*env)->GetMethodID(env, derValueClass, - "", "([B)V"); - if (derValueConstructor == 0) { - printf("Couldn't find DerValue constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found DerValue constructor\n"); - #endif /* DEBUG */ + derValueConstructor = (*env)->GetMethodID(env, derValueClass, + "", "([B)V"); + if (derValueConstructor == 0) { + printf("Couldn't find DerValue constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found DerValue constructor\n"); + #endif /* DEBUG */ - ticketConstructor = (*env)->GetMethodID(env, ticketClass, - "", "(Lsun/security/util/DerValue;)V"); - if (ticketConstructor == 0) { - printf("Couldn't find Ticket constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found Ticket constructor\n"); - #endif /* DEBUG */ + ticketConstructor = (*env)->GetMethodID(env, ticketClass, + "", "(Lsun/security/util/DerValue;)V"); + if (ticketConstructor == 0) { + printf("Couldn't find Ticket constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found Ticket constructor\n"); + #endif /* DEBUG */ - principalNameConstructor = (*env)->GetMethodID(env, principalNameClass, - "", "([Ljava/lang/String;)V"); - if (principalNameConstructor == 0) { - printf("Couldn't find PrincipalName constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found PrincipalName constructor\n"); - #endif /* DEBUG */ + principalNameConstructor = (*env)->GetMethodID(env, principalNameClass, + "", "([Ljava/lang/String;)V"); + if (principalNameConstructor == 0) { + printf("Couldn't find PrincipalName constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found PrincipalName constructor\n"); + #endif /* DEBUG */ - encryptionKeyConstructor = (*env)->GetMethodID(env, encryptionKeyClass, - "", "(I[B)V"); - if (encryptionKeyConstructor == 0) { - printf("Couldn't find EncryptionKey constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found EncryptionKey constructor\n"); - #endif /* DEBUG */ + encryptionKeyConstructor = (*env)->GetMethodID(env, encryptionKeyClass, + "", "(I[B)V"); + if (encryptionKeyConstructor == 0) { + printf("Couldn't find EncryptionKey constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found EncryptionKey constructor\n"); + #endif /* DEBUG */ - ticketFlagsConstructor = (*env)->GetMethodID(env, ticketFlagsClass, - "", "(I[B)V"); - if (ticketFlagsConstructor == 0) { - printf("Couldn't find TicketFlags constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found TicketFlags constructor\n"); - #endif /* DEBUG */ + ticketFlagsConstructor = (*env)->GetMethodID(env, ticketFlagsClass, + "", "(I[B)V"); + if (ticketFlagsConstructor == 0) { + printf("Couldn't find TicketFlags constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found TicketFlags constructor\n"); + #endif /* DEBUG */ - kerberosTimeConstructor = (*env)->GetMethodID(env, kerberosTimeClass, - "", "(Ljava/lang/String;)V"); - if (kerberosTimeConstructor == 0) { - printf("Couldn't find KerberosTime constructor\n"); - return JNI_ERR; - } - #ifdef DEBUG - printf("Found KerberosTime constructor\n"); - #endif /* DEBUG */ + kerberosTimeConstructor = (*env)->GetMethodID(env, kerberosTimeClass, + "", "(Ljava/lang/String;)V"); + if (kerberosTimeConstructor == 0) { + printf("Couldn't find KerberosTime constructor\n"); + return JNI_ERR; + } + #ifdef DEBUG + printf("Found KerberosTime constructor\n"); + #endif /* DEBUG */ - // load the setRealm method in PrincipalName - setRealmMethod = (*env)->GetMethodID(env, principalNameClass, - "setRealm", "(Ljava/lang/String;)V"); - if (setRealmMethod == 0) { - printf("Couldn't find setRealm in PrincipalName\n"); - return JNI_ERR; - } + // load the setRealm method in PrincipalName + setRealmMethod = (*env)->GetMethodID(env, principalNameClass, + "setRealm", "(Ljava/lang/String;)V"); + if (setRealmMethod == 0) { + printf("Couldn't find setRealm in PrincipalName\n"); + return JNI_ERR; + } - #ifdef DEBUG - printf("Finished OnLoad processing\n"); - #endif /* DEBUG */ + #ifdef DEBUG + printf("Finished OnLoad processing\n"); + #endif /* DEBUG */ - return JNI_VERSION_1_2; + return JNI_VERSION_1_2; } /* @@ -325,38 +325,38 @@ JNIEXPORT jint JNICALL JNI_OnLoad( */ JNIEXPORT void JNICALL JNI_OnUnload( - JavaVM *jvm, - void *reserved) { + JavaVM *jvm, + void *reserved) { - JNIEnv *env; + JNIEnv *env; - if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { - return; /* Nothing else we can do */ - } + if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) { + return; /* Nothing else we can do */ + } - if (ticketClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,ticketClass); - } - if (derValueClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,derValueClass); - } - if (principalNameClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,principalNameClass); - } - if (encryptionKeyClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,encryptionKeyClass); - } - if (ticketFlagsClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,ticketFlagsClass); - } - if (kerberosTimeClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,kerberosTimeClass); - } - if (javaLangStringClass != NULL) { - (*env)->DeleteWeakGlobalRef(env,javaLangStringClass); - } + if (ticketClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,ticketClass); + } + if (derValueClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,derValueClass); + } + if (principalNameClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,principalNameClass); + } + if (encryptionKeyClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,encryptionKeyClass); + } + if (ticketFlagsClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,ticketFlagsClass); + } + if (kerberosTimeClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,kerberosTimeClass); + } + if (javaLangStringClass != NULL) { + (*env)->DeleteWeakGlobalRef(env,javaLangStringClass); + } - return; + return; } /* @@ -365,31 +365,31 @@ JNIEXPORT void JNICALL JNI_OnUnload( * Signature: ()Lsun/security/krb5/Credentials; */ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativeCreds( - JNIEnv *env, - jclass krbcredsClass) { + JNIEnv *env, + jclass krbcredsClass) { - KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; - PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL; - PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; - PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; - NTSTATUS Status, SubStatus; - ULONG requestSize = 0; - ULONG responseSize = 0; - ULONG rspSize = 0; - HANDLE LogonHandle = NULL; - ULONG PackageId; - jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; - jobject ticketFlags, startTime, endTime, krbCreds = NULL; - jobject authTime, renewTillTime, hostAddresses = NULL; - KERB_EXTERNAL_TICKET *msticket; - int ignore_cache = 0; - FILETIME Now, EndTime, LocalEndTime; + KERB_QUERY_TKT_CACHE_REQUEST CacheRequest; + PKERB_RETRIEVE_TKT_RESPONSE TktCacheResponse = NULL; + PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; + PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL; + NTSTATUS Status, SubStatus; + ULONG requestSize = 0; + ULONG responseSize = 0; + ULONG rspSize = 0; + HANDLE LogonHandle = NULL; + ULONG PackageId; + jobject ticket, clientPrincipal, targetPrincipal, encryptionKey; + jobject ticketFlags, startTime, endTime, krbCreds = NULL; + jobject authTime, renewTillTime, hostAddresses = NULL; + KERB_EXTERNAL_TICKET *msticket; + int ignore_cache = 0; + FILETIME Now, EndTime, LocalEndTime; - while (TRUE) { + while (TRUE) { if (krbcredsConstructor == 0) { - krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "", - "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); + krbcredsConstructor = (*env)->GetMethodID(env, krbcredsClass, "", + "(Lsun/security/krb5/internal/Ticket;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/PrincipalName;Lsun/security/krb5/EncryptionKey;Lsun/security/krb5/internal/TicketFlags;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/KerberosTime;Lsun/security/krb5/internal/HostAddresses;)V"); if (krbcredsConstructor == 0) { printf("Couldn't find sun.security.krb5.Credentials constructor\n"); break; @@ -510,88 +510,88 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ msticket = &(pTicketResponse->Ticket); } -/* + /* -typedef struct _KERB_RETRIEVE_TKT_RESPONSE { - KERB_EXTERNAL_TICKET Ticket; -} KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE; + typedef struct _KERB_RETRIEVE_TKT_RESPONSE { + KERB_EXTERNAL_TICKET Ticket; + } KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE; -typedef struct _KERB_EXTERNAL_TICKET { - PKERB_EXTERNAL_NAME ServiceName; - PKERB_EXTERNAL_NAME TargetName; - PKERB_EXTERNAL_NAME ClientName; - UNICODE_STRING DomainName; - UNICODE_STRING TargetDomainName; - UNICODE_STRING AltTargetDomainName; - KERB_CRYPTO_KEY SessionKey; - ULONG TicketFlags; - ULONG Flags; - LARGE_INTEGER KeyExpirationTime; - LARGE_INTEGER StartTime; - LARGE_INTEGER EndTime; - LARGE_INTEGER RenewUntil; - LARGE_INTEGER TimeSkew; - ULONG EncodedTicketSize; - PUCHAR EncodedTicket; <========== Here's the good stuff -} KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET; + typedef struct _KERB_EXTERNAL_TICKET { + PKERB_EXTERNAL_NAME ServiceName; + PKERB_EXTERNAL_NAME TargetName; + PKERB_EXTERNAL_NAME ClientName; + UNICODE_STRING DomainName; + UNICODE_STRING TargetDomainName; + UNICODE_STRING AltTargetDomainName; + KERB_CRYPTO_KEY SessionKey; + ULONG TicketFlags; + ULONG Flags; + LARGE_INTEGER KeyExpirationTime; + LARGE_INTEGER StartTime; + LARGE_INTEGER EndTime; + LARGE_INTEGER RenewUntil; + LARGE_INTEGER TimeSkew; + ULONG EncodedTicketSize; + PUCHAR EncodedTicket; <========== Here's the good stuff + } KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET; -typedef struct _KERB_EXTERNAL_NAME { - SHORT NameType; - USHORT NameCount; - UNICODE_STRING Names[ANYSIZE_ARRAY]; -} KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME; + typedef struct _KERB_EXTERNAL_NAME { + SHORT NameType; + USHORT NameCount; + UNICODE_STRING Names[ANYSIZE_ARRAY]; + } KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME; -typedef struct _LSA_UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; + typedef struct _LSA_UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; + } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING; -typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; + typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING; -typedef struct KERB_CRYPTO_KEY { - LONG KeyType; - ULONG Length; - PUCHAR Value; -} KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY; + typedef struct KERB_CRYPTO_KEY { + LONG KeyType; + ULONG Length; + PUCHAR Value; + } KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY; -*/ + */ // Build a com.sun.security.krb5.Ticket ticket = BuildTicket(env, msticket->EncodedTicket, msticket->EncodedTicketSize); if (ticket == NULL) { - break; + break; } // OK, have a Ticket, now need to get the client name clientPrincipal = BuildPrincipal(env, msticket->ClientName, msticket->TargetDomainName); // mdu if (clientPrincipal == NULL) { - break; + break; } // and the "name" of tgt targetPrincipal = BuildPrincipal(env, msticket->ServiceName, msticket->DomainName); if (targetPrincipal == NULL) { - break; + break; } // Get the encryption key encryptionKey = BuildEncryptionKey(env, &(msticket->SessionKey)); if (encryptionKey == NULL) { - break; + break; } // and the ticket flags ticketFlags = BuildTicketFlags(env, &(msticket->TicketFlags)); if (ticketFlags == NULL) { - break; + break; } // Get the start time startTime = BuildKerberosTime(env, &(msticket->StartTime)); if (startTime == NULL) { - break; + break; } /* @@ -604,13 +604,13 @@ typedef struct KERB_CRYPTO_KEY { // and the end time endTime = BuildKerberosTime(env, &(msticket->EndTime)); if (endTime == NULL) { - break; + break; } // Get the renew till time renewTillTime = BuildKerberosTime(env, &(msticket->RenewUntil)); if (renewTillTime == NULL) { - break; + break; } // and now go build a KrbCreds object @@ -630,87 +630,87 @@ typedef struct KERB_CRYPTO_KEY { hostAddresses); break; - } // end of WHILE + } // end of WHILE - // clean up resources - if (TktCacheResponse != NULL) { - LsaFreeReturnBuffer(TktCacheResponse); - } - if (pTicketRequest) { - LocalFree(pTicketRequest); - } - if (pTicketResponse != NULL) { - LsaFreeReturnBuffer(pTicketResponse); - } + // clean up resources + if (TktCacheResponse != NULL) { + LsaFreeReturnBuffer(TktCacheResponse); + } + if (pTicketRequest) { + LocalFree(pTicketRequest); + } + if (pTicketResponse != NULL) { + LsaFreeReturnBuffer(pTicketResponse); + } - return krbCreds; + return krbCreds; } static NTSTATUS ConstructTicketRequest(UNICODE_STRING DomainName, PKERB_RETRIEVE_TKT_REQUEST *outRequest, ULONG *outSize) { - NTSTATUS Status; - UNICODE_STRING TargetPrefix; - USHORT TargetSize; - ULONG RequestSize; - ULONG Length; - PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; + NTSTATUS Status; + UNICODE_STRING TargetPrefix; + USHORT TargetSize; + ULONG RequestSize; + ULONG Length; + PKERB_RETRIEVE_TKT_REQUEST pTicketRequest = NULL; - *outRequest = NULL; - *outSize = 0; + *outRequest = NULL; + *outSize = 0; - // - // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we - // can easily concatenate it later. - // + // + // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we + // can easily concatenate it later. + // - TargetPrefix.Buffer = L"krbtgt/"; - Length = (ULONG)wcslen(TargetPrefix.Buffer) * sizeof(WCHAR); - TargetPrefix.Length = (USHORT)Length; - TargetPrefix.MaximumLength = TargetPrefix.Length; + TargetPrefix.Buffer = L"krbtgt/"; + Length = (ULONG)wcslen(TargetPrefix.Buffer) * sizeof(WCHAR); + TargetPrefix.Length = (USHORT)Length; + TargetPrefix.MaximumLength = TargetPrefix.Length; - // - // We will need to concatenate the "krbtgt/" prefix and the - // Logon Session's DnsDomainName into our request's target name. - // - // Therefore, first compute the necessary buffer size for that. - // - // Note that we might theoretically have integer overflow. - // + // + // We will need to concatenate the "krbtgt/" prefix and the + // Logon Session's DnsDomainName into our request's target name. + // + // Therefore, first compute the necessary buffer size for that. + // + // Note that we might theoretically have integer overflow. + // - TargetSize = TargetPrefix.Length + DomainName.Length; + TargetSize = TargetPrefix.Length + DomainName.Length; - // - // The ticket request buffer needs to be a single buffer. That buffer - // needs to include the buffer for the target name. - // + // + // The ticket request buffer needs to be a single buffer. That buffer + // needs to include the buffer for the target name. + // - RequestSize = sizeof (*pTicketRequest) + TargetSize; + RequestSize = sizeof (*pTicketRequest) + TargetSize; - // - // Allocate the request buffer and make sure it's zero-filled. - // + // + // Allocate the request buffer and make sure it's zero-filled. + // - pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) - LocalAlloc(LMEM_ZEROINIT, RequestSize); - if (!pTicketRequest) - return GetLastError(); + pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST) + LocalAlloc(LMEM_ZEROINIT, RequestSize); + if (!pTicketRequest) + return GetLastError(); - // - // Concatenate the target prefix with the previous reponse's - // target domain. - // + // + // Concatenate the target prefix with the previous reponse's + // target domain. + // - pTicketRequest->TargetName.Length = 0; - pTicketRequest->TargetName.MaximumLength = TargetSize; - pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); - Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName), - TargetPrefix, - DomainName); - *outRequest = pTicketRequest; - *outSize = RequestSize; - return Status; + pTicketRequest->TargetName.Length = 0; + pTicketRequest->TargetName.MaximumLength = TargetSize; + pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1); + Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName), + TargetPrefix, + DomainName); + *outRequest = pTicketRequest; + *outSize = RequestSize; + return Status; } DWORD @@ -720,22 +720,22 @@ ConcatenateUnicodeStrings( UNICODE_STRING Source2 ) { - // - // The buffers for Source1 and Source2 cannot overlap pTarget's - // buffer. Source1.Length + Source2.Length must be <= 0xFFFF, - // otherwise we overflow... - // + // + // The buffers for Source1 and Source2 cannot overlap pTarget's + // buffer. Source1.Length + Source2.Length must be <= 0xFFFF, + // otherwise we overflow... + // - USHORT TotalSize = Source1.Length + Source2.Length; - PBYTE buffer = (PBYTE) pTarget->Buffer; + USHORT TotalSize = Source1.Length + Source2.Length; + PBYTE buffer = (PBYTE) pTarget->Buffer; - if (TotalSize > pTarget->MaximumLength) - return ERROR_INSUFFICIENT_BUFFER; + if (TotalSize > pTarget->MaximumLength) + return ERROR_INSUFFICIENT_BUFFER; - pTarget->Length = TotalSize; - memcpy(buffer, Source1.Buffer, Source1.Length); - memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length); - return ERROR_SUCCESS; + pTarget->Length = TotalSize; + memcpy(buffer, Source1.Buffer, Source1.Length); + memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length); + return ERROR_SUCCESS; } BOOL @@ -783,27 +783,27 @@ ShowLastError( DWORD dwError ) { - #define MAX_MSG_SIZE 256 + #define MAX_MSG_SIZE 256 - static WCHAR szMsgBuf[MAX_MSG_SIZE]; - DWORD dwRes; + static WCHAR szMsgBuf[MAX_MSG_SIZE]; + DWORD dwRes; - printf("Error calling function %s: %lu\n", szAPI, dwError); + printf("Error calling function %s: %lu\n", szAPI, dwError); - dwRes = FormatMessage ( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dwError, - 0, - szMsgBuf, - MAX_MSG_SIZE, - NULL); - if (0 == dwRes) { - printf("FormatMessage failed with %d\n", GetLastError()); - // ExitProcess(EXIT_FAILURE); - } else { - printf("%S",szMsgBuf); - } + dwRes = FormatMessage ( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwError, + 0, + szMsgBuf, + MAX_MSG_SIZE, + NULL); + if (0 == dwRes) { + printf("FormatMessage failed with %d\n", GetLastError()); + // ExitProcess(EXIT_FAILURE); + } else { + printf("%S",szMsgBuf); + } } VOID @@ -831,189 +831,189 @@ InitUnicodeString( Length = (ULONG)wcslen( SourceString ) * sizeof( WCHAR ); DestinationString->Length = (USHORT)Length; DestinationString->MaximumLength = (USHORT)(Length + sizeof(UNICODE_NULL)); - } + } else { DestinationString->MaximumLength = 0; DestinationString->Length = 0; - } + } } jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize) { - /* To build a Ticket, we first need to build a DerValue out of the EncodedTicket. - * But before we can do that, we need to make a byte array out of the ET. - */ + /* To build a Ticket, we first need to build a DerValue out of the EncodedTicket. + * But before we can do that, we need to make a byte array out of the ET. + */ - jobject derValue, ticket; - jbyteArray ary; + jobject derValue, ticket; + jbyteArray ary; - ary = (*env)->NewByteArray(env,encodedTicketSize); - if ((*env)->ExceptionOccurred(env)) { - return (jobject) NULL; - } - - (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicketSize, - (jbyte *)encodedTicket); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - return (jobject) NULL; - } - - derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - return (jobject) NULL; - } + ary = (*env)->NewByteArray(env,encodedTicketSize); + if ((*env)->ExceptionOccurred(env)) { + return (jobject) NULL; + } + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, encodedTicketSize, + (jbyte *)encodedTicket); + if ((*env)->ExceptionOccurred(env)) { (*env)->DeleteLocalRef(env, ary); - ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, derValue); - return (jobject) NULL; - } + return (jobject) NULL; + } + + derValue = (*env)->NewObject(env, derValueClass, derValueConstructor, ary); + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, ary); + return (jobject) NULL; + } + + (*env)->DeleteLocalRef(env, ary); + ticket = (*env)->NewObject(env, ticketClass, ticketConstructor, derValue); + if ((*env)->ExceptionOccurred(env)) { (*env)->DeleteLocalRef(env, derValue); - return ticket; + return (jobject) NULL; + } + (*env)->DeleteLocalRef(env, derValue); + return ticket; } // mdu jobject BuildPrincipal(JNIEnv *env, PKERB_EXTERNAL_NAME principalName, UNICODE_STRING domainName) { - /* - * To build the Principal, we need to get the names out of - * this goofy MS structure - */ - jobject principal = NULL; - jobject realmStr = NULL; - jobjectArray stringArray; - jstring tempString; - int nameCount,i; - PUNICODE_STRING scanner; - WCHAR *realm; - ULONG realmLen; + /* + * To build the Principal, we need to get the names out of + * this goofy MS structure + */ + jobject principal = NULL; + jobject realmStr = NULL; + jobjectArray stringArray; + jstring tempString; + int nameCount,i; + PUNICODE_STRING scanner; + WCHAR *realm; + ULONG realmLen; - realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT, - ((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL))); - wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR)); + realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT, + ((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL))); + wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR)); - #ifdef DEBUG - printf("Principal domain is %S\n", realm); - printf("Name type is %x\n", principalName->NameType); - printf("Name count is %x\n", principalName->NameCount); - #endif + #ifdef DEBUG + printf("Principal domain is %S\n", realm); + printf("Name type is %x\n", principalName->NameType); + printf("Name count is %x\n", principalName->NameCount); + #endif - nameCount = principalName->NameCount; - stringArray = (*env)->NewObjectArray(env, nameCount, - javaLangStringClass, NULL); - if (stringArray == NULL) { - printf("Can't allocate String array for Principal\n"); - LocalFree(realm); - return principal; - } - - for (i=0; iNames[i]); - - // OK, got a Char array, so construct a String - tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer, - scanner->Length/sizeof(WCHAR)); - // Set the String into the StringArray - (*env)->SetObjectArrayElement(env, stringArray, i, tempString); - - // Do I have to worry about storage reclamation here? - } - principal = (*env)->NewObject(env, principalNameClass, - principalNameConstructor, stringArray); - - // now set the realm in the principal - realmLen = (ULONG)wcslen((PWCHAR)realm); - realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen); - (*env)->CallVoidMethod(env, principal, setRealmMethod, realmStr); - - // free local resources + nameCount = principalName->NameCount; + stringArray = (*env)->NewObjectArray(env, nameCount, + javaLangStringClass, NULL); + if (stringArray == NULL) { + printf("Can't allocate String array for Principal\n"); LocalFree(realm); - return principal; + } + + for (i=0; iNames[i]); + + // OK, got a Char array, so construct a String + tempString = (*env)->NewString(env, (const jchar*)scanner->Buffer, + scanner->Length/sizeof(WCHAR)); + // Set the String into the StringArray + (*env)->SetObjectArrayElement(env, stringArray, i, tempString); + + // Do I have to worry about storage reclamation here? + } + principal = (*env)->NewObject(env, principalNameClass, + principalNameConstructor, stringArray); + + // now set the realm in the principal + realmLen = (ULONG)wcslen((PWCHAR)realm); + realmStr = (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen); + (*env)->CallVoidMethod(env, principal, setRealmMethod, realmStr); + + // free local resources + LocalFree(realm); + + return principal; } jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey) { - // First, need to build a byte array - jbyteArray ary; - jobject encryptionKey = NULL; + // First, need to build a byte array + jbyteArray ary; + jobject encryptionKey = NULL; - ary = (*env)->NewByteArray(env,cryptoKey->Length); - (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length, - (jbyte *)cryptoKey->Value); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - } else { - encryptionKey = (*env)->NewObject(env, encryptionKeyClass, - encryptionKeyConstructor, cryptoKey->KeyType, ary); - } + ary = (*env)->NewByteArray(env,cryptoKey->Length); + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length, + (jbyte *)cryptoKey->Value); + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, ary); + } else { + encryptionKey = (*env)->NewObject(env, encryptionKeyClass, + encryptionKeyConstructor, cryptoKey->KeyType, ary); + } - return encryptionKey; + return encryptionKey; } jobject BuildTicketFlags(JNIEnv *env, PULONG flags) { - jobject ticketFlags = NULL; - jbyteArray ary; - /* - * mdu: Convert the bytes to nework byte order before copying - * them to a Java byte array. - */ - ULONG nlflags = htonl(*flags); + jobject ticketFlags = NULL; + jbyteArray ary; + /* + * mdu: Convert the bytes to nework byte order before copying + * them to a Java byte array. + */ + ULONG nlflags = htonl(*flags); - ary = (*env)->NewByteArray(env, sizeof(*flags)); - (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags), - (jbyte *)&nlflags); - if ((*env)->ExceptionOccurred(env)) { - (*env)->DeleteLocalRef(env, ary); - } else { - ticketFlags = (*env)->NewObject(env, ticketFlagsClass, - ticketFlagsConstructor, sizeof(*flags)*8, ary); - } + ary = (*env)->NewByteArray(env, sizeof(*flags)); + (*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags), + (jbyte *)&nlflags); + if ((*env)->ExceptionOccurred(env)) { + (*env)->DeleteLocalRef(env, ary); + } else { + ticketFlags = (*env)->NewObject(env, ticketFlagsClass, + ticketFlagsConstructor, sizeof(*flags)*8, ary); + } - return ticketFlags; + return ticketFlags; } jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime) { - jobject kerberosTime = NULL; - jstring stringTime = NULL; - SYSTEMTIME systemTime; - WCHAR timeString[16]; - WCHAR month[3]; - WCHAR day[3]; - WCHAR hour[3]; - WCHAR minute[3]; - WCHAR second[3]; + jobject kerberosTime = NULL; + jstring stringTime = NULL; + SYSTEMTIME systemTime; + WCHAR timeString[16]; + WCHAR month[3]; + WCHAR day[3]; + WCHAR hour[3]; + WCHAR minute[3]; + WCHAR second[3]; - if (FileTimeToSystemTime((FILETIME *)kerbtime, &systemTime)) { -// XXX Cannot use %02.2ld, because the leading 0 is ignored for integers. -// So, print them to strings, and then print them to the master string with a -// format pattern that makes it two digits and prefix with a 0 if necessary. - swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth); - swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay); - swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour); - swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute); - swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond); - swprintf( (wchar_t *)timeString, - L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ", + if (FileTimeToSystemTime((FILETIME *)kerbtime, &systemTime)) { + // XXX Cannot use %02.2ld, because the leading 0 is ignored for integers. + // So, print them to strings, and then print them to the master string with a + // format pattern that makes it two digits and prefix with a 0 if necessary. + swprintf( (wchar_t *)month, L"%2.2d", systemTime.wMonth); + swprintf( (wchar_t *)day, L"%2.2d", systemTime.wDay); + swprintf( (wchar_t *)hour, L"%2.2d", systemTime.wHour); + swprintf( (wchar_t *)minute, L"%2.2d", systemTime.wMinute); + swprintf( (wchar_t *)second, L"%2.2d", systemTime.wSecond); + swprintf( (wchar_t *)timeString, + L"%ld%02.2s%02.2s%02.2s%02.2s%02.2sZ", systemTime.wYear, month, day, hour, minute, second ); - #ifdef DEBUG - printf("%S\n", (wchar_t *)timeString); - #endif /* DEBUG */ - stringTime = (*env)->NewString(env, timeString, - (sizeof(timeString)/sizeof(WCHAR))-1); - if (stringTime != NULL) { // everything's OK so far - kerberosTime = (*env)->NewObject(env, kerberosTimeClass, - kerberosTimeConstructor, stringTime); - } + #ifdef DEBUG + printf("%S\n", (wchar_t *)timeString); + #endif /* DEBUG */ + stringTime = (*env)->NewString(env, timeString, + (sizeof(timeString)/sizeof(WCHAR))-1); + if (stringTime != NULL) { // everything's OK so far + kerberosTime = (*env)->NewObject(env, kerberosTimeClass, + kerberosTimeConstructor, stringTime); } - return kerberosTime; + } + return kerberosTime; } From ffacce23977bf834184fc339d99f6bbe594d04b1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Collet Date: Wed, 5 Mar 2008 11:40:22 +0100 Subject: [PATCH 068/274] 6641309: Wrong Cookie separator used in HttpURLConnection Added a space to cookie separator. Generified the code and added tags. Reviewed-by: chegar --- .../www/protocol/http/HttpURLConnection.java | 58 +++++--- .../net/CookieHandler/CookieManagerTest.java | 30 ++-- .../sun/net/www/protocol/http/B6641309.java | 129 ++++++++++++++++++ 3 files changed, 184 insertions(+), 33 deletions(-) create mode 100644 jdk/test/sun/net/www/protocol/http/B6641309.java diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index fb1f3b05ed1..b0cd7c8e856 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -64,11 +64,6 @@ import java.text.SimpleDateFormat; import java.util.TimeZone; import java.net.MalformedURLException; import java.nio.ByteBuffer; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; -import java.nio.channels.Selector; -import java.nio.channels.SelectionKey; -import java.nio.channels.SelectableChannel; import java.lang.reflect.*; /** @@ -824,6 +819,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * - get input, [read input,] get output, [write output] */ + @Override public synchronized OutputStream getOutputStream() throws IOException { try { @@ -908,30 +904,25 @@ public class HttpURLConnection extends java.net.HttpURLConnection { URI uri = ParseUtil.toURI(url); if (uri != null) { - Map cookies = cookieHandler.get(uri, requests.getHeaders(EXCLUDE_HEADERS)); + Map> cookies = cookieHandler.get(uri, requests.getHeaders(EXCLUDE_HEADERS)); if (!cookies.isEmpty()) { - Set s = cookies.entrySet(); - Iterator k_itr = s.iterator(); - while (k_itr.hasNext()) { - Map.Entry entry = (Map.Entry)k_itr.next(); - String key = (String)entry.getKey(); + for (Map.Entry> entry : cookies.entrySet()) { + String key = entry.getKey(); // ignore all entries that don't have "Cookie" // or "Cookie2" as keys if (!"Cookie".equalsIgnoreCase(key) && !"Cookie2".equalsIgnoreCase(key)) { continue; } - List l = (List)entry.getValue(); + List l = entry.getValue(); if (l != null && !l.isEmpty()) { - Iterator v_itr = l.iterator(); StringBuilder cookieValue = new StringBuilder(); - while (v_itr.hasNext()) { - String value = (String)v_itr.next(); - cookieValue.append(value).append(';'); + for (String value : l) { + cookieValue.append(value).append("; "); } - // strip off the ending ;-sign + // strip off the trailing '; ' try { - requests.add(key, cookieValue.substring(0, cookieValue.length() - 1)); + requests.add(key, cookieValue.substring(0, cookieValue.length() - 2)); } catch (StringIndexOutOfBoundsException ignored) { // no-op } @@ -950,6 +941,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } // end of getting cookies } + @Override + @SuppressWarnings("empty-statement") public synchronized InputStream getInputStream() throws IOException { if (!doInput) { @@ -1386,6 +1379,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public InputStream getErrorStream() { if (connected && responseCode >= 400) { // Client Error 4xx and Server Error 5xx @@ -2152,6 +2146,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * Gets a header field by name. Returns null if not known. * @param name the name of the header field */ + @Override public String getHeaderField(String name) { try { getInputStream(); @@ -2174,6 +2169,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @return a Map of header fields * @since 1.4 */ + @Override public Map getHeaderFields() { try { getInputStream(); @@ -2190,6 +2186,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * Gets a header field by index. Returns null if not known. * @param n the index of the header field */ + @Override public String getHeaderField(int n) { try { getInputStream(); @@ -2205,6 +2202,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * Gets a header field by index. Returns null if not known. * @param n the index of the header field */ + @Override public String getHeaderFieldKey(int n) { try { getInputStream(); @@ -2222,6 +2220,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * exists, overwrite its value with the new value. * @param value the value to be set */ + @Override public void setRequestProperty(String key, String value) { if (connected) throw new IllegalStateException("Already connected"); @@ -2243,6 +2242,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see #getRequestProperties(java.lang.String) * @since 1.4 */ + @Override public void addRequestProperty(String key, String value) { if (connected) throw new IllegalStateException("Already connected"); @@ -2262,6 +2262,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { requests.set(key, value); } + @Override public String getRequestProperty (String key) { // don't return headers containing security sensitive information if (key != null) { @@ -2286,6 +2287,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @throws IllegalStateException if already connected * @since 1.4 */ + @Override public Map getRequestProperties() { if (connected) throw new IllegalStateException("Already connected"); @@ -2294,6 +2296,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return requests.getHeaders(EXCLUDE_HEADERS); } + @Override public void setConnectTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); @@ -2313,6 +2316,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.net.URLConnection#connect() * @since 1.5 */ + @Override public int getConnectTimeout() { return (connectTimeout < 0 ? 0 : connectTimeout); } @@ -2337,6 +2341,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.InputStream#read() * @since 1.5 */ + @Override public void setReadTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); @@ -2354,10 +2359,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.InputStream#read() * @since 1.5 */ + @Override public int getReadTimeout() { return readTimeout < 0 ? 0 : readTimeout; } + @Override protected void finalize() { // this should do nothing. The stream finalizer will close // the fd @@ -2437,6 +2444,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.FilterInputStream#in * @see java.io.FilterInputStream#reset() */ + @Override public synchronized void mark(int readlimit) { super.mark(readlimit); if (cacheRequest != null) { @@ -2466,6 +2474,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @see java.io.FilterInputStream#in * @see java.io.FilterInputStream#mark(int) */ + @Override public synchronized void reset() throws IOException { super.reset(); if (cacheRequest != null) { @@ -2474,6 +2483,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public int read() throws IOException { try { byte[] b = new byte[1]; @@ -2487,10 +2497,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } + @Override public int read(byte[] b, int off, int len) throws IOException { try { int newLen = super.read(b, off, len); @@ -2521,6 +2533,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public void close () throws IOException { try { if (outputStream != null) { @@ -2565,6 +2578,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { error = false; } + @Override public void write (int b) throws IOException { checkError(); written ++; @@ -2574,10 +2588,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { out.write (b); } + @Override public void write (byte[] b) throws IOException { write (b, 0, b.length); } + @Override public void write (byte[] b, int off, int len) throws IOException { checkError(); written += len; @@ -2608,6 +2624,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return closed && ! error; } + @Override public void close () throws IOException { if (closed) { return; @@ -2726,6 +2743,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public int available() throws IOException { if (is == null) { return buffer.remaining(); @@ -2740,10 +2758,12 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return (ret == -1? ret : (b[0] & 0x00FF)); } + @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } + @Override public int read(byte[] b, int off, int len) throws IOException { int rem = buffer.remaining(); if (rem > 0) { @@ -2759,6 +2779,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } + @Override public void close() throws IOException { buffer = null; if (is != null) { @@ -2775,6 +2796,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { class EmptyInputStream extends InputStream { + @Override public int available() { return 0; } diff --git a/jdk/test/java/net/CookieHandler/CookieManagerTest.java b/jdk/test/java/net/CookieHandler/CookieManagerTest.java index a2c9db3b411..b83c27fcefc 100644 --- a/jdk/test/java/net/CookieHandler/CookieManagerTest.java +++ b/jdk/test/java/net/CookieHandler/CookieManagerTest.java @@ -132,17 +132,17 @@ class CookieHttpTransaction implements HttpCallback { ), new CookieTestCase("Set-Cookie", "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/;" + "domain=." + localHostAddr, - "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001", + "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001", "/" ), new CookieTestCase("Set-Cookie", "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr, - "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001", + "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001", "/" ), new CookieTestCase("Set-Cookie", "SHIPPING=FEDEX; path=/foo;" + "domain=." + localHostAddr, - "CUSTOMER=WILE:BOB;PART_NUMBER=ROCKET_LAUNCHER_0001;SHIPPING=FEDEX", + "CUSTOMER=WILE:BOB; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX", "/foo" ) }; @@ -157,7 +157,7 @@ class CookieHttpTransaction implements HttpCallback { ), new CookieTestCase("Set-Cookie", "PART_NUMBER=RIDING_ROCKET_0023; path=/ammo;" + "domain=." + localHostAddr, - "PART_NUMBER=RIDING_ROCKET_0023;PART_NUMBER=ROCKET_LAUNCHER_0001", + "PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001", "/ammo" ) }; @@ -167,17 +167,17 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme/login" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/pickitem" ), new CookieTestCase("Set-Cookie2", "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + ";Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"" + "; Shipping=\"FedEx\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/shipping" ) }; @@ -187,17 +187,17 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme/ammo" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Riding_Rocket_0023\"; Version=\"1\"; Path=\"/acme/ammo\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr + "\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\";$Path=\"/acme/ammo\";$Domain=\"." + localHostAddr + "\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/ammo" ), new CookieTestCase("", "", - "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";" + "$Domain=\"." + localHostAddr + "\"", "/acme/parts" ) }; @@ -207,12 +207,12 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_2000\"; Version=\"1\"; Path=\"/acme\";" + "domain=." + localHostAddr, - "$Version=\"1\";Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", + "$Version=\"1\"; Part_Number=\"Rocket_Launcher_2000\";$Path=\"/acme\";$Domain=\"." + localHostAddr + "\"", "/acme" ) }; @@ -222,17 +222,17 @@ class CookieHttpTransaction implements HttpCallback { testCases[count++] = new CookieTestCase[]{ new CookieTestCase("Set-Cookie2", "Customer=\"WILE_E_COYOTE\"; Version=\"1\"; Path=\"/acme\"", - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"", "/acme/login" ), new CookieTestCase("Set-Cookie2", "Part_Number=\"Rocket_Launcher_0001\"; Version=\"1\";Path=\"/acme\"", - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"", "/acme/pickitem" ), new CookieTestCase("Set-Cookie2", "Shipping=\"FedEx\"; Version=\"1\"; Path=\"/acme\"", - "$Version=\"1\";Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + ";Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"" + ";Shipping=\"FedEx\";$Path=\"/acme\"", + "$Version=\"1\"; Customer=\"WILE_E_COYOTE\";$Path=\"/acme\"" + "; Part_Number=\"Rocket_Launcher_0001\";$Path=\"/acme\"" + "; Shipping=\"FedEx\";$Path=\"/acme\"", "/acme/shipping" ) }; diff --git a/jdk/test/sun/net/www/protocol/http/B6641309.java b/jdk/test/sun/net/www/protocol/http/B6641309.java new file mode 100644 index 00000000000..15e8fdc31bc --- /dev/null +++ b/jdk/test/sun/net/www/protocol/http/B6641309.java @@ -0,0 +1,129 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6641309 + * @summary Wrong Cookie separator used in HttpURLConnection + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import com.sun.net.httpserver.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; + +public class B6641309 +{ + com.sun.net.httpserver.HttpServer httpServer; + ExecutorService executorService; + + public static void main(String[] args) + { + new B6641309(); + } + + public B6641309() + { + try { + startHttpServer(); + doClient(); + } catch (IOException ioe) { + System.err.println(ioe); + } + } + + void doClient() { + CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL)); + try { + InetSocketAddress address = httpServer.getAddress(); + + // GET Request + URL url = new URL("http://localhost:" + address.getPort() + "/test/"); + CookieHandler ch = CookieHandler.getDefault(); + Map> header = new HashMap>(); + List values = new LinkedList(); + values.add("Test1Cookie=TEST1; path=/test/"); + values.add("Test2Cookie=TEST2; path=/test/"); + header.put("Set-Cookie", values); + + // preload the CookieHandler with a cookie for our URL + // so that it will be sent during the first request + ch.put(url.toURI(), header); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); + int resp = uc.getResponseCode(); + if (resp != 200) + throw new RuntimeException("Failed: Response code from GET is not 200"); + + System.out.println("Response code from GET = 200 OK"); + + } catch (IOException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } finally { + httpServer.stop(1); + executorService.shutdown(); + } + } + + /** + * Http Server + */ + public void startHttpServer() throws IOException { + httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); + + // create HttpServer context + HttpContext ctx = httpServer.createContext("/test/", new MyHandler()); + + executorService = Executors.newCachedThreadPool(); + httpServer.setExecutor(executorService); + httpServer.start(); + } + + class MyHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + Headers reqHeaders = t.getRequestHeaders(); + int i = 0; + // Read till end of stream + do { + i = is.read(); + } while (i != -1); + is.close(); + + List cookies = reqHeaders.get("Cookie"); + if (cookies != null) { + for (String str : cookies) { + // The separator between the 2 cookies should be + // a semi-colon AND a space + if (str.equals("Test1Cookie=TEST1; Test2Cookie=TEST2")) + t.sendResponseHeaders(200, -1); + } + } + t.sendResponseHeaders(400, -1); + t.close(); + } + } +} From 578a880feef75eb2cd4476489838de0aacfb0d06 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 5 Mar 2008 21:55:33 +0800 Subject: [PATCH 069/274] 6648972: KDCReq.init always read padata PA-DATA is optional, only read it when it exists Reviewed-by: valeriep --- .../security/krb5/internal/ETypeInfo2.java | 8 +- .../sun/security/krb5/internal/KDCReq.java | 4 +- .../security/krb5/OptionPADataInKDCReq.java | 123 ++++++++++++++++++ 3 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 jdk/test/sun/security/krb5/OptionPADataInKDCReq.java diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java b/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java index 110e38b0806..30bf4dfb3c9 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java @@ -100,16 +100,16 @@ public class ETypeInfo2 { // salt if (encoding.getData().available() > 0) { - der = encoding.getData().getDerValue(); - if ((der.getTag() & 0x1F) == 0x01) { + if ((encoding.getData().peekByte() & 0x1F) == 0x01) { + der = encoding.getData().getDerValue(); this.saltStr = der.getData().getGeneralString(); } } // s2kparams if (encoding.getData().available() > 0) { - der = encoding.getData().getDerValue(); - if ((der.getTag() & 0x1F) == 0x02) { + if ((encoding.getData().peekByte() & 0x1F) == 0x02) { + der = encoding.getData().getDerValue(); this.s2kparams = der.getData().getOctetString(); } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java b/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java index fee4567c3c6..a46f6436cd8 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java @@ -144,8 +144,8 @@ public class KDCReq { } else { throw new Asn1Exception(Krb5.ASN1_BAD_ID); } - subDer = der.getData().getDerValue(); - if ((subDer.getTag() & 0x01F) == 0x03) { + if ((der.getData().peekByte() & 0x1F) == 0x03) { + subDer = der.getData().getDerValue(); DerValue subsubDer = subDer.getData().getDerValue(); if (subsubDer.getTag() != DerValue.tag_SequenceOf) { throw new Asn1Exception(Krb5.ASN1_BAD_ID); diff --git a/jdk/test/sun/security/krb5/OptionPADataInKDCReq.java b/jdk/test/sun/security/krb5/OptionPADataInKDCReq.java new file mode 100644 index 00000000000..2229b541e89 --- /dev/null +++ b/jdk/test/sun/security/krb5/OptionPADataInKDCReq.java @@ -0,0 +1,123 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 6648972 + * @summary KDCReq.init always read padata + */ +import sun.security.krb5.internal.ETypeInfo2; +import sun.security.krb5.internal.KDCReq; +import sun.security.util.DerValue; + +public class OptionPADataInKDCReq { + public static void main(String[] args) throws Exception { + /* + * This is a AS-REQ block without padata. The content is -- + [APPLICATION 10] SEQUENCE { + [1] INTEGER 5 + [2] INTEGER 10 + [4] SEQUENCE { + [0] BIT STRING 01000000 10000001 00000000 00010000 + [1] SEQUENCE { + [0] INTEGER 1 + [1] SEQUENCE { + STRING administrator + } + } + [2] STRING N3 + [3] SEQUENCE { + [0] INTEGER 2 + [1] SEQUENCE { + STRING krbtgt + STRING N3 + } + } + [5] TIME Sun Sep 13 10:48:05 CST 2037 + [6] TIME Sun Sep 13 10:48:05 CST 2037 + [7] INTEGER 2101281516 + [8] SEQUENCE { + INTEGER 23 + INTEGER -133 + INTEGER -128 + INTEGER 3 + INTEGER 1 + INTEGER 24 + INTEGER -135 + } + [9] SEQUENCE { + SEQUENCE { + [0] INTEGER 20 + [1] OCTET STRING + 0000: 58 50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 XP + } + } + } + } + */ + byte[] b = { + (byte)0x6a, (byte)0x81, (byte)0xbf, (byte)0x30, (byte)0x81, (byte)0xbc, (byte)0xa1, (byte)0x03, + (byte)0x02, (byte)0x01, (byte)0x05, (byte)0xa2, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x0a, + (byte)0xa4, (byte)0x81, (byte)0xaf, (byte)0x30, (byte)0x81, (byte)0xac, (byte)0xa0, (byte)0x07, + (byte)0x03, (byte)0x05, (byte)0x00, (byte)0x40, (byte)0x81, (byte)0x00, (byte)0x10, (byte)0xa1, + (byte)0x1a, (byte)0x30, (byte)0x18, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x01, + (byte)0xa1, (byte)0x11, (byte)0x30, (byte)0x0f, (byte)0x1b, (byte)0x0d, (byte)0x61, (byte)0x64, + (byte)0x6d, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x73, (byte)0x74, (byte)0x72, (byte)0x61, + (byte)0x74, (byte)0x6f, (byte)0x72, (byte)0xa2, (byte)0x04, (byte)0x1b, (byte)0x02, (byte)0x4e, + (byte)0x33, (byte)0xa3, (byte)0x17, (byte)0x30, (byte)0x15, (byte)0xa0, (byte)0x03, (byte)0x02, + (byte)0x01, (byte)0x02, (byte)0xa1, (byte)0x0e, (byte)0x30, (byte)0x0c, (byte)0x1b, (byte)0x06, + (byte)0x6b, (byte)0x72, (byte)0x62, (byte)0x74, (byte)0x67, (byte)0x74, (byte)0x1b, (byte)0x02, + (byte)0x4e, (byte)0x33, (byte)0xa5, (byte)0x11, (byte)0x18, (byte)0x0f, (byte)0x32, (byte)0x30, + (byte)0x33, (byte)0x37, (byte)0x30, (byte)0x39, (byte)0x31, (byte)0x33, (byte)0x30, (byte)0x32, + (byte)0x34, (byte)0x38, (byte)0x30, (byte)0x35, (byte)0x5a, (byte)0xa6, (byte)0x11, (byte)0x18, + (byte)0x0f, (byte)0x32, (byte)0x30, (byte)0x33, (byte)0x37, (byte)0x30, (byte)0x39, (byte)0x31, + (byte)0x33, (byte)0x30, (byte)0x32, (byte)0x34, (byte)0x38, (byte)0x30, (byte)0x35, (byte)0x5a, + (byte)0xa7, (byte)0x06, (byte)0x02, (byte)0x04, (byte)0x7d, (byte)0x3f, (byte)0x02, (byte)0xec, + (byte)0xa8, (byte)0x19, (byte)0x30, (byte)0x17, (byte)0x02, (byte)0x01, (byte)0x17, (byte)0x02, + (byte)0x02, (byte)0xff, (byte)0x7b, (byte)0x02, (byte)0x01, (byte)0x80, (byte)0x02, (byte)0x01, + (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x01, (byte)0x02, (byte)0x01, (byte)0x18, (byte)0x02, + (byte)0x02, (byte)0xff, (byte)0x79, (byte)0xa9, (byte)0x1d, (byte)0x30, (byte)0x1b, (byte)0x30, + (byte)0x19, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x14, (byte)0xa1, (byte)0x12, + (byte)0x04, (byte)0x10, (byte)0x58, (byte)0x50, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, + (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, (byte)0x20, + (byte)0x20, (byte)0x20, + }; + new KDCReq(b, 0x0a); + + /* + * This is a fake ETYPEINFO2 block with no salt + SEQUENCE { + [0] INTEGER 0 + [2] OCTET STRING 0000: 00 . + } + */ + byte[] b2 = { + (byte)0x30, (byte)0x0a, (byte)0xa0, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0xa2, + (byte)0x03, (byte)0x04, (byte)0x01, (byte)0x00, + }; + + ETypeInfo2 e2 = new ETypeInfo2(new DerValue(b2)); + if (e2.getSalt() != null || e2.getParams() == null) { + throw new Exception("ETypeInfo2 decoding error"); + } + } +} From 0c6743a97086dd3c574e2d00b5a338f56a04ac97 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 5 Mar 2008 22:15:45 +0800 Subject: [PATCH 070/274] 6590930: reed/write does not match for ccache Add null-awareness to ccache read Reviewed-by: valeriep --- .../internal/ccache/CCacheInputStream.java | 12 ++- .../krb5/internal/ccache/Credentials.java | 27 ++++-- jdk/test/sun/security/krb5/TimeInCCache.java | 93 +++++++++++++++++++ 3 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 jdk/test/sun/security/krb5/TimeInCCache.java diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java index 5a62d6d2508..9271d9bcefb 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java @@ -338,15 +338,19 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC System.out.println(">>>DEBUG key type: " + key.getEType()); long times[] = readTimes(); KerberosTime authtime = new KerberosTime(times[0]); - KerberosTime starttime = new KerberosTime(times[1]); + KerberosTime starttime = + (times[1]==0) ? null : new KerberosTime(times[1]); KerberosTime endtime = new KerberosTime(times[2]); - KerberosTime renewTill = new KerberosTime(times[3]); + KerberosTime renewTill = + (times[3]==0) ? null : new KerberosTime(times[3]); if (DEBUG) { System.out.println(">>>DEBUG auth time: " + authtime.toDate().toString()); - System.out.println(">>>DEBUG start time: " + starttime.toDate().toString()); + System.out.println(">>>DEBUG start time: " + + ((starttime==null)?"null":starttime.toDate().toString())); System.out.println(">>>DEBUG end time: " + endtime.toDate().toString()); - System.out.println(">>>DEBUG renew_till time: " + renewTill.toDate().toString()); + System.out.println(">>>DEBUG renew_till time: " + + ((renewTill==null)?"null":renewTill.toDate().toString())); } boolean skey = readskey(); boolean flags[] = readFlags(); diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java b/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java index 0c7b1ed32b2..ff45cb73d37 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java @@ -79,9 +79,13 @@ public class Credentials { key = (EncryptionKey) new_key.clone(); authtime = (KerberosTime) new_authtime.clone(); - starttime = (KerberosTime) new_starttime.clone(); + if (new_starttime != null) { + starttime = (KerberosTime) new_starttime.clone(); + } endtime = (KerberosTime) new_endtime.clone(); - renewTill = (KerberosTime) new_renewTill.clone(); + if (new_renewTill != null) { + renewTill = (KerberosTime) new_renewTill.clone(); + } if (new_caddr != null) { caddr = (HostAddresses) new_caddr.clone(); } @@ -112,9 +116,13 @@ public class Credentials { key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone(); flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone(); authtime = (KerberosTime) kdcRep.encKDCRepPart.authtime.clone(); - starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); + if (kdcRep.encKDCRepPart.starttime != null) { + starttime = (KerberosTime) kdcRep.encKDCRepPart.starttime.clone(); + } endtime = (KerberosTime) kdcRep.encKDCRepPart.endtime.clone(); - renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone(); + if (kdcRep.encKDCRepPart.renewTill != null) { + renewTill = (KerberosTime) kdcRep.encKDCRepPart.renewTill.clone(); + } srealm = (Realm) kdcRep.encKDCRepPart.srealm.clone(); sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone(); caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone(); @@ -181,9 +189,14 @@ public class Credentials { boolean valid = true; if (endtime.getTime() < System.currentTimeMillis()) { valid = false; - } else if ((starttime.getTime() > System.currentTimeMillis()) - || ((starttime == null) && (authtime.getTime() > System.currentTimeMillis()))) { - valid = false; + } else if (starttime != null) { + if (starttime.getTime() > System.currentTimeMillis()) { + valid = false; + } + } else { + if (authtime.getTime() > System.currentTimeMillis()) { + valid = false; + } } return valid; } diff --git a/jdk/test/sun/security/krb5/TimeInCCache.java b/jdk/test/sun/security/krb5/TimeInCCache.java new file mode 100644 index 00000000000..5ef8b5370df --- /dev/null +++ b/jdk/test/sun/security/krb5/TimeInCCache.java @@ -0,0 +1,93 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 6590930 + * @summary read/write does not match for ccache + */ + +import java.io.ByteArrayInputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import sun.security.krb5.internal.ccache.CCacheInputStream; +import sun.security.krb5.internal.ccache.Credentials; + +public class TimeInCCache { + public static void main(String[] args) throws Exception { + // A trivial cache file, with startdate and renewTill being zero. + // The endtime is set to sometime in year 2022, so that isValid() + // will always check starttime. + byte[] ccache = new byte[]{ + 5, 4, 0, 12, 0, 1, 0, 8, -1, -1, -1, 19, -1, -2, 89, 51, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73, + 46, 76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 10, 77, 65, 88, 73, 46, + 76, 79, 67, 65, 76, 0, 0, 0, 5, 100, 117, 109, 109, 121, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 10, 77, 65, 88, 73, 46, 76, + 79, 67, 65, 76, 0, 0, 0, 6, 107, 114, 98, 116, 103, 116, 0, 0, + 0, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, 0, 17, 0, 0, + 0, 16, -78, -85, -90, -50, -68, 115, 68, 8, -39, -109, 91, 61, -17, -27, + -122, -120, 71, 69, 16, -121, 0, 0, 0, 0, 98, 69, 16, -121, 0, 0, + 0, 0, 0, 64, -32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 97, -127, -3, 48, -127, -6, -96, 3, 2, 1, 5, -95, 12, + 27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -94, 31, 48, 29, + -96, 3, 2, 1, 0, -95, 22, 48, 20, 27, 6, 107, 114, 98, 116, 103, + 116, 27, 10, 77, 65, 88, 73, 46, 76, 79, 67, 65, 76, -93, -127, -61, + 48, -127, -64, -96, 3, 2, 1, 17, -95, 3, 2, 1, 1, -94, -127, -77, + 4, -127, -80, 43, 65, -66, 34, 21, -34, 37, 35, 32, 50, -14, 122, 77, + -3, -29, 37, 99, 50, 125, -43, -96, -78, 85, 23, 41, -80, 68, 2, -109, + -27, 38, -41, -72, -32, 127, 63, -76, -22, 81, 33, -114, -30, 104, 125, -81, + -29, 70, -25, 23, 100, -75, -25, 62, -120, -78, -61, -100, -74, 50, -117, -127, + -16, 79, -106, 62, -39, 91, 100, -10, 23, -88, -18, -47, 51, -19, 113, 18, + 98, -101, 31, 98, 22, -81, 11, -41, -42, 67, 87, 92, -2, 42, -54, 79, + 49, -90, 43, -37, 90, -102, 125, 62, -88, -77, 100, 102, 23, -57, -51, 38, + 68, -44, -57, -102, 103, -6, 85, -58, 74, -117, -87, 67, -103, -36, 110, -122, + 115, 12, 118, -106, -114, -51, 79, 68, 32, -91, -53, -5, -51, 89, 72, 70, + 123, -12, -95, 9, 40, -30, -117, 74, 77, 38, 91, 126, -82, 17, 98, 98, + -49, 78, 36, 36, 103, -76, -100, -23, 118, -92, -8, 80, 103, -23, -98, 56, + 21, 65, -77, 0, 0, 0, 0 + }; + System.setProperty("sun.security.krb5.debug", "true"); // test code changes in DEBUG + CCacheInputStream cis = new CCacheInputStream(new ByteArrayInputStream(ccache)); + cis.readVersion(); + cis.readTag(); + cis.readPrincipal(0x504); + Method m = CCacheInputStream.class.getDeclaredMethod("readCred", Integer.TYPE); + m.setAccessible(true); + Credentials c = (Credentials) m.invoke(cis, new Integer(0x504)); + sun.security.krb5.Credentials cc = c.setKrbCreds(); + + // 1. Make sure starttime is still null + if (cc.getStartTime() != null) { + throw new Exception("Fail, starttime should be zero here"); + } + + // 2. Make sure renewTill is still null + if (cc.getRenewTill() != null) { + throw new Exception("Fail, renewTill should be zero here"); + } + + // 3. Make sure isValid works + c.isValid(); + } +} From be421c50f197807b0c20436a4d9212e083009301 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 5 Mar 2008 22:16:06 +0800 Subject: [PATCH 071/274] 6664612: debug output leaked Reviewed-by: valeriep --- .../sun/security/krb5/internal/ccache/CCacheInputStream.java | 4 +++- .../sun/security/krb5/internal/crypto/dk/AesDkCrypto.java | 4 +++- .../sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java index 9271d9bcefb..64c3f8cd85b 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java @@ -215,7 +215,9 @@ public class CCacheInputStream extends KrbDataInputStream implements FileCCacheC addrType = read(2); addrLength = read(4); if (!(addrLength == 4 || addrLength == 16)) { - System.out.println("Incorrect address format."); + if (DEBUG) { + System.out.println("Incorrect address format."); + } return null; } byte[] result = new byte[addrLength]; diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java index 31919fc51f5..ea6e2d3eb24 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java @@ -440,7 +440,9 @@ public class AesDkCrypto extends DkCrypto { for (int i = 0; i < hashSize; i++) { if (calculatedHmac[i] != ciphertext[hmacOffset+i]) { cksumFailed = true; - System.err.println("Checksum failed !"); + if (debug) { + System.err.println("Checksum failed !"); + } break; } } diff --git a/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java b/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java index 57a0c091721..8d4c89d60b3 100644 --- a/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java +++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java @@ -397,7 +397,9 @@ public class ArcFourCrypto extends DkCrypto { for (int i = 0; i < hashSize; i++) { if (calculatedHmac[i] != ciphertext[i]) { cksumFailed = true; - System.err.println("Checksum failed !"); + if (debug) { + System.err.println("Checksum failed !"); + } break; } } From 45c655a782143312678b0e75ccd9bb2597f40389 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Collet Date: Wed, 5 Mar 2008 17:16:14 +0100 Subject: [PATCH 072/274] 6660405: HttpURLConnection returns the wrong InputStream Set inputStream back to null in disconnectInternal(). Reviewed-by: chegar --- .../www/protocol/http/HttpURLConnection.java | 1 + .../sun/net/www/protocol/http/B6660405.java | 163 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 jdk/test/sun/net/www/protocol/http/B6660405.java diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index b0cd7c8e856..ce030c8c5b8 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -2048,6 +2048,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { */ private void disconnectInternal() { responseCode = -1; + inputStream = null; if (pi != null) { pi.finishTracking(); pi = null; diff --git a/jdk/test/sun/net/www/protocol/http/B6660405.java b/jdk/test/sun/net/www/protocol/http/B6660405.java new file mode 100644 index 00000000000..2309497c2fb --- /dev/null +++ b/jdk/test/sun/net/www/protocol/http/B6660405.java @@ -0,0 +1,163 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6660405 + * @summary HttpURLConnection returns the wrong InputStream + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import com.sun.net.httpserver.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; + +public class B6660405 +{ + com.sun.net.httpserver.HttpServer httpServer; + ExecutorService executorService; + + static class MyCacheResponse extends CacheResponse { + private byte[] buf = new byte[1024]; + + public MyCacheResponse() { + } + + @Override + public Map> getHeaders() throws IOException + { + Map> h = new HashMap>(); + ArrayList l = new ArrayList(); + l.add("HTTP/1.1 200 OK"); + h.put(null, l); + l = new ArrayList(); + l.add("1024"); + h.put("Content-Length", l); + return h; + } + + @Override + public InputStream getBody() throws IOException + { + return new ByteArrayInputStream(buf); + } + + } + static class MyResponseCache extends ResponseCache { + + public MyResponseCache() { + } + + @Override + public CacheResponse get(URI uri, String rqstMethod, Map> rqstHeaders) throws IOException + { + if (uri.getPath().equals("/redirect/index.html")) { + return new MyCacheResponse(); + } + return null; + } + + @Override + public CacheRequest put(URI uri, URLConnection conn) throws IOException + { + return null; + } + + } + + public static void main(String[] args) + { + new B6660405(); + } + + public B6660405() + { + try { + startHttpServer(); + doClient(); + } catch (IOException ioe) { + System.err.println(ioe); + } + } + + void doClient() { + ResponseCache.setDefault(new MyResponseCache()); + try { + InetSocketAddress address = httpServer.getAddress(); + + // GET Request + URL url = new URL("http://localhost:" + address.getPort() + "/test/index.html"); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); + int code = uc.getResponseCode(); + System.err.println("response code = " + code); + int l = uc.getContentLength(); + System.err.println("content-length = " + l); + InputStream in = uc.getInputStream(); + int i = 0; + // Read till end of stream + do { + i = in.read(); + } while (i != -1); + in.close(); + } catch (IOException e) { + throw new RuntimeException("Got the wrong InputStream after checking headers"); + } finally { + httpServer.stop(1); + executorService.shutdown(); + } + } + + /** + * Http Server + */ + public void startHttpServer() throws IOException { + httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); + + // create HttpServer context + HttpContext ctx = httpServer.createContext("/test/", new MyHandler()); + + executorService = Executors.newCachedThreadPool(); + httpServer.setExecutor(executorService); + httpServer.start(); + } + + class MyHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + Headers reqHeaders = t.getRequestHeaders(); + Headers resHeaders = t.getResponseHeaders(); + + int i = 0; + // Read till end of stream + do { + i = is.read(); + } while (i != -1); + is.close(); + resHeaders.add("Location", "http://foo.bar/redirect/index.html"); + t.sendResponseHeaders(302, -1); + t.close(); + } + } +} From e33dde98175ea7d0d66790f510e74b10108725df Mon Sep 17 00:00:00 2001 From: Jean-Christophe Collet Date: Wed, 5 Mar 2008 18:11:33 +0100 Subject: [PATCH 073/274] 6651717: Debug output statement left in MailToURLConnection Removed output statement, removed unused imports, added override tags. Reviewed-by: chegar --- .../net/www/protocol/mailto/MailToURLConnection.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java index d939ce5515b..53367aead96 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java @@ -29,9 +29,6 @@ import java.net.URL; import java.net.InetAddress; import java.net.SocketPermission; import java.io.*; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.StringTokenizer; import java.security.Permission; import sun.net.www.*; import sun.net.smtp.SmtpClient; @@ -86,11 +83,11 @@ public class MailToURLConnection extends URLConnection { } public void connect() throws IOException { - System.err.println("connect. Timeout = " + connectTimeout); client = new SmtpClient(connectTimeout); client.setReadTimeout(readTimeout); } + @Override public synchronized OutputStream getOutputStream() throws IOException { if (os != null) { return os; @@ -107,6 +104,7 @@ public class MailToURLConnection extends URLConnection { return os; } + @Override public Permission getPermission() throws IOException { if (permission == null) { connect(); @@ -116,22 +114,26 @@ public class MailToURLConnection extends URLConnection { return permission; } + @Override public void setConnectTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); connectTimeout = timeout; } + @Override public int getConnectTimeout() { return (connectTimeout < 0 ? 0 : connectTimeout); } + @Override public void setReadTimeout(int timeout) { if (timeout < 0) throw new IllegalArgumentException("timeouts can't be negative"); readTimeout = timeout; } + @Override public int getReadTimeout() { return readTimeout < 0 ? 0 : readTimeout; } From 17458c966079a65a7d56da554ec229c9a20549e7 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 5 Mar 2008 11:33:31 -0800 Subject: [PATCH 074/274] 6671250: In Parse::do_if() old Cmp node 'c' should be replaced with new one after BoolNode transformation In Parse::do_if() 'c' (CmpNode) node may be changed during BoolNode transformation so 'c' may became dead but the node is referenced later in the code. Reviewed-by: never --- hotspot/src/share/vm/opto/parse2.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp index ae8615d0152..d66a68741da 100644 --- a/hotspot/src/share/vm/opto/parse2.cpp +++ b/hotspot/src/share/vm/opto/parse2.cpp @@ -1022,10 +1022,27 @@ void Parse::do_if(BoolTest::mask btest, Node* c) { Node* tst = _gvn.transform(tst0); BoolTest::mask taken_btest = BoolTest::illegal; BoolTest::mask untaken_btest = BoolTest::illegal; - if (btest == BoolTest::ne) { - // For now, these are the only cases of btest that matter. (More later.) - taken_btest = taken_if_true ? btest : BoolTest::eq; - untaken_btest = taken_if_true ? BoolTest::eq : btest; + + if (tst->is_Bool()) { + // Refresh c from the transformed bool node, since it may be + // simpler than the original c. Also re-canonicalize btest. + // This wins when (Bool ne (Conv2B p) 0) => (Bool ne (CmpP p NULL)). + // That can arise from statements like: if (x instanceof C) ... + if (tst != tst0) { + // Canonicalize one more time since transform can change it. + btest = tst->as_Bool()->_test._test; + if (!BoolTest(btest).is_canonical()) { + // Reverse edges one more time... + tst = _gvn.transform( tst->as_Bool()->negate(&_gvn) ); + btest = tst->as_Bool()->_test._test; + assert(BoolTest(btest).is_canonical(), "sanity"); + taken_if_true = !taken_if_true; + } + c = tst->in(1); + } + BoolTest::mask neg_btest = BoolTest(btest).negate(); + taken_btest = taken_if_true ? btest : neg_btest; + untaken_btest = taken_if_true ? neg_btest : btest; } // Generate real control flow From d8e9d2232314cb96314b3c22405a73b0e08c7583 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Wed, 5 Mar 2008 18:56:03 -0800 Subject: [PATCH 075/274] 6662830: OpenJDK build testing results Small corrections in the README. Reviewed-by: xdono --- README-builds.html | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/README-builds.html b/README-builds.html index 6530865db54..096d192e2b9 100644 --- a/README-builds.html +++ b/README-builds.html @@ -342,32 +342,29 @@

- The source code for the - OpenJDK is - delivered in 3 sibling directories: + The source code for the OpenJDK is delivered in a set of + directories: hotspot, langtools, corba, jaxws, jaxp, - jdk and + jdk. The hotspot directory contains the source code and make - files for - building the - OpenJDK - Hotspot Virtual Machine. - The jdk - directory contains the source code and make files for - building the - OpenJDK - runtime libraries, tools and demos. - The top level Makefile is used to build the complete OpenJDK - release including building the hotspot - VM, staging the VM binaries, and building the - OpenJDK - runtime libraries, - tools and demos. + files for building the OpenJDK Hotspot Virtual Machine. + The langtools directory contains the source code and make + files for building the OpenJDK javac and language tools. + The corba directory contains the source code and make + files for building the OpenJDK Corba files. + The jaxws directory contains the source code and make + files for building the OpenJDK JAXWS files. + The jaxp directory contains the source code and make + files for building the OpenJDK JAXP files. + The jdk directory contains the source code and make files for + building the OpenJDK runtime libraries and misc files. + The top level Makefile + is used to build the entire OpenJDK.

@@ -730,17 +727,15 @@ under an open-source license. In order to build an OpenJDK binary from source code, you must first download and install the appropriate - binary plug bundles from the OpenJDK Download area. + binary plug bundles from the OpenJDK, go to the + OpenJDK site and select + the "Bundles(7)" link. During the OpenJDK build process these "binary plugs" for the encumbered components will be copied into your resulting OpenJDK binary build image. These binary plug files are only for the purpose of building an OpenJDK binary. - Download the Binary Plugs by selecting the Downloads - link at - the OpenJDK site, - install the bundle, - and make sure you set + Make sure you set ALT_BINARY_PLUGS_PATH to the root of this installation. From 86d2ba8dfca2d85236a3a7f5d8d50f08b004749c Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Thu, 6 Mar 2008 07:51:28 -0800 Subject: [PATCH 076/274] 6596475: (launcher) javaw should call InitCommonControls Javaw does not show error window after manifest changes. Reviewed-by: darcy --- jdk/make/java/jli/Makefile | 1 + jdk/make/java/main/java/Makefile | 2 +- jdk/make/java/main/javaw/Makefile | 2 +- jdk/src/share/bin/java.c | 4 +--- jdk/src/share/bin/java.h | 5 ++++- jdk/src/share/bin/main.c | 2 -- jdk/src/solaris/bin/java_md.c | 12 ++++++------ jdk/src/windows/bin/java_md.c | 23 ++++++++++++++++++----- 8 files changed, 32 insertions(+), 19 deletions(-) diff --git a/jdk/make/java/jli/Makefile b/jdk/make/java/jli/Makefile index fb8868fd37d..236654fd4a9 100644 --- a/jdk/make/java/jli/Makefile +++ b/jdk/make/java/jli/Makefile @@ -107,6 +107,7 @@ endif # PLATFORM ifeq ($(PLATFORM), windows) EXTRA_LIBS = advapi32.lib \ + comctl32.lib \ user32.lib JAVALIB = diff --git a/jdk/make/java/main/java/Makefile b/jdk/make/java/main/java/Makefile index ad924f6663e..5c876294c98 100644 --- a/jdk/make/java/main/java/Makefile +++ b/jdk/make/java/main/java/Makefile @@ -43,7 +43,7 @@ include $(BUILDDIR)/common/Defs.gmk # Override the default version info with our own resource file (see 5106536) ifeq ($(PLATFORM), windows) -LDLIBS_COMMON += user32.lib +LDLIBS_COMMON += user32.lib comctl32.lib ifdef OPENJDK RC_FLAGS += -i "$(PLATFORM_SRC)/resource/icons" else diff --git a/jdk/make/java/main/javaw/Makefile b/jdk/make/java/main/javaw/Makefile index 9afb5d0133d..1c03b23fab7 100644 --- a/jdk/make/java/main/javaw/Makefile +++ b/jdk/make/java/main/javaw/Makefile @@ -46,7 +46,7 @@ STATIC_JLI = true include $(BUILDDIR)/common/Defs.gmk OTHER_CPPFLAGS += -DJAVAW -LDLIBS_COMMON += user32.lib +LDLIBS_COMMON += user32.lib comctl32.lib # Override the default version info with our own resource file (see 5106536) ifeq ($(PLATFORM), windows) diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c index 2e86de9a401..47c2fc17cd0 100644 --- a/jdk/src/share/bin/java.c +++ b/jdk/src/share/bin/java.c @@ -205,9 +205,7 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ _wc_enabled = cpwildcard; _ergo_policy = ergo; - if (javaw == JNI_TRUE) - SetJavaw(); - + InitLauncher(javaw); DumpState(); /* diff --git a/jdk/src/share/bin/java.h b/jdk/src/share/bin/java.h index c86c5d107db..291b6755690 100644 --- a/jdk/src/share/bin/java.h +++ b/jdk/src/share/bin/java.h @@ -172,7 +172,6 @@ const char* GetDotVersion(); const char* GetFullVersion(); jboolean IsJavaArgs(); jboolean IsJavaw(); -void SetJavaw(); jint GetErgoPolicy(); jboolean ServerClassMachine(); @@ -180,5 +179,9 @@ jboolean ServerClassMachine(); static int ContinueInNewThread(InvocationFunctions* ifn, int argc, char** argv, char* jarfile, char* classname, int ret); +/* + * Initialize platform specific settings + */ +void InitLauncher(jboolean javaw); #endif /* _JAVA_H_ */ diff --git a/jdk/src/share/bin/main.c b/jdk/src/share/bin/main.c index 7052159f267..88d9190a555 100644 --- a/jdk/src/share/bin/main.c +++ b/jdk/src/share/bin/main.c @@ -64,8 +64,6 @@ main(int argc, char ** argv) margv = argv; #endif /* JAVAW */ - JLI_SetTraceLauncher(); - return JLI_Launch(margc, margv, sizeof(const_jargs) / sizeof(char *), const_jargs, sizeof(const_appclasspath) / sizeof(char *), const_appclasspath, diff --git a/jdk/src/solaris/bin/java_md.c b/jdk/src/solaris/bin/java_md.c index 5d96c2780f0..74dd1a3ef8e 100644 --- a/jdk/src/solaris/bin/java_md.c +++ b/jdk/src/solaris/bin/java_md.c @@ -1299,12 +1299,6 @@ void SetJavaLauncherPlatformProps() { AddOption(pid_prop_str, NULL); #endif } -void -SetJavaw() -{ - /* noop on UNIX */ - return; -} jboolean IsJavaw() @@ -1312,3 +1306,9 @@ IsJavaw() /* noop on UNIX */ return JNI_FALSE; } + +void +InitLauncher(jboolean javaw) +{ + JLI_SetTraceLauncher(); +} diff --git a/jdk/src/windows/bin/java_md.c b/jdk/src/windows/bin/java_md.c index 2e1c787838d..f252e0b1b38 100644 --- a/jdk/src/windows/bin/java_md.c +++ b/jdk/src/windows/bin/java_md.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "java.h" @@ -52,11 +53,6 @@ static jboolean GetJREPath(char *path, jint pathsize); static jboolean _isjavaw = JNI_FALSE; -void -SetJavaw() -{ - _isjavaw = JNI_TRUE; -} jboolean IsJavaw() @@ -999,3 +995,20 @@ ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void /* Linux only, empty on windows. */ void SetJavaLauncherPlatformProps() {} + +void +InitLauncher(boolean javaw) +{ + INITCOMMONCONTROLSEX icx; + + /* + * Required for javaw mode MessageBox output as well as for + * HotSpot -XX:+ShowMessageBoxOnError in java mode, an empty + * flag field is sufficient to perform the basic UI initialization. + */ + memset(&icx, 0, sizeof(INITCOMMONCONTROLSEX)); + icx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCommonControlsEx(&icx); + _isjavaw = javaw; + JLI_SetTraceLauncher(); +} From 7c8027dacea0711ae7264b02e4ea9e40a8da947c Mon Sep 17 00:00:00 2001 From: Michael Bailey Date: Thu, 6 Mar 2008 10:07:25 -0800 Subject: [PATCH 077/274] 4741726: allow Object += String Remove code in line with restriction removed from JLS Reviewed-by: mcimadamore --- .../com/sun/tools/javac/comp/Attr.java | 15 ++++-------- ...jectAppend.java => StringConversion2.java} | 23 +++++++++++-------- 2 files changed, 17 insertions(+), 21 deletions(-) rename langtools/test/tools/javac/{expression/ObjectAppend.java => StringConversion2.java} (73%) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index bf06b95c51c..f597bc7f3e6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1609,17 +1609,10 @@ public class Attr extends JCTree.Visitor { tree.getTag() - JCTree.ASGOffset, owntype, operand); - if (types.isSameType(operator.type.getReturnType(), syms.stringType)) { - // String assignment; make sure the lhs is a string - chk.checkType(tree.lhs.pos(), - owntype, - syms.stringType); - } else { - chk.checkDivZero(tree.rhs.pos(), operator, operand); - chk.checkCastable(tree.rhs.pos(), - operator.type.getReturnType(), - owntype); - } + chk.checkDivZero(tree.rhs.pos(), operator, operand); + chk.checkCastable(tree.rhs.pos(), + operator.type.getReturnType(), + owntype); } result = check(tree, owntype, VAL, pkind, pt); } diff --git a/langtools/test/tools/javac/expression/ObjectAppend.java b/langtools/test/tools/javac/StringConversion2.java similarity index 73% rename from langtools/test/tools/javac/expression/ObjectAppend.java rename to langtools/test/tools/javac/StringConversion2.java index b92575f0d84..6e8db13e22d 100644 --- a/langtools/test/tools/javac/expression/ObjectAppend.java +++ b/langtools/test/tools/javac/StringConversion2.java @@ -1,5 +1,5 @@ /* - * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008 Sun Microsystems, Inc. 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,14 +23,17 @@ /* * @test - * @bug 4642850 - * @summary compiler allows Object += String - * @author gafter - * - * @compile/fail ObjectAppend.java + * @bug 4741726 + * @summary allow Object += String */ -class ObjectAppend {{ - Object o = null; - o += "string"; -}} +public class StringConversion2 +{ + public static void main(String[] args) { + Object o = "Hello "; + String s = "World!"; + o += s; + if (!o.equals("Hello World!")) + throw new Error("test failed"); + } +} From a7ed75b36aa3173289a61721c991e666c09531a9 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 6 Mar 2008 10:25:04 -0800 Subject: [PATCH 078/274] 6668802: javac handles diagnostics for last line badly, if line not terminated by newline Use CharBuffer.limit(), not the length of the backing array Reviewed-by: mcimadamore --- .../classes/com/sun/tools/javac/util/Log.java | 26 +++--- langtools/test/tools/javac/T6668802.java | 79 +++++++++++++++++++ 2 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 langtools/test/tools/javac/T6668802.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java index 7ceb7d98660..33c3144cb75 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java @@ -203,6 +203,10 @@ public class Log { */ private char[] buf = null; + /** The length of useful data in buf + */ + private int bufLen = 0; + /** The position in the buffer at which last error was reported */ private int bp; @@ -256,6 +260,7 @@ public class Log { */ protected void setBuf(char[] newBuf) { buf = newBuf; + bufLen = buf.length; bp = 0; lineStart = 0; line = 1; @@ -324,7 +329,7 @@ public class Log { return; int lineEnd = lineStart; - while (lineEnd < buf.length && buf[lineEnd] != CR && buf[lineEnd] != LF) + while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF) lineEnd++; if (lineEnd - lineStart == 0) return; @@ -336,12 +341,15 @@ public class Log { writer.flush(); } - protected static char[] getCharContent(JavaFileObject fileObject) throws IOException { + protected void initBuf(JavaFileObject fileObject) throws IOException { CharSequence cs = fileObject.getCharContent(true); if (cs instanceof CharBuffer) { - return JavacFileManager.toArray((CharBuffer)cs); + CharBuffer cb = (CharBuffer) cs; + buf = JavacFileManager.toArray(cb); + bufLen = cb.limit(); } else { - return cs.toString().toCharArray(); + buf = cs.toString().toCharArray(); + bufLen = buf.length; } } @@ -353,7 +361,7 @@ public class Log { return false; try { if (buf == null) { - buf = getCharContent(currentSource()); + initBuf(currentSource()); lineStart = 0; line = 1; } else if (lineStart > pos) { // messages don't come in order @@ -361,10 +369,10 @@ public class Log { line = 1; } bp = lineStart; - while (bp < buf.length && bp < pos) { + while (bp < bufLen && bp < pos) { switch (buf[bp++]) { case CR: - if (bp < buf.length && buf[bp] == LF) bp++; + if (bp < bufLen && buf[bp] == LF) bp++; line++; lineStart = bp; break; @@ -374,7 +382,7 @@ public class Log { break; } } - return bp <= buf.length; + return bp <= bufLen; } catch (IOException e) { //e.printStackTrace(); // FIXME: include e.getLocalizedMessage() in error message @@ -704,7 +712,7 @@ public class Log { if (findLine(pos)) { int column = 0; for (bp = lineStart; bp < pos; bp++) { - if (bp >= buf.length) + if (bp >= bufLen) return 0; if (buf[bp] == '\t') column = (column / TabInc * TabInc) + TabInc; diff --git a/langtools/test/tools/javac/T6668802.java b/langtools/test/tools/javac/T6668802.java new file mode 100644 index 00000000000..d357e2b39e7 --- /dev/null +++ b/langtools/test/tools/javac/T6668802.java @@ -0,0 +1,79 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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 6668802 + * @summary javac handles diagnostics for last line badly, if line not terminated by newline + */ + +import java.io.*; +import java.util.*; + +public class T6668802 +{ + public static void main(String[] args) throws Exception { + new T6668802().run(); + } + + void run() throws Exception { + String test = "public class Test {"; + File f = writeTestFile("Test.java", test); + String[] out = compileBadFile(f); + for (String line: out) + System.err.println(">>>" + line + "<<<"); + if (!out[1].equals(test)) { + show("expected", test); + show(" actual", out[1]); + throw new Error("test failed"); + } + } + + File writeTestFile(String path, String contents) throws IOException { + File f = new File(path); + FileWriter out = new FileWriter(f); + out.write(contents); + out.close(); + return f; + } + + String[] compileBadFile(File file) throws IOException { + List options = new ArrayList(); + options.add(file.getPath()); + System.err.println("compile: " + options); + String[] opts = options.toArray(new String[options.size()]); + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(opts, out); + if (rc == 0) + throw new Error("compilation succeeded unexpectedly"); + out.close(); + return sw.toString().split("[\n\r]+"); + } + + void show(String prefix, String text) { + System.err.println(prefix + ": (" + text.length() + ") " + text); + } +} From bf7f5e18873942c8ac65b3fb4bd13fd3dd4a4997 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 6 Mar 2008 10:30:17 -0800 Subject: [PATCH 079/274] 6667610: (Escape Analysis) retry compilation without EA if it fails During split unique types EA could exceed nodes limit and fail the method compilation. Reviewed-by: rasbold --- hotspot/src/share/vm/includeDB_compiler2 | 1 + hotspot/src/share/vm/opto/c2compiler.cpp | 13 ++++++++++-- hotspot/src/share/vm/opto/c2compiler.hpp | 1 + hotspot/src/share/vm/opto/compile.cpp | 16 ++++++++++++--- hotspot/src/share/vm/opto/compile.hpp | 9 ++++---- hotspot/src/share/vm/opto/escape.cpp | 26 +++++++++++++++++++++++- hotspot/src/share/vm/opto/parse1.cpp | 2 +- 7 files changed, 57 insertions(+), 11 deletions(-) diff --git a/hotspot/src/share/vm/includeDB_compiler2 b/hotspot/src/share/vm/includeDB_compiler2 index 01a6b9c94ce..514f6883b27 100644 --- a/hotspot/src/share/vm/includeDB_compiler2 +++ b/hotspot/src/share/vm/includeDB_compiler2 @@ -410,6 +410,7 @@ domgraph.cpp vectset.hpp escape.cpp allocation.hpp escape.cpp bcEscapeAnalyzer.hpp +escape.cpp c2compiler.hpp escape.cpp callnode.hpp escape.cpp cfgnode.hpp escape.cpp compile.hpp diff --git a/hotspot/src/share/vm/opto/c2compiler.cpp b/hotspot/src/share/vm/opto/c2compiler.cpp index 6543e692bde..591b7ea05c2 100644 --- a/hotspot/src/share/vm/opto/c2compiler.cpp +++ b/hotspot/src/share/vm/opto/c2compiler.cpp @@ -35,6 +35,9 @@ extern const int register_save_type[]; const char* C2Compiler::retry_no_subsuming_loads() { return "retry without subsuming loads"; } +const char* C2Compiler::retry_no_escape_analysis() { + return "retry without escape analysis"; +} void C2Compiler::initialize_runtime() { // Check assumptions used while running ADLC @@ -101,17 +104,23 @@ void C2Compiler::compile_method(ciEnv* env, initialize(); } bool subsume_loads = true; + bool do_escape_analysis = DoEscapeAnalysis; while (!env->failing()) { // Attempt to compile while subsuming loads into machine instructions. - Compile C(env, this, target, entry_bci, subsume_loads); + Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis); // Check result and retry if appropriate. if (C.failure_reason() != NULL) { - if (C.failure_reason_is(retry_no_subsuming_loads())) { + if (C.failure_reason_is(retry_no_subsuming_loads())) { assert(subsume_loads, "must make progress"); subsume_loads = false; continue; // retry } + if (C.failure_reason_is(retry_no_escape_analysis())) { + assert(do_escape_analysis, "must make progress"); + do_escape_analysis = false; + continue; // retry + } // Pass any other failure reason up to the ciEnv. // Note that serious, irreversible failures are already logged // on the ciEnv via env->record_method_not_compilable(). diff --git a/hotspot/src/share/vm/opto/c2compiler.hpp b/hotspot/src/share/vm/opto/c2compiler.hpp index dc5851082a4..a1d578797af 100644 --- a/hotspot/src/share/vm/opto/c2compiler.hpp +++ b/hotspot/src/share/vm/opto/c2compiler.hpp @@ -50,6 +50,7 @@ public: // sentinel value used to trigger backtracking in compile_method(). static const char* retry_no_subsuming_loads(); + static const char* retry_no_escape_analysis(); // Print compilation timers and statistics void print_timers(); diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index d62dbf3442f..475b281a89a 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -333,6 +333,12 @@ void Compile::print_compile_messages() { tty->print_cr("** Bailout: Recompile without subsuming loads **"); tty->print_cr("*********************************************************"); } + if (_do_escape_analysis != DoEscapeAnalysis && PrintOpto) { + // Recompiling without escape analysis + tty->print_cr("*********************************************************"); + tty->print_cr("** Bailout: Recompile without escape analysis **"); + tty->print_cr("*********************************************************"); + } if (env()->break_at_compile()) { // Open the debugger when compiing this method. tty->print("### Breaking when compiling: "); @@ -415,7 +421,7 @@ debug_only( int Compile::_debug_idx = 100000; ) // the continuation bci for on stack replacement. -Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci, bool subsume_loads ) +Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci, bool subsume_loads, bool do_escape_analysis ) : Phase(Compiler), _env(ci_env), _log(ci_env->log()), @@ -430,6 +436,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr _for_igvn(NULL), _warm_calls(NULL), _subsume_loads(subsume_loads), + _do_escape_analysis(do_escape_analysis), _failure_reason(NULL), _code_buffer("Compile::Fill_buffer"), _orig_pc_slot(0), @@ -487,7 +494,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr PhaseGVN gvn(node_arena(), estimated_size); set_initial_gvn(&gvn); - if (DoEscapeAnalysis) + if (_do_escape_analysis) _congraph = new ConnectionGraph(this); { // Scope for timing the parser @@ -577,6 +584,8 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr if (_congraph != NULL) { NOT_PRODUCT( TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, TimeCompiler); ) _congraph->compute_escape(); + if (failing()) return; + #ifndef PRODUCT if (PrintEscapeAnalysis) { _congraph->dump(); @@ -675,6 +684,7 @@ Compile::Compile( ciEnv* ci_env, _orig_pc_slot(0), _orig_pc_slot_offset_in_bytes(0), _subsume_loads(true), + _do_escape_analysis(false), _failure_reason(NULL), _code_buffer("Compile::Fill_buffer"), _node_bundling_limit(0), @@ -822,7 +832,7 @@ void Compile::Init(int aliaslevel) { // Type::update_loaded_types(_method, _method->constants()); // Init alias_type map. - if (!DoEscapeAnalysis && aliaslevel == 3) + if (!_do_escape_analysis && aliaslevel == 3) aliaslevel = 2; // No unique types without escape analysis _AliasLevel = aliaslevel; const int grow_ats = 16; diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index fcab3a37864..a4e4c1401f3 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -31,6 +31,7 @@ class InlineTree; class Int_Array; class Matcher; class MachNode; +class MachSafePointNode; class Node; class Node_Array; class Node_Notes; @@ -52,9 +53,6 @@ class TypeFunc; class Unique_Node_List; class nmethod; class WarmCallInfo; -#ifdef ENABLE_ZAP_DEAD_LOCALS -class MachSafePointNode; -#endif //------------------------------Compile---------------------------------------- // This class defines a top-level Compiler invocation. @@ -127,6 +125,7 @@ class Compile : public Phase { const int _compile_id; const bool _save_argument_registers; // save/restore arg regs for trampolines const bool _subsume_loads; // Load can be matched as part of a larger op. + const bool _do_escape_analysis; // Do escape analysis. ciMethod* _method; // The method being compiled. int _entry_bci; // entry bci for osr methods. const TypeFunc* _tf; // My kind of signature @@ -260,6 +259,8 @@ class Compile : public Phase { // instructions that subsume a load may result in an unschedulable // instruction sequence. bool subsume_loads() const { return _subsume_loads; } + // Do escape analysis. + bool do_escape_analysis() const { return _do_escape_analysis; } bool save_argument_registers() const { return _save_argument_registers; } @@ -560,7 +561,7 @@ class Compile : public Phase { // replacement, entry_bci indicates the bytecode for which to compile a // continuation. Compile(ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, - int entry_bci, bool subsume_loads); + int entry_bci, bool subsume_loads, bool do_escape_analysis); // Second major entry point. From the TypeFunc signature, generate code // to pass arguments from the Java calling convention to the C calling diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 62d0c0f1ac5..d66dd3f9866 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -395,6 +395,15 @@ PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, Gro if (result != NULL && C->get_alias_index(result->adr_type()) == alias_idx) { return result; } + if ((int)C->unique() + 2*NodeLimitFudgeFactor > MaxNodeLimit) { + if (C->do_escape_analysis() == true && !C->failing()) { + // Retry compilation without escape analysis. + // If this is the first failure, the sentinel string will "stick" + // to the Compile object, and the C2Compiler will see it and retry. + C->record_failure(C2Compiler::retry_no_escape_analysis()); + } + return NULL; + } orig_phi_worklist.append_if_missing(orig_phi); result = PhiNode::make(orig_phi->in(0), NULL, Type::MEMORY, atype); @@ -443,6 +452,9 @@ PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, Gro mem = nphi; } } + if (C->failing()) { + return NULL; + } result->set_req(idx++, mem); } #ifdef ASSERT @@ -672,6 +684,9 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (mem->is_Phi()) { mem = split_memory_phi(mem->as_Phi(), alias_idx, orig_phis, igvn); } + if (_compile->failing()) { + return; + } if (mem != n->in(MemNode::Memory)) set_map(n->_idx, mem); if (n->is_Load()) { @@ -742,7 +757,11 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if((uint)_compile->get_general_index(ni) == i) { Node *m = (ni >= nmm->req()) ? nmm->empty_memory() : nmm->in(ni); if (nmm->is_empty_memory(m)) { - nmm->set_memory_at(ni, split_memory_phi(mem->as_Phi(), ni, orig_phis, igvn)); + m = split_memory_phi(mem->as_Phi(), ni, orig_phis, igvn); + if (_compile->failing()) { + return; + } + nmm->set_memory_at(ni, m); } } } @@ -881,6 +900,11 @@ void ConnectionGraph::compute_escape() { // Now use the escape information to create unique types for // unescaped objects split_unique_types(alloc_worklist); + if (_compile->failing()) return; + + // Clean up after split unique types. + ResourceMark rm; + PhaseRemoveUseless pru(_compile->initial_gvn(), _compile->for_igvn()); } Node * ConnectionGraph::skip_casts(Node *n) { diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp index 4f8e93162cc..e3edece1a15 100644 --- a/hotspot/src/share/vm/opto/parse1.cpp +++ b/hotspot/src/share/vm/opto/parse1.cpp @@ -1836,7 +1836,7 @@ PhiNode *Parse::ensure_phi(int idx, bool nocreate) { PhiNode* phi = PhiNode::make(region, o, t); gvn().set_type(phi, t); - if (DoEscapeAnalysis) record_for_igvn(phi); + if (C->do_escape_analysis()) record_for_igvn(phi); map->set_req(idx, phi); return phi; } From 9a2759ee8df8c88c9440000388611b6bc37b7890 Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Thu, 6 Mar 2008 10:35:28 -0800 Subject: [PATCH 080/274] 6623830: SCCS cleanup has broken two regression tests Reviewed-by: chegar --- jdk/test/java/net/ResponseCache/file2.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/net/ResponseCache/file2.1 b/jdk/test/java/net/ResponseCache/file2.1 index 428de11adaa..1878bc2fe88 100644 --- a/jdk/test/java/net/ResponseCache/file2.1 +++ b/jdk/test/java/net/ResponseCache/file2.1 @@ -1,4 +1,4 @@ -/* @test +/* @test @(#)file2.1 1.1 03/08/09 * @summary Unit test for java.net.ResponseCacheHandler * @bug 4837267 * @author Yingxian Wang From 277c3322f6b6c0e232ca813e806b819ca5fd6bd8 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 6 Mar 2008 10:53:33 -0800 Subject: [PATCH 081/274] 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation Cloning an allocation will not allow scalar replacement since memory operations could not be associated with one allocation. Reviewed-by: rasbold --- hotspot/src/share/vm/opto/callnode.cpp | 1 + hotspot/src/share/vm/opto/callnode.hpp | 2 ++ hotspot/src/share/vm/opto/escape.cpp | 5 +++++ hotspot/src/share/vm/opto/loopTransform.cpp | 1 + hotspot/src/share/vm/opto/loopnode.cpp | 10 ++++++++-- hotspot/src/share/vm/opto/loopnode.hpp | 4 +++- 6 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 7fb60044039..f32562de0e4 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -832,6 +832,7 @@ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype, { init_class_id(Class_Allocate); init_flags(Flag_is_macro); + _is_scalar_replaceable = false; Node *topnode = C->top(); init_req( TypeFunc::Control , ctrl ); diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index c8315f94c96..d07a4d78d0e 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -626,6 +626,8 @@ public: return TypeFunc::make(domain, range); } + bool _is_scalar_replaceable; // Result of Escape Analysis + virtual uint size_of() const; // Size is bigger AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio, Node *size, Node *klass_node, Node *initial_test); diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index d66dd3f9866..7e2a18d8539 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -601,6 +601,11 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (es != PointsToNode::NoEscape || !ptn._unique_type) { continue; // can't make a unique type } + if (alloc->is_Allocate()) { + // Set the scalar_replaceable flag before the next check. + alloc->as_Allocate()->_is_scalar_replaceable = true; + } + set_map(alloc->_idx, n); set_map(n->_idx, alloc); const TypeInstPtr *t = igvn->type(n)->isa_instptr(); diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index 3de4e0cd752..de54863b5ba 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -1714,6 +1714,7 @@ void IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) // Gate unrolling, RCE and peeling efforts. if( !_child && // If not an inner loop, do not split !_irreducible && + _allow_optimizations && !tail()->is_top() ) { // Also ignore the occasional dead backedge if (!_has_call) { iteration_split_impl( phase, old_new ); diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp index 96140fae598..3ae7a41143e 100644 --- a/hotspot/src/share/vm/opto/loopnode.cpp +++ b/hotspot/src/share/vm/opto/loopnode.cpp @@ -1561,7 +1561,7 @@ PhaseIdealLoop::PhaseIdealLoop( PhaseIterGVN &igvn, const PhaseIdealLoop *verify // on just their loop-phi's for this pass of loop opts if( SplitIfBlocks && do_split_ifs ) { if (lpt->policy_range_check(this)) { - lpt->_rce_candidate = true; + lpt->_rce_candidate = 1; // = true } } } @@ -2145,7 +2145,7 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) { // as well? If so, then I found another entry into the loop. while( is_postvisited(l->_head) ) { // found irreducible - l->_irreducible = true; + l->_irreducible = 1; // = true l = l->_parent; _has_irreducible_loops = true; // Check for bad CFG here to prevent crash, and bailout of compile @@ -2199,6 +2199,12 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) { (iff->as_If()->_prob >= 0.01) ) innermost->_has_call = 1; } + } else if( n->is_Allocate() && n->as_Allocate()->_is_scalar_replaceable ) { + // Disable loop optimizations if the loop has a scalar replaceable + // allocation. This disabling may cause a potential performance lost + // if the allocation is not eliminated for some reason. + innermost->_allow_optimizations = false; + innermost->_has_call = 1; // = true } } } diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp index 60944afeee8..4bee9655d9f 100644 --- a/hotspot/src/share/vm/opto/loopnode.hpp +++ b/hotspot/src/share/vm/opto/loopnode.hpp @@ -289,13 +289,15 @@ public: _has_sfpt:1, // True if has non-call safepoint _rce_candidate:1; // True if candidate for range check elimination - Node_List* _required_safept; // A inner loop cannot delete these safepts; + Node_List* _required_safept; // A inner loop cannot delete these safepts; + bool _allow_optimizations; // Allow loop optimizations IdealLoopTree( PhaseIdealLoop* phase, Node *head, Node *tail ) : _parent(0), _next(0), _child(0), _head(head), _tail(tail), _phase(phase), _required_safept(NULL), + _allow_optimizations(true), _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0) { } From 373ad3f1c5c9db94fc2abb2071b58e04bc7f0b62 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Thu, 6 Mar 2008 11:37:14 -0800 Subject: [PATCH 082/274] 6628146: Exclude the .hgignore and .hgtags files from the source bundles Just add to list of SCM files. Reviewed-by: xdono --- jdk/make/common/shared/Platform.gmk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/make/common/shared/Platform.gmk b/jdk/make/common/shared/Platform.gmk index 915454a940c..648dcbeb7d6 100644 --- a/jdk/make/common/shared/Platform.gmk +++ b/jdk/make/common/shared/Platform.gmk @@ -101,10 +101,10 @@ REQUIRED_FREETYPE_VERSION=2.3.0 # so they will not be included when copying directory trees # or packaging up .jar files, etc. This applies to all workspaces. # -SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files +SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files .hgignore .hgtags # When changing SCM_DIRs also change SCM_DIRS_rexp and SCM_DIRS_prune: -SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files" -SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files \) -prune +SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files|.hgignore|.hgtags" +SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files -o -name .hgignore -o -name .hgtags \) -prune # Don't define this unless it's not defined ifndef VARIANT From 2dae31e47ce2c9c4ee6e424881894bcbb647b771 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Thu, 6 Mar 2008 13:56:47 -0800 Subject: [PATCH 083/274] 6624808: corba makefiles not using langtools compiler If supplied, the langtools javac should be used. Reviewed-by: xdono --- corba/make/common/shared/Defs.gmk | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/corba/make/common/shared/Defs.gmk b/corba/make/common/shared/Defs.gmk index 8cd237fed51..c7832863e34 100644 --- a/corba/make/common/shared/Defs.gmk +++ b/corba/make/common/shared/Defs.gmk @@ -281,6 +281,13 @@ endif # Get platform specific settings include $(BUILDDIR)/common/shared/Defs-$(PLATFORM).gmk +# Components +ifdef ALT_LANGTOOLS_DIST + LANGTOOLS_DIST :=$(call FullPath,$(ALT_LANGTOOLS_DIST)) +else + LANGTOOLS_DIST = +endif + # These are the same on all platforms but require the above platform include 1st # BOOTDIR: Bootstrap JDK, previous released JDK. From 623bcb71a54056435bbfadfa53edffc71dd207c8 Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Thu, 6 Mar 2008 16:06:45 -0800 Subject: [PATCH 084/274] 6578538: com.sun.crypto.provider.SunJCE instance leak using KRB5 and LoginContext Reviewed-by: valeriep --- .../sun/crypto/provider/PBKDF2KeyImpl.java | 8 ++- .../provider/KeyFactory/TestProviderLeak.java | 72 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 jdk/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java diff --git a/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java index afb9b3e94a5..ee5ed5a9229 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java @@ -34,6 +34,7 @@ import java.security.KeyRep; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.spec.InvalidKeySpecException; import javax.crypto.Mac; import javax.crypto.SecretKey; @@ -107,12 +108,17 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey { throw new InvalidKeySpecException("Key length is negative"); } try { - this.prf = Mac.getInstance(prfAlgo, new SunJCE()); + this.prf = Mac.getInstance(prfAlgo, "SunJCE"); } catch (NoSuchAlgorithmException nsae) { // not gonna happen; re-throw just in case InvalidKeySpecException ike = new InvalidKeySpecException(); ike.initCause(nsae); throw ike; + } catch (NoSuchProviderException nspe) { + // Again, not gonna happen; re-throw just in case + InvalidKeySpecException ike = new InvalidKeySpecException(); + ike.initCause(nspe); + throw ike; } this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength); } diff --git a/jdk/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java b/jdk/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java new file mode 100644 index 00000000000..6fe480cb6e0 --- /dev/null +++ b/jdk/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java @@ -0,0 +1,72 @@ +/* + * Copyright 2005-2007 Sun Microsystems, Inc. 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 6578538 + * @summary com.sun.crypto.provider.SunJCE instance leak using KRB5 and + * LoginContext + * @author Brad Wetmore + * + * @run main/othervm -Xmx2m TestProviderLeak + */ + +/* + * We force the leak to become a problem by specifying the minimum + * size heap we can (above). In current runs on a server and client + * machine, it took roughly 220-240 iterations to have the memory leak + * shut down other operations. It complained about "Unable to verify + * the SunJCE provider." + */ + +import javax.crypto.*; +import javax.crypto.spec.*; + +public class TestProviderLeak { + private static void dumpMemoryStats(String s) throws Exception { + Runtime rt = Runtime.getRuntime(); + System.out.println(s + ":\t" + + rt.freeMemory() + " bytes free"); + } + + public static void main(String [] args) throws Exception { + SecretKeyFactory skf = + SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "SunJCE"); + PBEKeySpec pbeKS = new PBEKeySpec( + "passPhrase".toCharArray(), new byte [] { 0 }, 5, 512); + for (int i = 0; i <= 1000; i++) { + try { + skf.generateSecret(pbeKS); + if ((i % 20) == 0) { + // Calling gc() isn't dependable, but doesn't hurt. + // Gives better output in leak cases. + System.gc(); + dumpMemoryStats("Iteration " + i); + } + } catch (Exception e) { + dumpMemoryStats("\nException seen at iteration " + i); + throw e; + } + } + } +} From 37b9a97e0882cd4e463349c50b172b21e6f03c91 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 6 Mar 2008 20:58:16 -0800 Subject: [PATCH 085/274] 6670459: Fix Node::dump() performance Dump full ideal graph takes forever. Reviewed-by: never, rasbold --- hotspot/src/share/vm/opto/node.cpp | 112 ++++++++--------------------- hotspot/src/share/vm/opto/node.hpp | 2 +- 2 files changed, 30 insertions(+), 84 deletions(-) diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index 14e112e2101..f361ef8b888 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -1462,26 +1462,6 @@ void Node::dump_out() const { } //------------------------------dump_nodes------------------------------------- - -// Helper class for dump_nodes. Wraps an old and new VectorSet. -class OldNewVectorSet : public StackObj { - Arena* _node_arena; - VectorSet _old_vset, _new_vset; - VectorSet* select(Node* n) { - return _node_arena->contains(n) ? &_new_vset : &_old_vset; - } - public: - OldNewVectorSet(Arena* node_arena, ResourceArea* area) : - _node_arena(node_arena), - _old_vset(area), _new_vset(area) {} - - void set(Node* n) { select(n)->set(n->_idx); } - bool test_set(Node* n) { return select(n)->test_set(n->_idx) != 0; } - bool test(Node* n) { return select(n)->test(n->_idx) != 0; } - void del(Node* n) { (*select(n)) >>= n->_idx; } -}; - - static void dump_nodes(const Node* start, int d, bool only_ctrl) { Node* s = (Node*)start; // remove const if (NotANode(s)) return; @@ -1489,75 +1469,41 @@ static void dump_nodes(const Node* start, int d, bool only_ctrl) { uint depth = (uint)ABS(d); int direction = d; Compile* C = Compile::current(); - ResourceArea *area = Thread::current()->resource_area(); - Node_Stack stack(area, MIN2(depth, C->unique() >> 1)); - OldNewVectorSet dumped(C->node_arena(), area); - OldNewVectorSet on_stack(C->node_arena(), area); + GrowableArray nstack(C->unique()); - on_stack.set(s); - stack.push(s, 0); - if (direction < 0) { - dumped.set(s); - s->dump(); - } + nstack.append(s); + int begin = 0; + int end = 0; + for(uint i = 0; i < depth; i++) { + end = nstack.length(); + for(int j = begin; j < end; j++) { + Node* tp = nstack.at(j); + uint limit = direction > 0 ? tp->len() : tp->outcnt(); + for(uint k = 0; k < limit; k++) { + Node* n = direction > 0 ? tp->in(k) : tp->raw_out(k); - // Do a depth first walk over edges - while (stack.is_nonempty()) { - Node* tp = stack.node(); - uint idx = stack.index(); - uint limit; - // Limit depth - if (stack.size() < depth) { - limit = direction > 0 ? tp->len() : tp->outcnt(); - } else { - limit = 0; // reached depth limit. - } - if (idx >= limit) { - // no more arcs to visit - if (direction > 0 && !dumped.test_set(tp)) tp->dump(); - on_stack.del(tp); - stack.pop(); - } else { - // process the "idx"th arc - stack.set_index(idx + 1); - Node* n = direction > 0 ? tp->in(idx) : tp->raw_out(idx); + if (NotANode(n)) continue; + // do not recurse through top or the root (would reach unrelated stuff) + if (n->is_Root() || n->is_top()) continue; + if (only_ctrl && !n->is_CFG()) continue; - if (NotANode(n)) continue; - // do not recurse through top or the root (would reach unrelated stuff) - if (n->is_Root() || n->is_top()) continue; - if (only_ctrl && !n->is_CFG()) continue; - - if (!on_stack.test(n)) { // forward arc - if (direction < 0 && !dumped.test_set(n)) n->dump(); - stack.push(n, 0); - on_stack.set(n); - } else { // back or cross arc - // print loop if there are no phis or regions in the mix - bool found_loop_breaker = false; - int k; - for (k = stack.size() - 1; k >= 0; k--) { - Node* m = stack.node_at(k); - if (m->is_Phi() || m->is_Region() || m->is_Root() || m->is_Start()) { - found_loop_breaker = true; - break; - } - if (m == n) // Found loop head - break; - } - assert(k >= 0, "n must be on stack"); - - if (!found_loop_breaker) { - tty->print("# %s LOOP FOUND:", only_ctrl ? "CONTROL" : "DATA"); - for (int i = stack.size() - 1; i >= k; i--) { - Node* m = stack.node_at(i); - bool mnew = C->node_arena()->contains(m); - tty->print(" %s%d:%s", (mnew? "": "o"), m->_idx, m->Name()); - if (i != 0) tty->print(direction > 0? " <-": " ->"); - } - tty->cr(); + bool on_stack = nstack.contains(n); + if (!on_stack) { + nstack.append(n); } } } + begin = end; + } + end = nstack.length(); + if (direction > 0) { + for(int j = end-1; j >= 0; j--) { + nstack.at(j)->dump(); + } + } else { + for(int j = 0; j < end; j++) { + nstack.at(j)->dump(); + } } } diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 8066da703ba..881de4d21b9 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -1384,7 +1384,7 @@ public: _inode_top->indx = i; } uint size_max() const { return (uint)pointer_delta(_inode_max, _inodes, sizeof(INode)); } // Max size - uint size() const { return (uint)pointer_delta(_inode_top, _inodes, sizeof(INode)) + 1; } // Current size + uint size() const { return (uint)pointer_delta((_inode_top+1), _inodes, sizeof(INode)); } // Current size bool is_nonempty() const { return (_inode_top >= _inodes); } bool is_empty() const { return (_inode_top < _inodes); } void clear() { _inode_top = _inodes - 1; } // retain storage From b02a978ac4384851d1b1c2dc4533da845aeda427 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Mar 2008 09:57:22 +0000 Subject: [PATCH 086/274] 6667108: typo in javadoc for java.net.Socket.getRemoteSocketAddress() Simple typo in method specification. Reviewed-by: jccollet --- jdk/src/share/classes/java/net/Socket.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index c02dd4e2855..478bece1577 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -731,7 +731,7 @@ class Socket implements java.io.Closeable { * then this method will continue to return the connected address * after the socket is closed. * - * @return a SocketAddress reprensenting the remote endpoint of this + * @return a SocketAddress representing the remote endpoint of this * socket, or null if it is not connected yet. * @see #getInetAddress() * @see #getPort() From b8383dba86319e0ce71af09484c5b6fd2321c4dc Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Mar 2008 11:30:32 +0000 Subject: [PATCH 087/274] 6615656: Removed unimplemented java.net methods Reviewed-by: jccollet --- jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java | 1 - jdk/src/share/classes/java/net/NetworkInterface.java | 2 -- jdk/src/solaris/classes/java/net/PlainSocketImpl.java | 3 --- jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java | 3 --- jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java | 3 --- 5 files changed, 12 deletions(-) diff --git a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java index ffc23824b61..41c39f0e15f 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java @@ -664,7 +664,6 @@ abstract class AbstractPlainSocketImpl extends SocketImpl abstract void socketSetOption(int cmd, boolean on, Object value) throws SocketException; abstract int socketGetOption(int opt, Object iaContainerObj) throws SocketException; - abstract int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) throws SocketException; abstract void socketSendUrgentData(int data) throws IOException; diff --git a/jdk/src/share/classes/java/net/NetworkInterface.java b/jdk/src/share/classes/java/net/NetworkInterface.java index 8b2899c48d9..0ce3a8d580b 100644 --- a/jdk/src/share/classes/java/net/NetworkInterface.java +++ b/jdk/src/share/classes/java/net/NetworkInterface.java @@ -425,8 +425,6 @@ public final class NetworkInterface { return virtual; } - private native static long getSubnet0(String name, int ind) throws SocketException; - private native static Inet4Address getBroadcast0(String name, int ind) throws SocketException; private native static boolean isUp0(String name, int ind) throws SocketException; private native static boolean isLoopback0(String name, int ind) throws SocketException; private native static boolean supportsMulticast0(String name, int ind) throws SocketException; diff --git a/jdk/src/solaris/classes/java/net/PlainSocketImpl.java b/jdk/src/solaris/classes/java/net/PlainSocketImpl.java index 113bcb0183e..25e2bab81f5 100644 --- a/jdk/src/solaris/classes/java/net/PlainSocketImpl.java +++ b/jdk/src/solaris/classes/java/net/PlainSocketImpl.java @@ -76,9 +76,6 @@ class PlainSocketImpl extends AbstractPlainSocketImpl native int socketGetOption(int opt, Object iaContainerObj) throws SocketException; - native int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException; - native void socketSendUrgentData(int data) throws IOException; } diff --git a/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java b/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java index 116046603f8..4e92df7f687 100644 --- a/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java +++ b/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java @@ -218,9 +218,6 @@ class DualStackPlainSocketImpl extends AbstractPlainSocketImpl return value; } - int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException {return 0;} // un-implemented REMOVE - void socketSendUrgentData(int data) throws IOException { int nativefd = checkAndReturnNativeFD(); sendOOB(nativefd, data); diff --git a/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java b/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java index 9475bd3f7a1..13851124b32 100644 --- a/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java +++ b/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java @@ -199,8 +199,5 @@ class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl native int socketGetOption(int opt, Object iaContainerObj) throws SocketException; - native int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException; - native void socketSendUrgentData(int data) throws IOException; } From 1b9d87730f2e79cbd91cabad4fdc2281b47d99b8 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Mar 2008 11:51:27 +0000 Subject: [PATCH 088/274] 6591358: documentation error in URLConnection.setRequestProperty("accept", ...) Simple doc change, "accept" -> "Accept" Reviewed-by: jccollet --- jdk/src/share/classes/java/net/URLConnection.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/net/URLConnection.java b/jdk/src/share/classes/java/net/URLConnection.java index c1236bd3a63..a78032a2fcc 100644 --- a/jdk/src/share/classes/java/net/URLConnection.java +++ b/jdk/src/share/classes/java/net/URLConnection.java @@ -1072,7 +1072,7 @@ public abstract class URLConnection { * properties to be appended into a single property. * * @param key the keyword by which the request is known - * (e.g., "accept"). + * (e.g., "Accept"). * @param value the value associated with it. * @throws IllegalStateException if already connected * @throws NullPointerException if key is null @@ -1096,7 +1096,7 @@ public abstract class URLConnection { * existing values associated with the same key. * * @param key the keyword by which the request is known - * (e.g., "accept"). + * (e.g., "Accept"). * @param value the value associated with it. * @throws IllegalStateException if already connected * @throws NullPointerException if key is null @@ -1120,7 +1120,7 @@ public abstract class URLConnection { * Returns the value of the named general request property for this * connection. * - * @param key the keyword by which the request is known (e.g., "accept"). + * @param key the keyword by which the request is known (e.g., "Accept"). * @return the value of the named general request property for this * connection. If key is null, then null is returned. * @throws IllegalStateException if already connected @@ -1164,7 +1164,7 @@ public abstract class URLConnection { * these properties. * * @param key the keyword by which the request is known - * (e.g., "accept"). + * (e.g., "Accept"). * @param value the value associated with the key. * * @see java.net.URLConnection#setRequestProperty(java.lang.String,java.lang.String) @@ -1183,7 +1183,7 @@ public abstract class URLConnection { * Returns the value of the default request property. Default request * properties are set for every connection. * - * @param key the keyword by which the request is known (e.g., "accept"). + * @param key the keyword by which the request is known (e.g., "Accept"). * @return the value of the default request property * for the specified key. * From 349fef2b701708d3aa218d67e246fdcb22d07924 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Mar 2008 13:00:44 +0000 Subject: [PATCH 089/274] 6628576: InterfaceAddress.equals() NPE when broadcast field == null Update logic in equals to correctly handle nulls. Reviewed-by: michaelm --- .../classes/java/net/InterfaceAddress.java | 6 +- .../java/net/InterfaceAddress/Equals.java | 119 ++++++++++++++++++ 2 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 jdk/test/java/net/InterfaceAddress/Equals.java diff --git a/jdk/src/share/classes/java/net/InterfaceAddress.java b/jdk/src/share/classes/java/net/InterfaceAddress.java index e352c35f80b..66a65358cbc 100644 --- a/jdk/src/share/classes/java/net/InterfaceAddress.java +++ b/jdk/src/share/classes/java/net/InterfaceAddress.java @@ -103,11 +103,9 @@ public class InterfaceAddress { return false; } InterfaceAddress cmp = (InterfaceAddress) obj; - if ((address != null & cmp.address == null) || - (!address.equals(cmp.address))) + if ( !(address == null ? cmp.address == null : address.equals(cmp.address)) ) return false; - if ((broadcast != null & cmp.broadcast == null) || - (!broadcast.equals(cmp.broadcast))) + if ( !(broadcast == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)) ) return false; if (maskLength != cmp.maskLength) return false; diff --git a/jdk/test/java/net/InterfaceAddress/Equals.java b/jdk/test/java/net/InterfaceAddress/Equals.java new file mode 100644 index 00000000000..5403bebe04c --- /dev/null +++ b/jdk/test/java/net/InterfaceAddress/Equals.java @@ -0,0 +1,119 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6628576 + * @summary InterfaceAddress.equals() NPE when broadcast field == null + */ + +import java.net.InterfaceAddress; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; + +public class Equals +{ + public static void main(String[] args) { + InterfaceAddress ia1; + InterfaceAddress ia2; + InetAddress loopbackAddr = InetAddress.getLoopbackAddress(); + InetAddress broadcast1 = null; + InetAddress broadcast2 = null; + + try { + broadcast1 = InetAddress.getByName("255.255.255.0"); + broadcast2 = InetAddress.getByName("255.255.0.0"); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + + ia1 = createInterfaceAddress(loopbackAddr, (InetAddress) null, (short)45); + ia2 = createInterfaceAddress(loopbackAddr, (InetAddress) null, (short)45); + + compare(ia1, ia2, true); + + ia2 = createInterfaceAddress(loopbackAddr, broadcast1, (short)45); + compare(ia1, ia2, false); + + ia2 = createInterfaceAddress((InetAddress)null, broadcast1, (short)45); + compare(ia1, ia2, false); + + ia1 = createInterfaceAddress(loopbackAddr, broadcast2, (short)45); + ia2 = createInterfaceAddress(loopbackAddr, broadcast2, (short)45); + compare(ia1, ia2, true); + + ia1.equals(null); + } + + static void compare(InterfaceAddress ia1, InterfaceAddress ia2, boolean equal) { + if (ia1.equals(ia2) != equal) + throw new RuntimeException("Failed: " + ia1 + " not equals to " + ia2); + + if (ia2.equals(ia1) != equal) + throw new RuntimeException("Failed: " + ia2 + " not equals to " + ia1); + } + + /** + * Returns an InterfaceAddress instance with its fields set the the values + * specificed. + */ + static InterfaceAddress createInterfaceAddress( + InetAddress address, InetAddress broadcast, short prefixlength) { + try { + Class IAClass = InterfaceAddress.class; + InterfaceAddress ia; + Constructor ctr = IAClass.getDeclaredConstructor(); + ctr.setAccessible(true); + + Field addressField = IAClass.getDeclaredField("address"); + addressField.setAccessible(true); + + Field broadcastField = IAClass.getDeclaredField("broadcast"); + broadcastField.setAccessible(true); + + Field maskLengthField = IAClass.getDeclaredField("maskLength"); + maskLengthField.setAccessible(true); + + ia = ctr.newInstance(); + addressField.set(ia, address); + broadcastField.set(ia, broadcast); + maskLengthField.setShort(ia, prefixlength); + + return ia; + } catch (NoSuchFieldException nsfe) { + nsfe.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InstantiationException ie) { + ie.printStackTrace(); + } catch (IllegalAccessException iae) { + iae.printStackTrace(); + } catch (InvocationTargetException ite) { + ite.printStackTrace(); + } + + return null; + } +} From afd3b1f4ba2113f1e2a5f5d503f3451880605669 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Mar 2008 15:15:54 +0000 Subject: [PATCH 090/274] 6672682: Forgotten file from CR 6615656 Reviewed-by: michaelm --- jdk/src/windows/classes/java/net/PlainSocketImpl.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/jdk/src/windows/classes/java/net/PlainSocketImpl.java b/jdk/src/windows/classes/java/net/PlainSocketImpl.java index c65c71c670f..cde60b53087 100644 --- a/jdk/src/windows/classes/java/net/PlainSocketImpl.java +++ b/jdk/src/windows/classes/java/net/PlainSocketImpl.java @@ -304,11 +304,6 @@ class PlainSocketImpl extends AbstractPlainSocketImpl return impl.socketGetOption(opt, iaContainerObj); } - int socketGetOption1(int opt, Object iaContainerObj, FileDescriptor fd) - throws SocketException { - return impl.socketGetOption1(opt, iaContainerObj, fd); - } - void socketSendUrgentData(int data) throws IOException { impl.socketSendUrgentData(data); } From 950ab581668ed5c5cdb6c60ad27393e6c11fdef3 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Mar 2008 07:25:17 -0800 Subject: [PATCH 091/274] 6628661: NTLM-authentication doesn't work with non-ASCII letters Use JNU_GetStringPlatformChars to convert jstrings to the locale specific native C strings Reviewed-by: michaelm --- .../net/www/protocol/http/NTLMAuthSequence.c | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c b/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c index 4d4e56ee807..580e2fabadb 100644 --- a/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c +++ b/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c @@ -36,6 +36,8 @@ #include #include +#include "jni_util.h" + #define SECURITY_WIN32 #include "sspi.h" #include "issperr.h" @@ -117,22 +119,36 @@ JNIEXPORT jlong JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_getCrede { SEC_WINNT_AUTH_IDENTITY AuthId; SEC_WINNT_AUTH_IDENTITY * pAuthId; - CHAR *pUser = 0; - CHAR *pDomain = 0; - CHAR *pPassword = 0; + const CHAR *pUser = 0; + const CHAR *pDomain = 0; + const CHAR *pPassword = 0; CredHandle *pCred; TimeStamp ltime; jboolean isCopy; SECURITY_STATUS ss; if (user != 0) { - pUser = (CHAR *)(*env)->GetStringUTFChars(env, user, &isCopy); + pUser = JNU_GetStringPlatformChars(env, user, &isCopy); + if (pUser == NULL) + return 0; // pending Exception } if (domain != 0) { - pDomain = (CHAR *)(*env)->GetStringUTFChars(env, domain, &isCopy); + pDomain = JNU_GetStringPlatformChars(env, domain, &isCopy); + if (pDomain == NULL) { + if (pUser != NULL) + JNU_ReleaseStringPlatformChars(env, user, pUser); + return 0; // pending Exception + } } if (password != 0) { - pPassword = (CHAR *)(*env)->GetStringUTFChars(env, password, &isCopy); + pPassword = JNU_GetStringPlatformChars(env, password, &isCopy); + if (pPassword == NULL) { + if(pUser != NULL) + JNU_ReleaseStringPlatformChars(env, user, pUser); + if(pDomain != NULL) + JNU_ReleaseStringPlatformChars(env, domain, pDomain); + return 0; // pending Exception + } } pCred = (CredHandle *)malloc(sizeof (CredHandle)); @@ -167,6 +183,14 @@ JNIEXPORT jlong JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_getCrede pCred, <ime ); + /* Release resources held by JNU_GetStringPlatformChars */ + if (pUser != NULL) + JNU_ReleaseStringPlatformChars(env, user, pUser); + if (pPassword != NULL) + JNU_ReleaseStringPlatformChars(env, password, pPassword); + if (pDomain != NULL) + JNU_ReleaseStringPlatformChars(env, domain, pDomain); + if (ss == 0) { return (jlong) pCred; } else { @@ -181,7 +205,6 @@ JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_NTLMAuthSequence_get VOID *pInput = 0; DWORD inputLen; CHAR buffOut[512]; - DWORD pcbBuffOut; jboolean isCopy; SECURITY_STATUS ss; SecBufferDesc OutBuffDesc; From 077f55f47081da77b51683fabd05d00f0eebcb58 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 Mar 2008 17:17:49 +0000 Subject: [PATCH 092/274] 6631048: Problem when writing on output stream of HttpURLConnection Fix up logic in ChunkedOutputStream.write Reviewed-by: jccollet --- .../sun/net/www/http/ChunkedOutputStream.java | 13 ++- .../www/http/ChunkedOutputStream/Test.java | 98 ++++++++++++++++++- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/sun/net/www/http/ChunkedOutputStream.java b/jdk/src/share/classes/sun/net/www/http/ChunkedOutputStream.java index a06b5afe228..5f4a7902f62 100644 --- a/jdk/src/share/classes/sun/net/www/http/ChunkedOutputStream.java +++ b/jdk/src/share/classes/sun/net/www/http/ChunkedOutputStream.java @@ -177,14 +177,23 @@ public class ChunkedOutputStream extends PrintStream { return; } - if (len > MAX_BUF_SIZE) { + int l = preferredChunkSize - count; + + if ((len > MAX_BUF_SIZE) && (len > l)) { + /* current chunk is empty just write the data */ + if (count == 0) { + count = len; + flush (b, false, off); + return; + } + /* first finish the current chunk */ - int l = preferredChunkSize - count; if (l > 0) { System.arraycopy(b, off, buf, count, l); count = preferredChunkSize; flush(buf, false); } + count = len - l; /* Now write the rest of the data */ flush (b, false, l+off); diff --git a/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java b/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java index 89bc8b3bf85..3866761ade6 100644 --- a/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java +++ b/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java @@ -23,7 +23,7 @@ /** * @test - * @bug 5026745 + * @bug 5026745 6631048 * @run main/othervm/timeout=500 Test * @summary Cannot flush output stream when writing to an HttpUrlConnection */ @@ -158,6 +158,50 @@ public class Test implements HttpHandler { exchange.sendResponseHeaders(200, 0); } break; + case 10: /* test11 */ + printRequestURI(exchange); + is = exchange.getRequestBody(); + s = read (is, str1.length()); + + error = false; + for (int i=10; i< 30 * 1024; i++) { + byte c = (byte)is.read(); + + if (c != (byte)i) { + error = true; + System.out.println ("error at position " + i); + } + } + if (!s.equals(str1) ) { + System.out.println ("received string : " + s); + exchange.sendResponseHeaders(500, 0); + } else if (error) { + System.out.println ("error"); + exchange.sendResponseHeaders(500, 0); + } else { + exchange.sendResponseHeaders(200, 0); + } + break; + case 11: /* test12 */ + printRequestURI(exchange); + is = exchange.getRequestBody(); + + error = false; + for (int i=10; i< 30 * 1024; i++) { + byte c = (byte)is.read(); + + if (c != (byte)i) { + error = true; + System.out.println ("error at position " + i); + } + } + if (error) { + System.out.println ("error"); + exchange.sendResponseHeaders(500, 0); + } else { + exchange.sendResponseHeaders(200, 0); + } + break; } exchange.close(); count ++; @@ -390,6 +434,56 @@ public class Test implements HttpHandler { } } + static void test11 (String u) throws Exception { + URL url = new URL (u); + System.out.println ("client opening connection to: " + u); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); + urlc.setChunkedStreamingMode (36 * 1024); + urlc.setDoOutput(true); + urlc.setRequestMethod ("POST"); + OutputStream os = urlc.getOutputStream (); + byte[] buf = new byte [30 * 1024]; + for (int i=0; i< 30 * 1024; i++) { + buf[i] = (byte) i; + } + /* write a small bit first, and then the large buffer */ + os.write (str1.getBytes()); + //os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */ + os.write (buf, 10, (10 * 1024) - 10); + os.write (buf, (10 * 1024), (10 * 1024)); + os.write (buf, (20 * 1024), (10 * 1024)); + os.close(); + InputStream is = urlc.getInputStream(); + is.close(); + int ret = urlc.getResponseCode(); + if (ret != 200) { + throw new Exception ("Expected 200: got " + ret); + } + } + + static void test12 (String u) throws Exception { + URL url = new URL (u); + System.out.println ("client opening connection to: " + u); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection (); + urlc.setChunkedStreamingMode (36 * 1024); + urlc.setDoOutput(true); + urlc.setRequestMethod ("POST"); + OutputStream os = urlc.getOutputStream (); + byte[] buf = new byte [30 * 1024]; + for (int i=0; i< 30 * 1024; i++) { + buf[i] = (byte) i; + } + os.write (buf, 10, buf.length - 10); /* skip 10 bytes to test offset */ + os.close(); + InputStream is = urlc.getInputStream(); + is.close(); + int ret = urlc.getResponseCode(); + if (ret != 200) { + throw new Exception ("Expected 200: got " + ret); + } + } + + static com.sun.net.httpserver.HttpServer httpserver; public static void main (String[] args) throws Exception { @@ -411,6 +505,8 @@ public class Test implements HttpHandler { test8("http://localhost:"+ port + "/test/test8"); test9("http://localhost:"+ port + "/test/test9"); test10("http://localhost:"+ port + "/test/test10"); + test11("http://localhost:"+ port + "/test/test11"); + test12("http://localhost:"+ port + "/test/test12"); } finally { if (httpserver != null) httpserver.stop(0); From 9ec574b7e69a5d964a8185d71f8c5e602deb66f1 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 7 Mar 2008 11:09:13 -0800 Subject: [PATCH 093/274] 6667605: (Escape Analysis) inline java constructors when EA is on Java constructors should be inlined to be able scalar replace a new object Reviewed-by: rasbold --- hotspot/src/share/vm/opto/bytecodeInfo.cpp | 95 +++++++++++++++++----- hotspot/src/share/vm/opto/parse.hpp | 6 +- hotspot/src/share/vm/opto/phaseX.cpp | 80 ++---------------- 3 files changed, 85 insertions(+), 96 deletions(-) diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 10648c654ac..1b12ee877ad 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -79,8 +79,20 @@ static void print_indent(int depth) { for (int i = depth; i != 0; --i) tty->print(" "); } +static bool is_init_with_ea(ciMethod* callee_method, + ciMethod* caller_method, Compile* C) { + // True when EA is ON and a java constructor is called or + // a super constructor is called from an inlined java constructor. + return DoEscapeAnalysis && EliminateAllocations && + ( callee_method->is_initializer() || + (caller_method->is_initializer() && + caller_method != C->method() && + caller_method->holder()->is_subclass_of(callee_method->holder())) + ); +} + // positive filter: should send be inlined? returns NULL, if yes, or rejection msg -const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { +const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { // Allows targeted inlining if(callee_method->should_inline()) { *wci_result = *(WarmCallInfo::always_hot()); @@ -97,7 +109,8 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ci int size = callee_method->code_size(); // Check for too many throws (and not too huge) - if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) { + if(callee_method->interpreter_throwout_count() > InlineThrowCount && + size < InlineThrowMaxSize ) { wci_result->set_profit(wci_result->profit() * 100); if (PrintInlining && Verbose) { print_indent(inline_depth()); @@ -114,8 +127,12 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ci int invoke_count = method()->interpreter_invocation_count(); assert( invoke_count != 0, "Require invokation count greater than zero"); int freq = call_site_count/invoke_count; + // bump the max size if the call is frequent - if ((freq >= InlineFrequencyRatio) || (call_site_count >= InlineFrequencyCount)) { + if ((freq >= InlineFrequencyRatio) || + (call_site_count >= InlineFrequencyCount) || + is_init_with_ea(callee_method, caller_method, C)) { + max_size = C->freq_inline_size(); if (size <= max_size && TraceFrequencyInlining) { print_indent(inline_depth()); @@ -126,7 +143,8 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ci } } else { // Not hot. Check for medium-sized pre-existing nmethod at cold sites. - if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode/4) + if (callee_method->has_compiled_code() && + callee_method->instructions_size() > InlineSmallCode/4) return "already compiled into a medium method"; } if (size > max_size) { @@ -139,7 +157,7 @@ const char* InlineTree::shouldInline(ciMethod* callee_method, int caller_bci, ci // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg -const char* InlineTree::shouldNotInline(ciMethod *callee_method, WarmCallInfo* wci_result) const { +const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg if (!UseOldInlining) { const char* fail = NULL; @@ -204,9 +222,23 @@ const char* InlineTree::shouldNotInline(ciMethod *callee_method, WarmCallInfo* w // use frequency-based objections only for non-trivial methods if (callee_method->code_size() <= MaxTrivialSize) return NULL; - if (UseInterpreter && !CompileTheWorld) { // don't use counts with -Xcomp or CTW - if (!callee_method->has_compiled_code() && !callee_method->was_executed_more_than(0)) return "never executed"; - if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return "executed < MinInliningThreshold times"; + + // don't use counts with -Xcomp or CTW + if (UseInterpreter && !CompileTheWorld) { + + if (!callee_method->has_compiled_code() && + !callee_method->was_executed_more_than(0)) { + return "never executed"; + } + + if (is_init_with_ea(callee_method, caller_method, C)) { + + // Escape Analysis: inline all executed constructors + + } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, + CompileThreshold >> 1))) { + return "executed < MinInliningThreshold times"; + } } if (callee_method->should_not_inline()) { @@ -219,8 +251,7 @@ const char* InlineTree::shouldNotInline(ciMethod *callee_method, WarmCallInfo* w //-----------------------------try_to_inline----------------------------------- // return NULL if ok, reason for not inlining otherwise // Relocated from "InliningClosure::try_to_inline" -const char* InlineTree::try_to_inline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { - ciMethod* caller_method = method(); +const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { // Old algorithm had funny accumulating BC-size counters if (UseOldInlining && ClipInlining @@ -229,25 +260,47 @@ const char* InlineTree::try_to_inline(ciMethod* callee_method, int caller_bci, c } const char *msg = NULL; - if ((msg = shouldInline(callee_method, caller_bci, profile, wci_result)) != NULL) return msg; - if ((msg = shouldNotInline(callee_method, wci_result)) != NULL) return msg; + if ((msg = shouldInline(callee_method, caller_method, caller_bci, + profile, wci_result)) != NULL) { + return msg; + } + if ((msg = shouldNotInline(callee_method, caller_method, + wci_result)) != NULL) { + return msg; + } bool is_accessor = InlineAccessors && callee_method->is_accessor(); // suppress a few checks for accessors and trivial methods if (!is_accessor && callee_method->code_size() > MaxTrivialSize) { - // don't inline into giant methods - if (C->unique() > (uint)NodeCountInliningCutoff) return "NodeCountInliningCutoff"; - // don't inline unreached call sites - if (profile.count() == 0) return "call site not reached"; + // don't inline into giant methods + if (C->unique() > (uint)NodeCountInliningCutoff) { + return "NodeCountInliningCutoff"; + } + + if ((!UseInterpreter || CompileTheWorld) && + is_init_with_ea(callee_method, caller_method, C)) { + + // Escape Analysis stress testing when running Xcomp or CTW: + // inline constructors even if they are not reached. + + } else if (profile.count() == 0) { + // don't inline unreached call sites + return "call site not reached"; + } } - if (!C->do_inlining() && InlineAccessors && !is_accessor) return "not an accessor"; - - if( inline_depth() > MaxInlineLevel ) return "inlining too deep"; + if (!C->do_inlining() && InlineAccessors && !is_accessor) { + return "not an accessor"; + } + if( inline_depth() > MaxInlineLevel ) { + return "inlining too deep"; + } if( method() == callee_method && - inline_depth() > MaxRecursiveInlineLevel ) return "recursively inlining too deep"; + inline_depth() > MaxRecursiveInlineLevel ) { + return "recursively inlining too deep"; + } int size = callee_method->code_size(); @@ -336,7 +389,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); - failure_msg = try_to_inline(callee_method, caller_bci, profile, &wci); + failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci); if (failure_msg != NULL && C->log() != NULL) { C->log()->begin_elem("inline_fail reason='"); C->log()->text("%s", failure_msg); diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index 60ffdf17dd7..df2bc6cd54a 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -54,9 +54,9 @@ protected: InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, JVMState* caller_jvms, int caller_bci); - const char* try_to_inline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result); - const char* shouldInline(ciMethod* callee_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; - const char* shouldNotInline(ciMethod* callee_method, WarmCallInfo* wci_result) const; + const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result); + const char* shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; + const char* shouldNotInline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const; void print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const PRODUCT_RETURN; InlineTree *caller_tree() const { return _caller_tree; } diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 3c5cd2cca13..90b34d4afad 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -648,79 +648,9 @@ ConNode* PhaseTransform::zerocon(BasicType bt) { //============================================================================= //------------------------------transform-------------------------------------- // Return a node which computes the same function as this node, but in a -// faster or cheaper fashion. The Node passed in here must have no other -// pointers to it, as its storage will be reclaimed if the Node can be -// optimized away. +// faster or cheaper fashion. Node *PhaseGVN::transform( Node *n ) { - NOT_PRODUCT( set_transforms(); ) - - // Apply the Ideal call in a loop until it no longer applies - Node *k = n; - NOT_PRODUCT( uint loop_count = 0; ) - while( 1 ) { - Node *i = k->Ideal(this, /*can_reshape=*/false); - if( !i ) break; - assert( i->_idx >= k->_idx, "Idealize should return new nodes, use Identity to return old nodes" ); - // Can never reclaim storage for Ideal calls, because the Ideal call - // returns a new Node, bumping the High Water Mark and our old Node - // is caught behind the new one. - //if( k != i ) { - //k->destruct(); // Reclaim storage for recent node - k = i; - //} - assert(loop_count++ < K, "infinite loop in PhaseGVN::transform"); - } - NOT_PRODUCT( if( loop_count != 0 ) { set_progress(); } ) - - // If brand new node, make space in type array. - ensure_type_or_null(k); - - // Cache result of Value call since it can be expensive - // (abstract interpretation of node 'k' using phase->_types[ inputs ]) - const Type *t = k->Value(this); // Get runtime Value set - assert(t != NULL, "value sanity"); - if (type_or_null(k) != t) { -#ifndef PRODUCT - // Do not record transformation or value construction on first visit - if (type_or_null(k) == NULL) { - inc_new_values(); - set_progress(); - } -#endif - set_type(k, t); - // If k is a TypeNode, capture any more-precise type permanently into Node - k->raise_bottom_type(t); - } - - if( t->singleton() && !k->is_Con() ) { - //k->destruct(); // Reclaim storage for recent node - NOT_PRODUCT( set_progress(); ) - return makecon(t); // Turn into a constant - } - - // Now check for Identities - Node *i = k->Identity(this); // Look for a nearby replacement - if( i != k ) { // Found? Return replacement! - //k->destruct(); // Reclaim storage for recent node - NOT_PRODUCT( set_progress(); ) - return i; - } - - // Try Global Value Numbering - i = hash_find_insert(k); // Found older value when i != NULL - if( i && i != k ) { // Hit? Return the old guy - NOT_PRODUCT( set_progress(); ) - return i; - } - - // Collect points-to information for escape analysys - ConnectionGraph *cgr = C->congraph(); - if (cgr != NULL) { - cgr->record_escape(k, this); - } - - // Return Idealized original - return k; + return transform_no_reclaim(n); } //------------------------------transform-------------------------------------- @@ -784,6 +714,12 @@ Node *PhaseGVN::transform_no_reclaim( Node *n ) { return i; } + // Collect points-to information for escape analysys + ConnectionGraph *cgr = C->congraph(); + if (cgr != NULL) { + cgr->record_escape(k, this); + } + // Return Idealized original return k; } From b85d2a9e765a46729527990ad434068459821d09 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Sat, 8 Mar 2008 22:49:45 +0800 Subject: [PATCH 094/274] 6634644: broken fragment, should use @link Reviewed-by: mullan --- .../classes/javax/security/cert/X509Certificate.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/javax/security/cert/X509Certificate.java b/jdk/src/share/classes/javax/security/cert/X509Certificate.java index e5849e5c520..14ccaffaffd 100644 --- a/jdk/src/share/classes/javax/security/cert/X509Certificate.java +++ b/jdk/src/share/classes/javax/security/cert/X509Certificate.java @@ -363,7 +363,7 @@ public abstract class X509Certificate extends Certificate { * subject Name * * - *

See getIssuerDN for Name + *

See {@link #getIssuerDN() getIssuerDN} for Name * and other relevant definitions. * * @return a Principal whose name is the subject name. @@ -393,7 +393,7 @@ public abstract class X509Certificate extends Certificate { /** * Gets the notAfter date from the validity period of - * the certificate. See getNotBefore + * the certificate. See {@link #getNotBefore() getNotBefore} * for relevant ASN.1 definitions. * * @return the end date of the validity period. @@ -429,7 +429,7 @@ public abstract class X509Certificate extends Certificate { * For example, the string "1.2.840.10040.4.3" identifies the SHA-1 * with DSA signature algorithm, as per the PKIX part I. * - *

See getSigAlgName for + *

See {@link #getSigAlgName() getSigAlgName} for * relevant ASN.1 definitions. * * @return the signature algorithm OID string. @@ -442,7 +442,7 @@ public abstract class X509Certificate extends Certificate { * algorithm parameters are null; the parameters are usually * supplied with the certificate's public key. * - *

See getSigAlgName for + *

See {@link #getSigAlgName() getSigAlgName} for * relevant ASN.1 definitions. * * @return the DER-encoded signature algorithm parameters, or From e75aa5c3abdc26625cfb45cb4bab48f34cc9c9df Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Sat, 8 Mar 2008 22:51:14 +0800 Subject: [PATCH 095/274] 6643094: Test on keytool -startdate forgets about December Reviewed-by: xuelei --- jdk/test/sun/security/tools/keytool/StartDateTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/test/sun/security/tools/keytool/StartDateTest.java b/jdk/test/sun/security/tools/keytool/StartDateTest.java index 4c47ad724b8..7e3e5bad103 100644 --- a/jdk/test/sun/security/tools/keytool/StartDateTest.java +++ b/jdk/test/sun/security/tools/keytool/StartDateTest.java @@ -52,15 +52,15 @@ public class StartDateTest { cal.setTime(getIssueDate()); System.out.println(cal); if (cal.get(Calendar.YEAR) != year + 1) { - throw new Exception("Function #1 check fails"); + throw new Exception("Function check #1 fails"); } run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " + "-selfcert -startdate +1m"); cal.setTime(getIssueDate()); System.out.println(cal); - if (cal.get(Calendar.MONTH) != month + 1) { - throw new Exception("Function #1 check fails"); + if (cal.get(Calendar.MONTH) != (month + 1) % 12) { + throw new Exception("Function check #2 fails"); } new File("jks").delete(); From 095647f3a47ffd6f83493645ee96d9fb8ed76488 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Sat, 8 Mar 2008 22:52:20 +0800 Subject: [PATCH 096/274] 6597349: KeyStore.getCertificateChain() may not return the full chain Reviewed-by: mullan --- jdk/src/share/classes/java/security/KeyStore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/security/KeyStore.java b/jdk/src/share/classes/java/security/KeyStore.java index f19a231bfbd..ced20e27446 100644 --- a/jdk/src/share/classes/java/security/KeyStore.java +++ b/jdk/src/share/classes/java/security/KeyStore.java @@ -789,7 +789,7 @@ public class KeyStore { * @param alias the alias name * * @return the certificate chain (ordered with the user's certificate first - * and the root certificate authority last), or null if the given alias + * followed by zero or more certificate authorities), or null if the given alias * does not exist or does not contain a certificate chain * * @exception KeyStoreException if the keystore has not been initialized From 6b9d629f069faeb157e3594dd0754cca466a6a98 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Sun, 9 Mar 2008 13:11:51 -0700 Subject: [PATCH 097/274] 6649270: Change by-default openjdk building in control/make/makefile to use open source tree Change build rules to allow for openjdk builds by default when building the closed or production build. Reviewed-by: xdono --- Makefile | 115 ++++++++++++++++++++++++++++------------- make/Defs-internal.gmk | 2 - 2 files changed, 80 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index 5e06900266b..3ced65f0e31 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,17 @@ ifndef CONTROL_TOPDIR fi) endif +# Openjdk sources (only used if SKIP_OPENJDK_BUILD!=true) +OPENJDK_SOURCETREE=$(TOPDIR)/openjdk +OPENJDK_BUILDDIR:=$(shell \ + if [ -r $(OPENJDK_SOURCETREE)/control/make/Makefile ]; then \ + echo "$(OPENJDK_SOURCETREE)/control/make"; \ + elif [ -r $(OPENJDK_SOURCETREE)/Makefile ]; then \ + echo "$(OPENJDK_SOURCETREE)"; \ + else \ + echo "."; \ + fi) + ifndef JDK_TOPDIR JDK_TOPDIR=$(TOPDIR)/jdk endif @@ -81,12 +92,28 @@ include ./make/deploy-rules.gmk all:: setup build -setup: +setup: openjdk_check $(MKDIR) -p $(OUTPUTDIR)/j2sdk-image $(MKDIR) -p $(ABS_OUTPUTDIR)/j2sdk-image $(MKDIR) -p $(OUTPUTDIR)-fastdebug/j2sdk-image $(MKDIR) -p $(ABS_OUTPUTDIR)-fastdebug/j2sdk-image +# Check on whether we really can build the openjdk, need source etc. +openjdk_check: +ifneq ($(SKIP_OPENJDK_BUILD), true) + @$(ECHO) " " + @$(ECHO) "=================================================" + @if [ ! -r $(OPENJDK_BUILDDIR)/Makefile ] ; then \ + $(ECHO) "ERROR: No openjdk source tree available at: $(OPENJDK_BUILDDIR)"; \ + exit 1; \ + else \ + $(ECHO) "OpenJDK will be built after JDK is built"; \ + $(ECHO) " OPENJDK_BUILDDIR=$(OPENJDK_BUILDDIR)"; \ + fi + @$(ECHO) "=================================================" + @$(ECHO) " " +endif + build:: sanity clobber:: @@ -190,46 +217,64 @@ ifneq ($(SKIP_COMPARE_IMAGES), true) all :: compare-image endif -ifeq ($(SKIP_OPENJDK_BUILD), false) +ifneq ($(SKIP_OPENJDK_BUILD), true) + all :: openjdk_build +endif + +# If we have bundle rules, we have a chance here to do a complete cycle +# build, of production and open build. +# FIXUP: We should create the openjdk source bundle and build that? +# But how do we reliable create or get at a formal openjdk source tree? +# The one we have needs to be trimmed of built bits and closed dirs. +# The repositories might not be available. +# The openjdk source bundle is probably not available. + +ifneq ($(SKIP_OPENJDK_BUILD), true) ifeq ($(BUILD_JDK), true) ifeq ($(BUNDLE_RULES_AVAILABLE), true) - # If we have bundle rules, we have a chance here to do a complete cycle - # build, of closed and open build. - # FIXUP: We should create the openjdk source bundle and build that? - ABS_OPENJDK_PLUGS=$(ABS_OUTPUTDIR)/$(OPENJDK_BINARY_PLUGS_INAME) - ABS_OPENJDK_OUTPUTDIR=$(ABS_OUTPUTDIR)/openjdk - OPENJDK_BUILD_NAME_PREFIX \ - = $(J2SDK_NAME)-$(JDK_MKTG_UNDERSCORE_VERSION)-$(MILESTONE) - OPENJDK_BUILD_NAME_SUFFIX \ - = $(BUILD_NUMBER)-$(PLATFORM)-$(ARCH)-$(BUNDLE_DATE) - OPENJDK_BUILD_NAME \ - = $(OPENJDK_BUILD_NAME_PREFIX)-openjdk-$(OPENJDK_BUILD_NAME_SUFFIX) - OPENJDK_BUILD_BINARY_ZIP \ - = $(ABS_BIN_BUNDLEDIR)/$(OPENJDK_BUILD_NAME).zip - all :: openjdk-build - openjdk-build: + +OPENJDK_PLUGS=$(ABS_OUTPUTDIR)/$(OPENJDK_BINARY_PLUGS_INAME) +OPENJDK_OUTPUTDIR=$(ABS_OUTPUTDIR)/open-output +OPENJDK_BUILD_NAME \ + = openjdk-$(JDK_MINOR_VERSION)-$(BUILD_NUMBER)-$(PLATFORM)-$(ARCH)-$(BUNDLE_DATE) +OPENJDK_BUILD_BINARY_ZIP=$(ABS_BIN_BUNDLEDIR)/$(OPENJDK_BUILD_NAME).zip +BUILT_IMAGE=$(ABS_OUTPUTDIR)/j2sdk-image +ifeq ($(PLATFORM)$(ARCH_DATA_MODEL),solaris64) + OPENJDK_BOOTDIR=$(BOOTDIR) + OPENJDK_IMPORTJDK=$(JDK_IMPORT_PATH) +else + OPENJDK_BOOTDIR=$(BUILT_IMAGE) + OPENJDK_IMPORTJDK=$(BUILT_IMAGE) +endif + +openjdk_build: @$(ECHO) " " @$(ECHO) "=================================================" @$(ECHO) "Starting openjdk build" + @$(ECHO) " Using: ALT_JDK_DEVTOOLS_DIR=$(JDK_DEVTOOLS_DIR)" @$(ECHO) "=================================================" @$(ECHO) " " - $(RM) -r $(ABS_OPENJDK_OUTPUTDIR) - $(MKDIR) -p $(ABS_OPENJDK_OUTPUTDIR) - $(MAKE) OPENJDK=true \ - BUILD_LANGTOOLS=$(BUILD_LANGTOOLS) \ - BUILD_CORBA=$(BUILD_CORBA) \ - BUILD_JAXP=$(BUILD_JAXP) \ - BUILD_JAXWS=$(BUILD_JAXWS) \ - BUILD_HOTSPOT=$(BUILD_HOTSPOT) \ - ALT_OUTPUTDIR=$(ABS_OPENJDK_OUTPUTDIR) \ - ALT_BINARY_PLUGS_PATH=$(ABS_OUTPUTDIR)/$(OPENJDK_BINARY_PLUGS_INAME) \ - ALT_BOOTDIR=$(ABS_OUTPUTDIR)/j2sdk-image \ - ALT_JDK_IMPORT_PATH=$(ABS_OUTPUTDIR)/j2sdk-image \ - product_build + $(RM) -r $(OPENJDK_OUTPUTDIR) + $(MKDIR) -p $(OPENJDK_OUTPUTDIR) + ($(CD) $(OPENJDK_BUILDDIR) && $(MAKE) \ + OPENJDK=true \ + ALT_JDK_DEVTOOLS_DIR=$(JDK_DEVTOOLS_DIR) \ + ALT_OUTPUTDIR=$(OPENJDK_OUTPUTDIR) \ + ALT_BINARY_PLUGS_PATH=$(OPENJDK_PLUGS) \ + ALT_BOOTDIR=$(OPENJDK_BOOTDIR) \ + ALT_JDK_IMPORT_PATH=$(OPENJDK_IMPORTJDK) \ + product_build ) $(RM) $(OPENJDK_BUILD_BINARY_ZIP) - ( $(CD) $(ABS_OPENJDK_OUTPUTDIR)/j2sdk-image && \ + ( $(CD) $(OPENJDK_OUTPUTDIR)/j2sdk-image && \ $(ZIPEXE) -q -r $(OPENJDK_BUILD_BINARY_ZIP) .) - $(RM) -r $(ABS_OPENJDK_OUTPUTDIR) + $(RM) -r $(OPENJDK_OUTPUTDIR) + @$(ECHO) " " + @$(ECHO) "=================================================" + @$(ECHO) "Finished openjdk build" + @$(ECHO) " Binary Bundle: $(OPENJDK_BUILD_BINARY_ZIP)" + @$(ECHO) "=================================================" + @$(ECHO) " " + endif endif endif @@ -432,11 +477,11 @@ endif # Cycle build. Build the jdk, use it to build the jdk again. ################################################################ -ABS_BOOTJDK_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk +ABS_BOOTDIR_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk boot_cycle: - $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTJDK_OUTPUTDIR) product_build - $(MAKE) ALT_BOOTDIR=$(ABS_BOOTJDK_OUTPUTDIR)/j2sdk-image product_build + $(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) product_build + $(MAKE) ALT_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/j2sdk-image product_build ################################################################ # JPRT rule to build diff --git a/make/Defs-internal.gmk b/make/Defs-internal.gmk index 6d4c81ca6ff..7343049c61b 100644 --- a/make/Defs-internal.gmk +++ b/make/Defs-internal.gmk @@ -151,8 +151,6 @@ ifdef OPENJDK else ifndef SKIP_OPENJDK_BUILD SKIP_OPENJDK_BUILD = false - # FIXUP: until freetype fixed on linux and solaris rmi build fixed - SKIP_OPENJDK_BUILD = true endif endif From fbfab433d554d7b9e20e4204b7a2c0cae6caf010 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Sun, 9 Mar 2008 14:16:49 -0700 Subject: [PATCH 098/274] 6672777: Broken deploy build from jdk fix 6668781 for cygwin windows Deploy workspace does not set BUILDDIR, uses it, assumes it is jdk/make. Reviewed-by: xdono --- jdk/make/common/Defs.gmk | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 6048744384e..92da33487ce 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -41,7 +41,15 @@ SUN_MAKE_TEST:sh = echo "ERROR: PLEASE USE GNU VERSION OF MAKE"; exit 33 ifndef JDK_TOPDIR - JDK_TOPDIR=$(BUILDDIR)/.. + ifdef BUILDDIR + JDK_TOPDIR=$(BUILDDIR)/.. + else + JDK_TOPDIR:=$(error "ERROR: Cannot define top of jdk repository") + endif +endif +ifndef BUILDDIR + # Hack, due to deploy repository using this file. + BUILDDIR=$(JDK_TOPDIR)/make endif ifndef JDK_MAKE_SHARED_DIR JDK_MAKE_SHARED_DIR=$(JDK_TOPDIR)/make/common/shared From 6377bd6f3ab4a4a540f611cfd9149dd5fe2b1ffc Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Sun, 9 Mar 2008 15:47:58 -0700 Subject: [PATCH 099/274] 6649672: Adjustments to OUTPUTDIR default and mkdirs to avoid empty directory clutter Cleanup of OUTPUTDIR handling Reviewed-by: xdono --- Makefile | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 3ced65f0e31..43b36254335 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,8 @@ # have any questions. # +BUILD_PARENT_DIRECTORY=. + ifndef TOPDIR TOPDIR:=$(shell \ if [ -r ./j2se/make/Makefile -o -r ./jdk/make/Makefile ]; then \ @@ -66,6 +68,7 @@ include ./make/Defs-internal.gmk all:: @$(ECHO) $(PLATFORM) $(ARCH) $(RELEASE) build started: `$(DATE) '+%y-%m-%d %H:%M'` + $(MKDIR) -p $(OUTPUTDIR) # Rules for sanity checks include ./make/sanity-rules.gmk @@ -94,12 +97,9 @@ all:: setup build setup: openjdk_check $(MKDIR) -p $(OUTPUTDIR)/j2sdk-image - $(MKDIR) -p $(ABS_OUTPUTDIR)/j2sdk-image - $(MKDIR) -p $(OUTPUTDIR)-fastdebug/j2sdk-image - $(MKDIR) -p $(ABS_OUTPUTDIR)-fastdebug/j2sdk-image # Check on whether we really can build the openjdk, need source etc. -openjdk_check: +openjdk_check: FRC ifneq ($(SKIP_OPENJDK_BUILD), true) @$(ECHO) " " @$(ECHO) "=================================================" @@ -170,7 +170,7 @@ endif COMMON_DEBUG_FLAGS= \ DEBUG_NAME=$(DEBUG_NAME) \ - ALT_OUTPUTDIR=$(_OUTPUTDIR)-$(DEBUG_NAME) \ + ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)-$(DEBUG_NAME) \ NO_DOCS=true product_build: setup @@ -501,3 +501,6 @@ include ./make/jprt.gmk j2se_fastdebug_only: jdk_fastdebug_only j2se_only: jdk_only +# Force target +FRC: + From 13ced2b9352e23eee1cc8650e49b51dd38a084e8 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Sun, 9 Mar 2008 21:56:42 -0700 Subject: [PATCH 100/274] 4499288: (cs spec) Charset terminology problems Reviewed-by: mr, iris --- .../classes/java/nio/charset/Charset.java | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/jdk/src/share/classes/java/nio/charset/Charset.java b/jdk/src/share/classes/java/nio/charset/Charset.java index 13723432712..4c166d519a2 100644 --- a/jdk/src/share/classes/java/nio/charset/Charset.java +++ b/jdk/src/share/classes/java/nio/charset/Charset.java @@ -212,36 +212,47 @@ import sun.security.action.GetPropertyAction; * *

Terminology

* - *

The name of this class is taken from the terms used in RFC 2278. In that - * document a charset is defined as the combination of a coded character - * set and a character-encoding scheme. + *

The name of this class is taken from the terms used in + * RFC 2278. + * In that document a charset is defined as the combination of + * one or more coded character sets and a character-encoding scheme. + * (This definition is confusing; some other software systems define + * charset as a synonym for coded character set.) * *

A coded character set is a mapping between a set of abstract * characters and a set of integers. US-ASCII, ISO 8859-1, - * JIS X 0201, and full Unicode, which is the same as - * ISO 10646-1, are examples of coded character sets. + * JIS X 0201, and Unicode are examples of coded character sets. * - *

A character-encoding scheme is a mapping between a coded - * character set and a set of octet (eight-bit byte) sequences. UTF-8, UCS-2, - * UTF-16, ISO 2022, and EUC are examples of character-encoding schemes. - * Encoding schemes are often associated with a particular coded character set; - * UTF-8, for example, is used only to encode Unicode. Some schemes, however, - * are associated with multiple character sets; EUC, for example, can be used - * to encode characters in a variety of Asian character sets. + *

Some standards have defined a character set to be simply a + * set of abstract characters without an associated assigned numbering. + * An alphabet is an example of such a character set. However, the subtle + * distinction between character set and coded character set + * is rarely used in practice; the former has become a short form for the + * latter, including in the Java API specification. + * + *

A character-encoding scheme is a mapping between one or more + * coded character sets and a set of octet (eight-bit byte) sequences. + * UTF-8, UTF-16, ISO 2022, and EUC are examples of + * character-encoding schemes. Encoding schemes are often associated with + * a particular coded character set; UTF-8, for example, is used only to + * encode Unicode. Some schemes, however, are associated with multiple + * coded character sets; EUC, for example, can be used to encode + * characters in a variety of Asian coded character sets. * *

When a coded character set is used exclusively with a single - * character-encoding scheme then the corresponding charset is usually named - * for the character set; otherwise a charset is usually named for the encoding - * scheme and, possibly, the locale of the character sets that it supports. - * Hence US-ASCII is the name of the charset for US-ASCII while + * character-encoding scheme then the corresponding charset is usually + * named for the coded character set; otherwise a charset is usually named + * for the encoding scheme and, possibly, the locale of the coded + * character sets that it supports. Hence US-ASCII is both the + * name of a coded character set and of the charset that encodes it, while * EUC-JP is the name of the charset that encodes the * JIS X 0201, JIS X 0208, and JIS X 0212 - * character sets. + * coded character sets for the Japanese language. * *

The native character encoding of the Java programming language is - * UTF-16. A charset in the Java platform therefore defines a mapping between - * sequences of sixteen-bit UTF-16 code units and sequences of bytes.

+ * UTF-16. A charset in the Java platform therefore defines a mapping + * between sequences of sixteen-bit UTF-16 code units (that is, sequences + * of chars) and sequences of bytes.

* * * @author Mark Reinhold From 14120d1c34e84e53b83b212683a6de6ac8f66bb4 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Sun, 9 Mar 2008 21:56:42 -0700 Subject: [PATCH 101/274] 6671834: (str) Eliminate StringCoding.java compile warnings Reviewed-by: iris --- .../share/classes/java/lang/StringCoding.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/java/lang/StringCoding.java b/jdk/src/share/classes/java/lang/StringCoding.java index 7eb302130d1..d3a23a8816d 100644 --- a/jdk/src/share/classes/java/lang/StringCoding.java +++ b/jdk/src/share/classes/java/lang/StringCoding.java @@ -53,22 +53,23 @@ class StringCoding { private StringCoding() { } - /* The cached coders for each thread - */ - private static ThreadLocal decoder = new ThreadLocal(); - private static ThreadLocal encoder = new ThreadLocal(); + /** The cached coders for each thread */ + private final static ThreadLocal> decoder = + new ThreadLocal>(); + private final static ThreadLocal> encoder = + new ThreadLocal>(); private static boolean warnUnsupportedCharset = true; - private static Object deref(ThreadLocal tl) { - SoftReference sr = (SoftReference)tl.get(); + private static T deref(ThreadLocal> tl) { + SoftReference sr = tl.get(); if (sr == null) return null; return sr.get(); } - private static void set(ThreadLocal tl, Object ob) { - tl.set(new SoftReference(ob)); + private static void set(ThreadLocal> tl, T ob) { + tl.set(new SoftReference(ob)); } // Trim the given byte array to the given length @@ -174,7 +175,7 @@ class StringCoding { static char[] decode(String charsetName, byte[] ba, int off, int len) throws UnsupportedEncodingException { - StringDecoder sd = (StringDecoder)deref(decoder); + StringDecoder sd = deref(decoder); String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; if ((sd == null) || !(csn.equals(sd.requestedCharsetName()) || csn.equals(sd.charsetName()))) { @@ -273,7 +274,7 @@ class StringCoding { static byte[] encode(String charsetName, char[] ca, int off, int len) throws UnsupportedEncodingException { - StringEncoder se = (StringEncoder)deref(encoder); + StringEncoder se = deref(encoder); String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; if ((se == null) || !(csn.equals(se.requestedCharsetName()) || csn.equals(se.charsetName()))) { From f7ce4bc4ab4e069fa2f4a60f9c24ff576bf03bd5 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Sun, 9 Mar 2008 21:56:42 -0700 Subject: [PATCH 102/274] 6633613: (str) StringCoding optimizations to avoid unnecessary array copies with Charset arg Reviewed-by: iris --- jdk/src/share/classes/java/lang/StringCoding.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/lang/StringCoding.java b/jdk/src/share/classes/java/lang/StringCoding.java index d3a23a8816d..f9d8ef3e66b 100644 --- a/jdk/src/share/classes/java/lang/StringCoding.java +++ b/jdk/src/share/classes/java/lang/StringCoding.java @@ -194,8 +194,7 @@ class StringCoding { static char[] decode(Charset cs, byte[] ba, int off, int len) { StringDecoder sd = new StringDecoder(cs, cs.name()); - byte[] b = Arrays.copyOf(ba, ba.length); - return sd.decode(b, off, len); + return sd.decode(Arrays.copyOfRange(ba, off, off + len), 0, len); } static char[] decode(byte[] ba, int off, int len) { @@ -293,8 +292,7 @@ class StringCoding { static byte[] encode(Charset cs, char[] ca, int off, int len) { StringEncoder se = new StringEncoder(cs, cs.name()); - char[] c = Arrays.copyOf(ca, ca.length); - return se.encode(c, off, len); + return se.encode(Arrays.copyOfRange(ca, off, off + len), 0, len); } static byte[] encode(char[] ca, int off, int len) { From 4d5b9980281cfae3dac5f913593cffb30c2cfed9 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:50 -0700 Subject: [PATCH 103/274] 6631966: (process) Raise Windows pipe buffer size an extra 24 bytes (win) Reviewed-by: alanb, iris --- jdk/src/windows/native/java/lang/ProcessImpl_md.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c index fd9da8e4168..71113a7d5b4 100644 --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c @@ -33,7 +33,12 @@ #include #include -#define PIPE_SIZE 4096 +/* We try to make sure that we can read and write 4095 bytes (the + * fixed limit on Linux) to the pipe on all operating systems without + * deadlock. Windows 2000 inexplicably appears to need an extra 24 + * bytes of slop to avoid deadlock. + */ +#define PIPE_SIZE (4096+24) char * extractExecutablePath(JNIEnv *env, char *source) From a686efe6ac9be1d68648950ff48515f522df9b31 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:51 -0700 Subject: [PATCH 104/274] 6632696: Writing to closed output files (writeBytes) leaks native memory (unix) Reviewed-by: alanb, iris --- jdk/src/share/native/java/io/io_util.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/native/java/io/io_util.c b/jdk/src/share/native/java/io/io_util.c index 4f7372babb9..f8fc714bbdc 100644 --- a/jdk/src/share/native/java/io/io_util.c +++ b/jdk/src/share/native/java/io/io_util.c @@ -40,7 +40,7 @@ readSingle(JNIEnv *env, jobject this, jfieldID fid) { char ret; FD fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); + JNU_ThrowIOException(env, "Stream Closed"); return -1; } nread = IO_Read(fd, &ret, 1); @@ -94,7 +94,7 @@ readBytes(JNIEnv *env, jobject this, jbyteArray bytes, fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); + JNU_ThrowIOException(env, "Stream Closed"); return -1; } @@ -121,7 +121,7 @@ writeSingle(JNIEnv *env, jobject this, jint byte, jfieldID fid) { int n; FD fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); + JNU_ThrowIOException(env, "Stream Closed"); return; } n = IO_Write(fd, &c, 1); @@ -172,8 +172,8 @@ writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, while (len > 0) { fd = GET_FD(this, fid); if (fd == -1) { - JNU_ThrowIOException (env, "Stream Closed"); - return; + JNU_ThrowIOException(env, "Stream Closed"); + break; } n = IO_Write(fd, buf+off, len); if (n == JVM_IO_ERR) { From 2c1daccc0a45183696a90bdb80094daf6f296b6f Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:51 -0700 Subject: [PATCH 105/274] 6631362: Nuke io_util_md.c:handleFileSizeFD (win) Reviewed-by: alanb, iris --- jdk/src/windows/native/java/io/io_util_md.c | 18 ------------------ jdk/src/windows/native/java/io/io_util_md.h | 1 - 2 files changed, 19 deletions(-) diff --git a/jdk/src/windows/native/java/io/io_util_md.c b/jdk/src/windows/native/java/io/io_util_md.c index a18894ca885..342e8cdc017 100644 --- a/jdk/src/windows/native/java/io/io_util_md.c +++ b/jdk/src/windows/native/java/io/io_util_md.c @@ -444,24 +444,6 @@ handleSetLength(jlong fd, jlong length) { return 0; } -int -handleFileSizeFD(jlong fd, jlong *size) -{ - DWORD sizeLow = 0; - DWORD sizeHigh = 0; - HANDLE h = (HANDLE)fd; - if (h == INVALID_HANDLE_VALUE) { - return -1; - } - sizeLow = GetFileSize(h, &sizeHigh); - if (sizeLow == ((DWORD)-1)) { - if (GetLastError() != ERROR_SUCCESS) { - return -1; - } - } - return (((jlong)sizeHigh) << 32) | sizeLow; -} - JNIEXPORT size_t handleRead(jlong fd, void *buf, jint len) diff --git a/jdk/src/windows/native/java/io/io_util_md.h b/jdk/src/windows/native/java/io/io_util_md.h index fdbd5bf22e2..bf9047d7c65 100644 --- a/jdk/src/windows/native/java/io/io_util_md.h +++ b/jdk/src/windows/native/java/io/io_util_md.h @@ -38,7 +38,6 @@ void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags); int handleAvailable(jlong fd, jlong *pbytes); JNIEXPORT int handleSync(jlong fd); int handleSetLength(jlong fd, jlong length); -int handleFileSizeFD(jlong fd, jlong *size); JNIEXPORT size_t handleRead(jlong fd, void *buf, jint len); JNIEXPORT size_t handleWrite(jlong fd, const void *buf, jint len); jint handleClose(JNIEnv *env, jobject this, jfieldID fid); From 8d412f036d7fa56e18c2d771f012d3e4959255d8 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:51 -0700 Subject: [PATCH 106/274] 6631437: File{In,Out}putStream minor improvements to spec and stylistic improvements to code Reviewed-by: alanb, iris --- .../classes/java/io/FileInputStream.java | 12 +++++----- .../classes/java/io/FileOutputStream.java | 24 +++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/jdk/src/share/classes/java/io/FileInputStream.java b/jdk/src/share/classes/java/io/FileInputStream.java index 8575e6d9397..a37c69c6239 100644 --- a/jdk/src/share/classes/java/io/FileInputStream.java +++ b/jdk/src/share/classes/java/io/FileInputStream.java @@ -48,15 +48,15 @@ public class FileInputStream extends InputStream { /* File Descriptor - handle to the open file */ - private FileDescriptor fd; + private final FileDescriptor fd; private FileChannel channel = null; - private Object closeLock = new Object(); + private final Object closeLock = new Object(); private volatile boolean closed = false; - private static ThreadLocal runningFinalize = - new ThreadLocal(); + private static final ThreadLocal runningFinalize = + new ThreadLocal(); private static boolean isRunningFinalize() { Boolean val; @@ -151,7 +151,7 @@ class FileInputStream extends InputStream * is thrown. *

* This constructor does not throw an exception if fdObj - * is {link java.io.FileDescriptor#valid() invalid}. + * is {@link java.io.FileDescriptor#valid() invalid}. * However, if the methods are invoked on the resulting stream to attempt * I/O on the stream, an IOException is thrown. * @@ -389,7 +389,7 @@ class FileInputStream extends InputStream * @see java.io.FileInputStream#close() */ protected void finalize() throws IOException { - if ((fd != null) && (fd != fd.in)) { + if ((fd != null) && (fd != FileDescriptor.in)) { /* * Finalizer should not release the FileDescriptor if another diff --git a/jdk/src/share/classes/java/io/FileOutputStream.java b/jdk/src/share/classes/java/io/FileOutputStream.java index 695f43150fe..f6b880a503e 100644 --- a/jdk/src/share/classes/java/io/FileOutputStream.java +++ b/jdk/src/share/classes/java/io/FileOutputStream.java @@ -52,20 +52,18 @@ public class FileOutputStream extends OutputStream { /** - * The system dependent file descriptor. The value is - * 1 more than actual file descriptor. This means that - * the default value 0 indicates that the file is not open. + * The system dependent file descriptor. */ - private FileDescriptor fd; + private final FileDescriptor fd; private FileChannel channel= null; private boolean append = false; - private Object closeLock = new Object(); + private final Object closeLock = new Object(); private volatile boolean closed = false; - private static ThreadLocal runningFinalize = - new ThreadLocal(); + private static final ThreadLocal runningFinalize = + new ThreadLocal(); private static boolean isRunningFinalize() { Boolean val; @@ -75,7 +73,7 @@ class FileOutputStream extends OutputStream } /** - * Creates an output file stream to write to the file with the + * Creates a file output stream to write to the file with the * specified name. A new FileDescriptor object is * created to represent this file connection. *

@@ -100,8 +98,8 @@ class FileOutputStream extends OutputStream } /** - * Creates an output file stream to write to the file with the specified - * name. If the second argument is true, then + * Creates a file output stream to write to the file with the specified + * name. If the second argument is true, then * bytes will be written to the end of the file rather than the beginning. * A new FileDescriptor object is created to represent this * file connection. @@ -211,7 +209,7 @@ class FileOutputStream extends OutputStream } /** - * Creates an output file stream to write to the specified file + * Creates a file output stream to write to the specified file * descriptor, which represents an existing connection to an actual * file in the file system. *

@@ -223,7 +221,7 @@ class FileOutputStream extends OutputStream * is thrown. *

* This constructor does not throw an exception if fdObj - * is {link java.io.FileDescriptor#valid() invalid}. + * is {@link java.io.FileDescriptor#valid() invalid}. * However, if the methods are invoked on the resulting stream to attempt * I/O on the stream, an IOException is thrown. * @@ -408,7 +406,7 @@ class FileOutputStream extends OutputStream */ protected void finalize() throws IOException { if (fd != null) { - if (fd == fd.out || fd == fd.err) { + if (fd == FileDescriptor.out || fd == FileDescriptor.err) { flush(); } else { From 504a24907dc225b19cd807040b1db9a24606034c Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:51 -0700 Subject: [PATCH 107/274] 6631352: File{OutputStream,Writer} should implement atomic append mode using FILE_APPEND_DATA (win) Reviewed-by: alanb, iris --- jdk/make/java/java/mapfile-vers | 1 - .../classes/java/io/FileOutputStream.java | 23 ++---- .../classes/sun/nio/ch/FileChannelImpl.java | 49 ++++------- jdk/src/share/native/java/io/io_util.c | 2 +- .../native/java/io/FileOutputStream_md.c | 11 +-- .../native/java/io/FileOutputStream_md.c | 36 +-------- jdk/src/windows/native/java/io/io_util_md.c | 13 ++- .../io/FileOutputStream/AtomicAppend.java | 81 +++++++++++++++++++ 8 files changed, 120 insertions(+), 96 deletions(-) create mode 100644 jdk/test/java/io/FileOutputStream/AtomicAppend.java diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers index 4599570449e..38f9e126d82 100644 --- a/jdk/make/java/java/mapfile-vers +++ b/jdk/make/java/java/mapfile-vers @@ -85,7 +85,6 @@ SUNWprivate_1.1 { Java_java_io_FileOutputStream_close0; Java_java_io_FileOutputStream_initIDs; Java_java_io_FileOutputStream_open; - Java_java_io_FileOutputStream_openAppend; Java_java_io_FileOutputStream_write; Java_java_io_FileOutputStream_writeBytes; Java_java_io_FileSystem_getFileSystem; diff --git a/jdk/src/share/classes/java/io/FileOutputStream.java b/jdk/src/share/classes/java/io/FileOutputStream.java index f6b880a503e..f252237d89f 100644 --- a/jdk/src/share/classes/java/io/FileOutputStream.java +++ b/jdk/src/share/classes/java/io/FileOutputStream.java @@ -58,8 +58,6 @@ class FileOutputStream extends OutputStream private FileChannel channel= null; - private boolean append = false; - private final Object closeLock = new Object(); private volatile boolean closed = false; private static final ThreadLocal runningFinalize = @@ -200,12 +198,7 @@ class FileOutputStream extends OutputStream } fd = new FileDescriptor(); fd.incrementAndGetUseCount(); - this.append = append; - if (append) { - openAppend(name); - } else { - open(name); - } + open(name, append); } /** @@ -250,16 +243,12 @@ class FileOutputStream extends OutputStream } /** - * Opens a file, with the specified name, for writing. + * Opens a file, with the specified name, for overwriting or appending. * @param name name of file to be opened + * @param append whether the file is to be opened in append mode */ - private native void open(String name) throws FileNotFoundException; - - /** - * Opens a file, with the specified name, for appending. - * @param name name of file to be opened - */ - private native void openAppend(String name) throws FileNotFoundException; + private native void open(String name, boolean append) + throws FileNotFoundException; /** * Writes the specified byte to this file output stream. Implements @@ -383,7 +372,7 @@ class FileOutputStream extends OutputStream public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, false, true, this, append); + channel = FileChannelImpl.open(fd, false, true, this); /* * Increment fd's use count. Invoking the channel's close() diff --git a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java index 4aa21dbd18a..aae23b7664b 100644 --- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java +++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java @@ -52,39 +52,37 @@ public class FileChannelImpl { // Used to make native read and write calls - private static NativeDispatcher nd; + private static final NativeDispatcher nd; // Memory allocation size for mapping buffers - private static long allocationGranularity; + private static final long allocationGranularity; // Cached field for MappedByteBuffer.isAMappedBuffer - private static Field isAMappedBufferField; + private static final Field isAMappedBufferField; // File descriptor - private FileDescriptor fd; + private final FileDescriptor fd; // File access mode (immutable) - private boolean writable; - private boolean readable; - private boolean appending; + private final boolean writable; + private final boolean readable; // Required to prevent finalization of creating stream (immutable) - private Object parent; + private final Object parent; // Thread-safe set of IDs of native threads, for signalling - private NativeThreadSet threads = new NativeThreadSet(2); + private final NativeThreadSet threads = new NativeThreadSet(2); // Lock for operations involving position and size - private Object positionLock = new Object(); + private final Object positionLock = new Object(); private FileChannelImpl(FileDescriptor fd, boolean readable, - boolean writable, Object parent, boolean append) + boolean writable, Object parent) { this.fd = fd; this.readable = readable; this.writable = writable; this.parent = parent; - this.appending = append; } // Invoked by getChannel() methods @@ -94,14 +92,7 @@ public class FileChannelImpl boolean readable, boolean writable, Object parent) { - return new FileChannelImpl(fd, readable, writable, parent, false); - } - - public static FileChannel open(FileDescriptor fd, - boolean readable, boolean writable, - Object parent, boolean append) - { - return new FileChannelImpl(fd, readable, writable, parent, append); + return new FileChannelImpl(fd, readable, writable, parent); } private void ensureOpen() throws IOException { @@ -134,15 +125,7 @@ public class FileChannelImpl // superclass AbstractInterruptibleChannel, but the isOpen logic in // that method will prevent this method from being reinvoked. // - if (parent instanceof FileInputStream) - ((FileInputStream)parent).close(); - else if (parent instanceof FileOutputStream) - ((FileOutputStream)parent).close(); - else if (parent instanceof RandomAccessFile) - ((RandomAccessFile)parent).close(); - else - assert false; - + ((java.io.Closeable)parent).close(); } else { nd.close(fd); } @@ -218,8 +201,6 @@ public class FileChannelImpl if (!isOpen()) return 0; ti = threads.add(); - if (appending) - position(size()); do { n = IOUtil.write(fd, src, -1, nd, positionLock); } while ((n == IOStatus.INTERRUPTED) && isOpen()); @@ -244,8 +225,6 @@ public class FileChannelImpl if (!isOpen()) return 0; ti = threads.add(); - if (appending) - position(size()); do { n = IOUtil.write(fd, srcs, nd); } while ((n == IOStatus.INTERRUPTED) && isOpen()); @@ -1051,7 +1030,7 @@ public class FileChannelImpl private FileKey fileKey; FileLockReference(FileLock referent, - ReferenceQueue queue, + ReferenceQueue queue, FileKey key) { super(referent, queue); this.fileKey = key; @@ -1073,7 +1052,7 @@ public class FileChannelImpl new ConcurrentHashMap>(); // reference queue for cleared refs - private static ReferenceQueue queue = new ReferenceQueue(); + private static ReferenceQueue queue = new ReferenceQueue(); // the enclosing file channel private FileChannelImpl fci; diff --git a/jdk/src/share/native/java/io/io_util.c b/jdk/src/share/native/java/io/io_util.c index f8fc714bbdc..f355069cd0a 100644 --- a/jdk/src/share/native/java/io/io_util.c +++ b/jdk/src/share/native/java/io/io_util.c @@ -95,7 +95,7 @@ readBytes(JNIEnv *env, jobject this, jbyteArray bytes, fd = GET_FD(this, fid); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); - return -1; + return -1; } nread = IO_Read(fd, buf, len); diff --git a/jdk/src/solaris/native/java/io/FileOutputStream_md.c b/jdk/src/solaris/native/java/io/FileOutputStream_md.c index 3bee404589c..4fc5904660b 100644 --- a/jdk/src/solaris/native/java/io/FileOutputStream_md.c +++ b/jdk/src/solaris/native/java/io/FileOutputStream_md.c @@ -53,13 +53,10 @@ Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fdClass) { */ JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_TRUNC); -} - -JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_openAppend(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_APPEND); +Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, + jstring path, jboolean append) { + fileOpen(env, this, path, fos_fd, + O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC)); } JNIEXPORT void JNICALL diff --git a/jdk/src/windows/native/java/io/FileOutputStream_md.c b/jdk/src/windows/native/java/io/FileOutputStream_md.c index b5c29abe3e5..97862c5d2d8 100644 --- a/jdk/src/windows/native/java/io/FileOutputStream_md.c +++ b/jdk/src/windows/native/java/io/FileOutputStream_md.c @@ -39,8 +39,6 @@ jfieldID fos_fd; /* id for jobject 'fd' in java.io.FileOutputStream */ -jfieldID fos_append; - /************************************************************** * static methods to store field ID's in initializers */ @@ -49,7 +47,6 @@ JNIEXPORT void JNICALL Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fosClass) { fos_fd = (*env)->GetFieldID(env, fosClass, "fd", "Ljava/io/FileDescriptor;"); - fos_append = (*env)->GetFieldID(env, fosClass, "append", "Z"); } /************************************************************** @@ -57,45 +54,20 @@ Java_java_io_FileOutputStream_initIDs(JNIEnv *env, jclass fosClass) { */ JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_TRUNC); -} - -JNIEXPORT void JNICALL -Java_java_io_FileOutputStream_openAppend(JNIEnv *env, jobject this, jstring path) { - fileOpen(env, this, path, fos_fd, O_WRONLY | O_CREAT | O_APPEND); +Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this, + jstring path, jboolean append) { + fileOpen(env, this, path, fos_fd, + O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC)); } JNIEXPORT void JNICALL Java_java_io_FileOutputStream_write(JNIEnv *env, jobject this, jint byte) { - jboolean append = (*env)->GetBooleanField(env, this, fos_append); - FD fd = GET_FD(this, fos_fd); - if (fd == -1) { - JNU_ThrowIOException(env, "Stream Closed"); - return; - } - if (append == JNI_TRUE) { - if (IO_Lseek(fd, 0L, SEEK_END) == -1) { - JNU_ThrowIOExceptionWithLastError(env, "Append failed"); - } - } writeSingle(env, this, byte, fos_fd); } JNIEXPORT void JNICALL Java_java_io_FileOutputStream_writeBytes(JNIEnv *env, jobject this, jbyteArray bytes, jint off, jint len) { - jboolean append = (*env)->GetBooleanField(env, this, fos_append); - FD fd = GET_FD(this, fos_fd); - if (fd == -1) { - JNU_ThrowIOException(env, "Stream Closed"); - return; - } - if (append == JNI_TRUE) { - if (IO_Lseek(fd, 0L, SEEK_END) == -1) { - JNU_ThrowIOExceptionWithLastError(env, "Append failed"); - } - } writeBytes(env, this, bytes, off, len, fos_fd); } diff --git a/jdk/src/windows/native/java/io/io_util_md.c b/jdk/src/windows/native/java/io/io_util_md.c index 342e8cdc017..89290c778f7 100644 --- a/jdk/src/windows/native/java/io/io_util_md.c +++ b/jdk/src/windows/native/java/io/io_util_md.c @@ -42,7 +42,7 @@ extern jboolean onNT = JNI_FALSE; -static int MAX_INPUT_EVENTS = 2000; +static DWORD MAX_INPUT_EVENTS = 2000; void initializeWindowsVersion() { @@ -190,9 +190,16 @@ pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) { jlong winFileHandleOpen(JNIEnv *env, jstring path, int flags) { + /* To implement O_APPEND, we use the strategy from + http://msdn2.microsoft.com/en-us/library/aa363858.aspx + "You can get atomic append by opening a file with + FILE_APPEND_DATA access and _without_ FILE_WRITE_DATA access. + If you do this then all writes will ignore the current file + pointer and be done at the end-of file." */ const DWORD access = - (flags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) : + (flags & O_APPEND) ? (FILE_GENERIC_WRITE & ~FILE_WRITE_DATA) : (flags & O_WRONLY) ? GENERIC_WRITE : + (flags & O_RDWR) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_READ; const DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE; @@ -495,7 +502,7 @@ handleClose(JNIEnv *env, jobject this, jfieldID fid) FD fd = GET_FD(this, fid); HANDLE h = (HANDLE)fd; - if (fd == INVALID_HANDLE_VALUE) { + if (h == INVALID_HANDLE_VALUE) { return 0; } diff --git a/jdk/test/java/io/FileOutputStream/AtomicAppend.java b/jdk/test/java/io/FileOutputStream/AtomicAppend.java new file mode 100644 index 00000000000..f5f0c23606c --- /dev/null +++ b/jdk/test/java/io/FileOutputStream/AtomicAppend.java @@ -0,0 +1,81 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 6631352 + * @summary Check that appends are atomic + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; + +public class AtomicAppend { + // Before the fix for + // 6631352: Implement atomic append mode using FILE_APPEND_DATA (win) + // this would fail intermittently on windows + void test(String[] args) throws Throwable { + final int nThreads = 10; + final int writes = 1000; + final File file = new File("foo"); + file.delete(); + try { + final ExecutorService es = Executors.newFixedThreadPool(nThreads); + for (int i = 0; i < nThreads; i++) + es.execute(new Runnable() { public void run() { + try { + FileOutputStream s = new FileOutputStream(file, true); + for (int j = 0; j < 1000; j++) { + s.write((int) 'x'); + s.flush(); + } + s.close(); + } catch (Throwable t) { unexpected(t); }}}); + es.shutdown(); + es.awaitTermination(10L, TimeUnit.MINUTES); + equal(file.length(), (long) (nThreads * writes)); + } finally { + file.delete(); + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new AtomicAppend().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} From abde1241e187c17a5b9dc344156315469e87b161 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:51 -0700 Subject: [PATCH 108/274] 4960438: (process) Need IO redirection API for subprocesses Reviewed-by: alanb, iris --- jdk/src/share/classes/java/lang/Process.java | 71 +- .../classes/java/lang/ProcessBuilder.java | 726 +++++++++++++++--- .../sun/misc/JavaIOFileDescriptorAccess.java | 4 + .../classes/java/io/FileDescriptor.java | 10 +- .../classes/java/lang/ProcessImpl.java | 59 +- .../classes/java/lang/UNIXProcess.java.linux | 184 +++-- .../java/lang/UNIXProcess.java.solaris | 364 +++++---- .../solaris/native/java/lang/UNIXProcess_md.c | 51 +- .../classes/java/io/FileDescriptor.java | 33 +- .../classes/java/lang/ProcessImpl.java | 150 +++- .../windows/native/java/lang/ProcessImpl_md.c | 97 ++- jdk/test/java/lang/ProcessBuilder/Basic.java | 379 ++++++++- 12 files changed, 1666 insertions(+), 462 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Process.java b/jdk/src/share/classes/java/lang/Process.java index fe4045ab25f..88010fd555d 100644 --- a/jdk/src/share/classes/java/lang/Process.java +++ b/jdk/src/share/classes/java/lang/Process.java @@ -41,18 +41,24 @@ import java.io.*; *

The methods that create processes may not work well for special * processes on certain native platforms, such as native windowing * processes, daemon processes, Win16/DOS processes on Microsoft - * Windows, or shell scripts. The created subprocess does not have - * its own terminal or console. All its standard I/O (i.e. stdin, - * stdout, stderr) operations will be redirected to the parent process - * through three streams - * ({@link #getOutputStream()}, - * {@link #getInputStream()}, - * {@link #getErrorStream()}). + * Windows, or shell scripts. + * + *

By default, the created subprocess does not have its own terminal + * or console. All its standard I/O (i.e. stdin, stdout, stderr) + * operations will be redirected to the parent process, where they can + * be accessed via the streams obtained using the methods + * {@link #getOutputStream()}, + * {@link #getInputStream()}, and + * {@link #getErrorStream()}. * The parent process uses these streams to feed input to and get output * from the subprocess. Because some native platforms only provide * limited buffer size for standard input and output streams, failure * to promptly write the input stream or read the output stream of - * the subprocess may cause the subprocess to block, and even deadlock. + * the subprocess may cause the subprocess to block, or even deadlock. + * + *

Where desired, + * subprocess I/O can also be redirected + * using methods of the {@link ProcessBuilder} class. * *

The subprocess is not killed when there are no more references to * the {@code Process} object, but rather the subprocess @@ -62,16 +68,22 @@ import java.io.*; * Process} object execute asynchronously or concurrently with respect * to the Java process that owns the {@code Process} object. * - * @author unascribed - * @see ProcessBuilder + *

As of 1.5, {@link ProcessBuilder#start()} is the preferred way + * to create a {@code Process}. + * * @since JDK1.0 */ public abstract class Process { /** * Returns the output stream connected to the normal input of the * subprocess. Output to the stream is piped into the standard - * input stream of the process represented by this {@code Process} - * object. + * input of the process represented by this {@code Process} object. + * + *

If the standard input of the subprocess has been redirected using + * {@link ProcessBuilder#redirectInput(Redirect) + * ProcessBuilder.redirectInput} + * then this method will return a + * null output stream. * *

Implementation note: It is a good idea for the returned * output stream to be buffered. @@ -84,30 +96,47 @@ public abstract class Process { /** * Returns the input stream connected to the normal output of the * subprocess. The stream obtains data piped from the standard - * output stream of the process represented by this {@code - * Process} object. + * output of the process represented by this {@code Process} object. + * + *

If the standard output of the subprocess has been redirected using + * {@link ProcessBuilder#redirectOutput(Redirect) + * ProcessBuilder.redirectOutput} + * then this method will return a + * null input stream. + * + *

Otherwise, if the standard error of the subprocess has been + * redirected using + * {@link ProcessBuilder#redirectErrorStream(boolean) + * ProcessBuilder.redirectErrorStream} + * then the input stream returned by this method will receive the + * merged standard output and the standard error of the subprocess. * *

Implementation note: It is a good idea for the returned * input stream to be buffered. * * @return the input stream connected to the normal output of the * subprocess - * @see ProcessBuilder#redirectErrorStream() */ abstract public InputStream getInputStream(); /** - * Returns the input stream connected to the error output stream of - * the subprocess. The stream obtains data piped from the error - * output stream of the process represented by this {@code Process} - * object. + * Returns the input stream connected to the error output of the + * subprocess. The stream obtains data piped from the error output + * of the process represented by this {@code Process} object. + * + *

If the standard error of the subprocess has been redirected using + * {@link ProcessBuilder#redirectError(Redirect) + * ProcessBuilder.redirectError} or + * {@link ProcessBuilder#redirectErrorStream(boolean) + * ProcessBuilder.redirectErrorStream} + * then this method will return a + * null input stream. * *

Implementation note: It is a good idea for the returned * input stream to be buffered. * - * @return the input stream connected to the error output stream of + * @return the input stream connected to the error output of * the subprocess - * @see ProcessBuilder#redirectErrorStream() */ abstract public InputStream getErrorStream(); diff --git a/jdk/src/share/classes/java/lang/ProcessBuilder.java b/jdk/src/share/classes/java/lang/ProcessBuilder.java index 32895a5baab..be24e8d8235 100644 --- a/jdk/src/share/classes/java/lang/ProcessBuilder.java +++ b/jdk/src/share/classes/java/lang/ProcessBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -27,6 +27,10 @@ package java.lang; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -34,7 +38,7 @@ import java.util.Map; /** * This class is used to create operating system processes. * - *

Each ProcessBuilder instance manages a collection + *

Each {@code ProcessBuilder} instance manages a collection * of process attributes. The {@link #start()} method creates a new * {@link Process} instance with those attributes. The {@link * #start()} method can be invoked repeatedly from the same instance @@ -59,19 +63,64 @@ import java.util.Map; * *

  • a working directory. The default value is the current * working directory of the current process, usually the directory - * named by the system property user.dir. + * named by the system property {@code user.dir}. + * + *
  • a source of standard input. + * By default, the subprocess reads input from a pipe. Java code + * can access this pipe via the output stream returned by + * {@link Process#getOutputStream()}. However, standard input may + * be redirected to another source using + * {@link #redirectInput(Redirect) redirectInput}. + * In this case, {@link Process#getOutputStream()} will return a + * null output stream, for which: + * + *
      + *
    • the {@link OutputStream#write(int) write} methods always + * throw {@code IOException} + *
    • the {@link OutputStream#close() close} method does nothing + *
    + * + *
  • a destination for standard output + * and standard error. By default, the subprocess writes standard + * output and standard error to pipes. Java code can access these pipes + * via the input streams returned by {@link Process#getInputStream()} and + * {@link Process#getErrorStream()}. However, standard output and + * standard error may be redirected to other destinations using + * {@link #redirectOutput(Redirect) redirectOutput} and + * {@link #redirectError(Redirect) redirectError}. + * In this case, {@link Process#getInputStream()} and/or + * {@link Process#getErrorStream()} will return a null input + * stream, for which: + * + *
      + *
    • the {@link InputStream#read() read} methods always return + * {@code -1} + *
    • the {@link InputStream#available() available} method always returns + * {@code 0} + *
    • the {@link InputStream#close() close} method does nothing + *
    * *
  • a redirectErrorStream property. Initially, this property - * is false, meaning that the standard output and error + * is {@code false}, meaning that the standard output and error * output of a subprocess are sent to two separate streams, which can * be accessed using the {@link Process#getInputStream()} and {@link - * Process#getErrorStream()} methods. If the value is set to - * true, the standard error is merged with the standard - * output. This makes it easier to correlate error messages with the - * corresponding output. In this case, the merged data can be read - * from the stream returned by {@link Process#getInputStream()}, while - * reading from the stream returned by {@link - * Process#getErrorStream()} will get an immediate end of file. + * Process#getErrorStream()} methods. + * + *

    If the value is set to {@code true}, then: + * + *

    * * * @@ -87,34 +136,43 @@ import java.util.Map; * is invoked. * *

    Note that this class is not synchronized. - * If multiple threads access a ProcessBuilder instance + * If multiple threads access a {@code ProcessBuilder} instance * concurrently, and at least one of the threads modifies one of the * attributes structurally, it must be synchronized externally. * *

    Starting a new process which uses the default working directory * and environment is easy: * - *

    + * 
     {@code
      * Process p = new ProcessBuilder("myCommand", "myArg").start();
    - * 
    + * } * *

    Here is an example that starts a process with a modified working - * directory and environment: + * directory and environment, and redirects standard output and error + * to be appended to a log file: * - *

    - * ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
    - * Map<String, String> env = pb.environment();
    + * 
     {@code
    + * ProcessBuilder pb =
    + *   new ProcessBuilder("myCommand", "myArg1", "myArg2");
    + * Map env = pb.environment();
      * env.put("VAR1", "myValue");
      * env.remove("OTHERVAR");
      * env.put("VAR2", env.get("VAR1") + "suffix");
      * pb.directory(new File("myDir"));
    + * File log = new File("log");
    + * pb.redirectErrorStream(true);
    + * pb.redirectOutput(Redirect.appendTo(log));
      * Process p = pb.start();
    - * 
    + * assert pb.redirectInput() == Redirect.PIPE; + * assert pb.redirectOutput().file() == log; + * assert p.getInputStream().read() == -1; + * } * *

    To start a process with an explicit set of environment * variables, first call {@link java.util.Map#clear() Map.clear()} * before adding environment variables. * + * @author Martin Buchholz * @since 1.5 */ @@ -124,20 +182,19 @@ public final class ProcessBuilder private File directory; private Map environment; private boolean redirectErrorStream; + private Redirect[] redirects; /** * Constructs a process builder with the specified operating * system program and arguments. This constructor does not - * make a copy of the command list. Subsequent + * make a copy of the {@code command} list. Subsequent * updates to the list will be reflected in the state of the * process builder. It is not checked whether - * command corresponds to a valid operating system - * command.

    + * {@code command} corresponds to a valid operating system + * command. * - * @param command The list containing the program and its arguments - * - * @throws NullPointerException - * If the argument is null + * @param command the list containing the program and its arguments + * @throws NullPointerException if the argument is null */ public ProcessBuilder(List command) { if (command == null) @@ -149,12 +206,12 @@ public final class ProcessBuilder * Constructs a process builder with the specified operating * system program and arguments. This is a convenience * constructor that sets the process builder's command to a string - * list containing the same strings as the command + * list containing the same strings as the {@code command} * array, in the same order. It is not checked whether - * command corresponds to a valid operating system - * command.

    + * {@code command} corresponds to a valid operating system + * command. * - * @param command A string array containing the program and its arguments + * @param command a string array containing the program and its arguments */ public ProcessBuilder(String... command) { this.command = new ArrayList(command.length); @@ -165,16 +222,15 @@ public final class ProcessBuilder /** * Sets this process builder's operating system program and * arguments. This method does not make a copy of the - * command list. Subsequent updates to the list will + * {@code command} list. Subsequent updates to the list will * be reflected in the state of the process builder. It is not - * checked whether command corresponds to a valid - * operating system command.

    + * checked whether {@code command} corresponds to a valid + * operating system command. * - * @param command The list containing the program and its arguments - * @return This process builder + * @param command the list containing the program and its arguments + * @return this process builder * - * @throws NullPointerException - * If the argument is null + * @throws NullPointerException if the argument is null */ public ProcessBuilder command(List command) { if (command == null) @@ -187,12 +243,12 @@ public final class ProcessBuilder * Sets this process builder's operating system program and * arguments. This is a convenience method that sets the command * to a string list containing the same strings as the - * command array, in the same order. It is not - * checked whether command corresponds to a valid - * operating system command.

    + * {@code command} array, in the same order. It is not + * checked whether {@code command} corresponds to a valid + * operating system command. * - * @param command A string array containing the program and its arguments - * @return This process builder + * @param command a string array containing the program and its arguments + * @return this process builder */ public ProcessBuilder command(String... command) { this.command = new ArrayList(command.length); @@ -205,9 +261,9 @@ public final class ProcessBuilder * Returns this process builder's operating system program and * arguments. The returned list is not a copy. Subsequent * updates to the list will be reflected in the state of this - * process builder.

    + * process builder. * - * @return This process builder's program and its arguments + * @return this process builder's program and its arguments */ public List command() { return command; @@ -225,10 +281,10 @@ public final class ProcessBuilder *

    The returned object may be modified using ordinary {@link * java.util.Map Map} operations. These modifications will be * visible to subprocesses started via the {@link #start()} - * method. Two ProcessBuilder instances always + * method. Two {@code ProcessBuilder} instances always * contain independent process environments, so changes to the * returned map will never be reflected in any other - * ProcessBuilder instance or the values returned by + * {@code ProcessBuilder} instance or the values returned by * {@link System#getenv System.getenv}. * *

    If the system does not support environment variables, an @@ -262,25 +318,24 @@ public final class ProcessBuilder *

    The returned map is typically case-sensitive on all platforms. * *

    If a security manager exists, its - * {@link SecurityManager#checkPermission checkPermission} - * method is called with a - * {@link RuntimePermission}("getenv.*") - * permission. This may result in a {@link SecurityException} being - * thrown. + * {@link SecurityManager#checkPermission checkPermission} method + * is called with a + * {@link RuntimePermission}{@code ("getenv.*")} permission. + * This may result in a {@link SecurityException} being thrown. * *

    When passing information to a Java subprocess, * system properties - * are generally preferred over environment variables.

    + * are generally preferred over environment variables. * - * @return This process builder's environment + * @return this process builder's environment * - * @throws SecurityException - * If a security manager exists and its - * {@link SecurityManager#checkPermission checkPermission} - * method doesn't allow access to the process environment + * @throws SecurityException + * if a security manager exists and its + * {@link SecurityManager#checkPermission checkPermission} + * method doesn't allow access to the process environment * - * @see Runtime#exec(String[],String[],java.io.File) - * @see System#getenv() + * @see Runtime#exec(String[],String[],java.io.File) + * @see System#getenv() */ public Map environment() { SecurityManager security = System.getSecurityManager(); @@ -328,12 +383,12 @@ public final class ProcessBuilder * * Subprocesses subsequently started by this object's {@link * #start()} method will use this as their working directory. - * The returned value may be null -- this means to use + * The returned value may be {@code null} -- this means to use * the working directory of the current Java process, usually the - * directory named by the system property user.dir, - * as the working directory of the child process.

    + * directory named by the system property {@code user.dir}, + * as the working directory of the child process. * - * @return This process builder's working directory + * @return this process builder's working directory */ public File directory() { return directory; @@ -344,50 +399,522 @@ public final class ProcessBuilder * * Subprocesses subsequently started by this object's {@link * #start()} method will use this as their working directory. - * The argument may be null -- this means to use the + * The argument may be {@code null} -- this means to use the * working directory of the current Java process, usually the - * directory named by the system property user.dir, - * as the working directory of the child process.

    + * directory named by the system property {@code user.dir}, + * as the working directory of the child process. * - * @param directory The new working directory - * @return This process builder + * @param directory the new working directory + * @return this process builder */ public ProcessBuilder directory(File directory) { this.directory = directory; return this; } + // ---------------- I/O Redirection ---------------- + + /** + * Implements a null input stream. + */ + static class NullInputStream extends InputStream { + public int read() { return -1; } + public int available() { return 0; } + } + + /** + * Implements a null output stream. + */ + static class NullOutputStream extends OutputStream { + public void write(int b) throws IOException { + throw new IOException("Stream closed"); + } + } + + /** + * Represents a source of subprocess input or a destination of + * subprocess output. + * + * Each {@code Redirect} instance is one of the following: + * + *
      + *
    • the special value {@link #PIPE Redirect.PIPE} + *
    • the special value {@link #INHERIT Redirect.INHERIT} + *
    • a redirection to read from a file, created by an invocation of + * {@link Redirect#from Redirect.from(File)} + *
    • a redirection to write to a file, created by an invocation of + * {@link Redirect#to Redirect.to(File)} + *
    • a redirection to append to a file, created by an invocation of + * {@link Redirect#appendTo Redirect.appendTo(File)} + *
    + * + *

    Each of the above categories has an associated unique + * {@link Type Type}. + * + * @since 1.7 + */ + public static abstract class Redirect { + /** + * The type of a {@link Redirect}. + */ + public enum Type { + /** + * The type of {@link Redirect#PIPE Redirect.PIPE}. + */ + PIPE, + + /** + * The type of {@link Redirect#INHERIT Redirect.INHERIT}. + */ + INHERIT, + + /** + * The type of redirects returned from + * {@link Redirect#from Redirect.from(File)}. + */ + READ, + + /** + * The type of redirects returned from + * {@link Redirect#to Redirect.to(File)}. + */ + WRITE, + + /** + * The type of redirects returned from + * {@link Redirect#appendTo Redirect.appendTo(File)}. + */ + APPEND + }; + + /** + * Returns the type of this {@code Redirect}. + * @return the type of this {@code Redirect} + */ + public abstract Type type(); + + /** + * Indicates that subprocess I/O will be connected to the + * current Java process over a pipe. + * + * This is the default handling of subprocess standard I/O. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.PIPE.file() == null &&
    +         * Redirect.PIPE.type() == Redirect.Type.PIPE
    +         * }
    + */ + public static final Redirect PIPE = new Redirect() { + public Type type() { return Type.PIPE; } + public String toString() { return type().toString(); }}; + + /** + * Indicates that subprocess I/O source or destination will be the + * same as those of the current process. This is the normal + * behavior of most operating system command interpreters (shells). + * + *

    It will always be true that + *

     {@code
    +         * Redirect.INHERIT.file() == null &&
    +         * Redirect.INHERIT.type() == Redirect.Type.INHERIT
    +         * }
    + */ + public static final Redirect INHERIT = new Redirect() { + public Type type() { return Type.INHERIT; } + public String toString() { return type().toString(); }}; + + /** + * Returns the {@link File} source or destination associated + * with this redirect, or {@code null} if there is no such file. + * + * @return the file associated with this redirect, + * or {@code null} if there is no such file + */ + public File file() { return null; } + + FileOutputStream toFileOutputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + /** + * Returns a redirect to read from the specified file. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.from(file).file() == file &&
    +         * Redirect.from(file).type() == Redirect.Type.READ
    +         * }
    + * + * @throws NullPointerException if the specified file is null + * @return a redirect to read from the specified file + */ + public static Redirect from(final File file) { + if (file == null) + throw new NullPointerException(); + return new Redirect() { + public Type type() { return Type.READ; } + public File file() { return file; } + public String toString() { + return "redirect to read from file \"" + file + "\""; + } + }; + } + + /** + * Returns a redirect to write to the specified file. + * If the specified file exists when the subprocess is started, + * its previous contents will be discarded. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.to(file).file() == file &&
    +         * Redirect.to(file).type() == Redirect.Type.WRITE
    +         * }
    + * + * @throws NullPointerException if the specified file is null + * @return a redirect to write to the specified file + */ + public static Redirect to(final File file) { + if (file == null) + throw new NullPointerException(); + return new Redirect() { + public Type type() { return Type.WRITE; } + public File file() { return file; } + public String toString() { + return "redirect to write to file \"" + file + "\""; + } + FileOutputStream toFileOutputStream() throws IOException { + return new FileOutputStream(file, false); + } + }; + } + + /** + * Returns a redirect to append to the specified file. + * Each write operation first advances the position to the + * end of the file and then writes the requested data. + * Whether the advancement of the position and the writing + * of the data are done in a single atomic operation is + * system-dependent and therefore unspecified. + * + *

    It will always be true that + *

     {@code
    +         * Redirect.appendTo(file).file() == file &&
    +         * Redirect.appendTo(file).type() == Redirect.Type.APPEND
    +         * }
    + * + * @throws NullPointerException if the specified file is null + * @return a redirect to append to the specified file + */ + public static Redirect appendTo(final File file) { + if (file == null) + throw new NullPointerException(); + return new Redirect() { + public Type type() { return Type.APPEND; } + public File file() { return file; } + public String toString() { + return "redirect to append to file \"" + file + "\""; + } + FileOutputStream toFileOutputStream() throws IOException { + return new FileOutputStream(file, true); + } + }; + } + + /** + * Compares the specified object with this {@code Redirect} for + * equality. Returns {@code true} if and only if the two + * objects are identical or both objects are {@code Redirect} + * instances of the same type associated with non-null equal + * {@code File} instances. + */ + public boolean equals(Object obj) { + if (obj == this) + return true; + if (! (obj instanceof Redirect)) + return false; + Redirect r = (Redirect) obj; + if (r.type() != this.type()) + return false; + assert this.file() != null; + return this.file().equals(r.file()); + } + + /** + * Returns a hash code value for this {@code Redirect}. + * @return a hash code value for this {@code Redirect} + */ + public int hashCode() { + File file = file(); + if (file == null) + return super.hashCode(); + else + return file.hashCode(); + } + + /** + * No public constructors. Clients must use predefined + * static {@code Redirect} instances or factory methods. + */ + private Redirect() {} + } + + private Redirect[] redirects() { + if (redirects == null) + redirects = new Redirect[] { + Redirect.PIPE, Redirect.PIPE, Redirect.PIPE + }; + return redirects; + } + + /** + * Sets this process builder's standard input source. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method obtain their standard input from this source. + * + *

    If the source is {@link Redirect#PIPE Redirect.PIPE} + * (the initial value), then the standard input of a + * subprocess can be written to using the output stream + * returned by {@link Process#getOutputStream()}. + * If the source is set to any other value, then + * {@link Process#getOutputStream()} will return a + * null output stream. + * + * @param source the new standard input source + * @return this process builder + * @throws IllegalArgumentException + * if the redirect does not correspond to a valid source + * of data, that is, has type + * {@link Redirect.Type#WRITE WRITE} or + * {@link Redirect.Type#APPEND APPEND} + * @since 1.7 + */ + public ProcessBuilder redirectInput(Redirect source) { + if (source.type() == Redirect.Type.WRITE || + source.type() == Redirect.Type.APPEND) + throw new IllegalArgumentException( + "Redirect invalid for reading: " + source); + redirects()[0] = source; + return this; + } + + /** + * Sets this process builder's standard output destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method send their standard output to this destination. + * + *

    If the destination is {@link Redirect#PIPE Redirect.PIPE} + * (the initial value), then the standard output of a subprocess + * can be read using the input stream returned by {@link + * Process#getInputStream()}. + * If the destination is set to any other value, then + * {@link Process#getInputStream()} will return a + * null input stream. + * + * @param destination the new standard output destination + * @return this process builder + * @throws IllegalArgumentException + * if the redirect does not correspond to a valid + * destination of data, that is, has type + * {@link Redirect.Type#READ READ} + * @since 1.7 + */ + public ProcessBuilder redirectOutput(Redirect destination) { + if (destination.type() == Redirect.Type.READ) + throw new IllegalArgumentException( + "Redirect invalid for writing: " + destination); + redirects()[1] = destination; + return this; + } + + /** + * Sets this process builder's standard error destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method send their standard error to this destination. + * + *

    If the destination is {@link Redirect#PIPE Redirect.PIPE} + * (the initial value), then the error output of a subprocess + * can be read using the input stream returned by {@link + * Process#getErrorStream()}. + * If the destination is set to any other value, then + * {@link Process#getErrorStream()} will return a + * null input stream. + * + *

    If the {@link #redirectErrorStream redirectErrorStream} + * attribute has been set {@code true}, then the redirection set + * by this method has no effect. + * + * @param destination the new standard error destination + * @return this process builder + * @throws IllegalArgumentException + * if the redirect does not correspond to a valid + * destination of data, that is, has type + * {@link Redirect.Type#READ READ} + * @since 1.7 + */ + public ProcessBuilder redirectError(Redirect destination) { + if (destination.type() == Redirect.Type.READ) + throw new IllegalArgumentException( + "Redirect invalid for writing: " + destination); + redirects()[2] = destination; + return this; + } + + /** + * Sets this process builder's standard input source to a file. + * + *

    This is a convenience method. An invocation of the form + * {@code redirectInput(file)} + * behaves in exactly the same way as the invocation + * {@link #redirectInput(Redirect) redirectInput} + * {@code (Redirect.from(file))}. + * + * @param file the new standard input source + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder redirectInput(File file) { + return redirectInput(Redirect.from(file)); + } + + /** + * Sets this process builder's standard output destination to a file. + * + *

    This is a convenience method. An invocation of the form + * {@code redirectOutput(file)} + * behaves in exactly the same way as the invocation + * {@link #redirectOutput(Redirect) redirectOutput} + * {@code (Redirect.to(file))}. + * + * @param file the new standard output destination + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder redirectOutput(File file) { + return redirectOutput(Redirect.to(file)); + } + + /** + * Sets this process builder's standard error destination to a file. + * + *

    This is a convenience method. An invocation of the form + * {@code redirectError(file)} + * behaves in exactly the same way as the invocation + * {@link #redirectError(Redirect) redirectError} + * {@code (Redirect.to(file))}. + * + * @param file the new standard error destination + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder redirectError(File file) { + return redirectError(Redirect.to(file)); + } + + /** + * Returns this process builder's standard input source. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method obtain their standard input from this source. + * The initial value is {@link Redirect#PIPE Redirect.PIPE}. + * + * @return this process builder's standard input source + * @since 1.7 + */ + public Redirect redirectInput() { + return (redirects == null) ? Redirect.PIPE : redirects[0]; + } + + /** + * Returns this process builder's standard output destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method redirect their standard output to this destination. + * The initial value is {@link Redirect#PIPE Redirect.PIPE}. + * + * @return this process builder's standard output destination + * @since 1.7 + */ + public Redirect redirectOutput() { + return (redirects == null) ? Redirect.PIPE : redirects[1]; + } + + /** + * Returns this process builder's standard error destination. + * + * Subprocesses subsequently started by this object's {@link #start()} + * method redirect their standard error to this destination. + * The initial value is {@link Redirect#PIPE Redirect.PIPE}. + * + * @return this process builder's standard error destination + * @since 1.7 + */ + public Redirect redirectError() { + return (redirects == null) ? Redirect.PIPE : redirects[2]; + } + + /** + * Sets the source and destination for subprocess standard I/O + * to be the same as those of the current Java process. + * + *

    This is a convenience method. An invocation of the form + *

     {@code
    +     * pb.inheritIO()
    +     * }
    + * behaves in exactly the same way as the invocation + *
     {@code
    +     * pb.redirectInput(Redirect.INHERIT)
    +     *   .redirectOutput(Redirect.INHERIT)
    +     *   .redirectError(Redirect.INHERIT)
    +     * }
    + * + * This gives behavior equivalent to most operating system + * command interpreters, or the standard C library function + * {@code system()}. + * + * @return this process builder + * @since 1.7 + */ + public ProcessBuilder inheritIO() { + Arrays.fill(redirects(), Redirect.INHERIT); + return this; + } + /** * Tells whether this process builder merges standard error and * standard output. * - *

    If this property is true, then any error output + *

    If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the * {@link Process#getInputStream()} method. This makes it easier * to correlate error messages with the corresponding output. - * The initial value is false.

    + * The initial value is {@code false}. * - * @return This process builder's redirectErrorStream property + * @return this process builder's {@code redirectErrorStream} property */ public boolean redirectErrorStream() { return redirectErrorStream; } /** - * Sets this process builder's redirectErrorStream property. + * Sets this process builder's {@code redirectErrorStream} property. * - *

    If this property is true, then any error output + *

    If this property is {@code true}, then any error output * generated by subprocesses subsequently started by this object's * {@link #start()} method will be merged with the standard * output, so that both can be read using the * {@link Process#getInputStream()} method. This makes it easier * to correlate error messages with the corresponding output. - * The initial value is false.

    + * The initial value is {@code false}. * - * @param redirectErrorStream The new property value - * @return This process builder + * @param redirectErrorStream the new property value + * @return this process builder */ public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) { this.redirectErrorStream = redirectErrorStream; @@ -410,7 +937,7 @@ public final class ProcessBuilder *

    If there is a security manager, its * {@link SecurityManager#checkExec checkExec} * method is called with the first component of this object's - * command array as its argument. This may result in + * {@code command} array as its argument. This may result in * a {@link SecurityException} being thrown. * *

    Starting an operating system process is highly system-dependent. @@ -426,26 +953,42 @@ public final class ProcessBuilder * subclass of {@link IOException}. * *

    Subsequent modifications to this process builder will not - * affect the returned {@link Process}.

    + * affect the returned {@link Process}. * - * @return A new {@link Process} object for managing the subprocess + * @return a new {@link Process} object for managing the subprocess * - * @throws NullPointerException - * If an element of the command list is null + * @throws NullPointerException + * if an element of the command list is null * - * @throws IndexOutOfBoundsException - * If the command is an empty list (has size 0) + * @throws IndexOutOfBoundsException + * if the command is an empty list (has size {@code 0}) * - * @throws SecurityException - * If a security manager exists and its - * {@link SecurityManager#checkExec checkExec} - * method doesn't allow creation of the subprocess + * @throws SecurityException + * if a security manager exists and + *
      * - * @throws IOException - * If an I/O error occurs + *
    • its + * {@link SecurityManager#checkExec checkExec} + * method doesn't allow creation of the subprocess, or * - * @see Runtime#exec(String[], String[], java.io.File) - * @see SecurityManager#checkExec(String) + *
    • the standard input to the subprocess was + * {@linkplain #redirectInput redirected from a file} + * and the security manager's + * {@link SecurityManager#checkRead checkRead} method + * denies read access to the file, or + * + *
    • the standard output or standard error of the + * subprocess was + * {@linkplain #redirectOutput redirected to a file} + * and the security manager's + * {@link SecurityManager#checkWrite checkWrite} method + * denies write access to the file + * + *
    + * + * @throws IOException if an I/O error occurs + * + * @see Runtime#exec(String[], String[], java.io.File) */ public Process start() throws IOException { // Must convert to array first -- a malicious user-supplied @@ -467,6 +1010,7 @@ public final class ProcessBuilder return ProcessImpl.start(cmdarray, environment, dir, + redirects, redirectErrorStream); } catch (IOException e) { // It's much easier for us to create a high-quality error diff --git a/jdk/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java b/jdk/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java index 874145c6290..42f3ea1ae66 100644 --- a/jdk/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java +++ b/jdk/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java @@ -33,4 +33,8 @@ import java.io.FileDescriptor; public interface JavaIOFileDescriptorAccess { public void set(FileDescriptor obj, int fd); public int get(FileDescriptor fd); + + // Only valid on Windows + public void setHandle(FileDescriptor obj, long handle); + public long getHandle(FileDescriptor obj); } diff --git a/jdk/src/solaris/classes/java/io/FileDescriptor.java b/jdk/src/solaris/classes/java/io/FileDescriptor.java index fdd1d143b82..ef8aa1c4602 100644 --- a/jdk/src/solaris/classes/java/io/FileDescriptor.java +++ b/jdk/src/solaris/classes/java/io/FileDescriptor.java @@ -152,11 +152,19 @@ public final class FileDescriptor { public int get(FileDescriptor obj) { return obj.fd; } + + public void setHandle(FileDescriptor obj, long handle) { + throw new UnsupportedOperationException(); + } + + public long getHandle(FileDescriptor obj) { + throw new UnsupportedOperationException(); + } } ); } - // pacakge private methods used by FIS,FOS and RAF + // package private methods used by FIS, FOS and RAF int incrementAndGetUseCount() { return useCount.incrementAndGet(); diff --git a/jdk/src/solaris/classes/java/lang/ProcessImpl.java b/jdk/src/solaris/classes/java/lang/ProcessImpl.java index d7bdbe19117..b9074349efa 100644 --- a/jdk/src/solaris/classes/java/lang/ProcessImpl.java +++ b/jdk/src/solaris/classes/java/lang/ProcessImpl.java @@ -26,7 +26,10 @@ package java.lang; import java.io.IOException; -import java.lang.Process; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.lang.ProcessBuilder.Redirect; +import java.lang.ProcessBuilder.Redirect; /** * This class is for the exclusive use of ProcessBuilder.start() to @@ -36,6 +39,9 @@ import java.lang.Process; * @since 1.5 */ final class ProcessImpl { + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); + private ProcessImpl() {} // Not instantiable private static byte[] toCString(String s) { @@ -54,6 +60,7 @@ final class ProcessImpl { static Process start(String[] cmdarray, java.util.Map environment, String dir, + ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException { @@ -78,11 +85,61 @@ final class ProcessImpl { int[] envc = new int[1]; byte[] envBlock = ProcessEnvironment.toEnvironmentBlock(environment, envc); + int[] std_fds; + + FileInputStream f0 = null; + FileOutputStream f1 = null; + FileOutputStream f2 = null; + + try { + if (redirects == null) { + std_fds = new int[] { -1, -1, -1 }; + } else { + std_fds = new int[3]; + + if (redirects[0] == Redirect.PIPE) + std_fds[0] = -1; + else if (redirects[0] == Redirect.INHERIT) + std_fds[0] = 0; + else { + f0 = new FileInputStream(redirects[0].file()); + std_fds[0] = fdAccess.get(f0.getFD()); + } + + if (redirects[1] == Redirect.PIPE) + std_fds[1] = -1; + else if (redirects[1] == Redirect.INHERIT) + std_fds[1] = 1; + else { + f1 = redirects[1].toFileOutputStream(); + std_fds[1] = fdAccess.get(f1.getFD()); + } + + if (redirects[2] == Redirect.PIPE) + std_fds[2] = -1; + else if (redirects[2] == Redirect.INHERIT) + std_fds[2] = 2; + else { + f2 = redirects[2].toFileOutputStream(); + std_fds[2] = fdAccess.get(f2.getFD()); + } + } + return new UNIXProcess (toCString(cmdarray[0]), argBlock, args.length, envBlock, envc[0], toCString(dir), + std_fds, redirectErrorStream); + } finally { + // In theory, close() can throw IOException + // (although it is rather unlikely to happen here) + try { if (f0 != null) f0.close(); } + finally { + try { if (f1 != null) f1.close(); } + finally { if (f2 != null) f2.close(); } + } + } } } diff --git a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux index ded83065eb7..9fc9e9da645 100644 --- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux +++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux @@ -1,5 +1,5 @@ -/* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. +/* + * Copyright 1995-2008 Sun Microsystems, Inc. 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 @@ -34,9 +34,9 @@ import java.io.*; */ final class UNIXProcess extends Process { - private FileDescriptor stdin_fd; - private FileDescriptor stdout_fd; - private FileDescriptor stderr_fd; + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); + private int pid; private int exitcode; private boolean hasExited; @@ -48,15 +48,26 @@ final class UNIXProcess extends Process { /* this is for the reaping thread */ private native int waitForProcessExit(int pid); + /** + * Create a process using fork(2) and exec(2). + * + * @param std_fds array of file descriptors. Indexes 0, 1, and + * 2 correspond to standard input, standard output and + * standard error, respectively. On input, a value of -1 + * means to create a pipe to connect child and parent + * processes. On output, a value which is not -1 is the + * parent pipe fd corresponding to the pipe which has + * been created. An element of this array is -1 on input + * if and only if it is not -1 on output. + * @return the pid of the subprocess + */ private native int forkAndExec(byte[] prog, - byte[] argBlock, int argc, - byte[] envBlock, int envc, - byte[] dir, - boolean redirectErrorStream, - FileDescriptor stdin_fd, - FileDescriptor stdout_fd, - FileDescriptor stderr_fd) - throws IOException; + byte[] argBlock, int argc, + byte[] envBlock, int envc, + byte[] dir, + int[] std_fds, + boolean redirectErrorStream) + throws IOException; /* In the process constructor we wait on this gate until the process */ /* has been created. Then we return from the constructor. */ @@ -97,67 +108,82 @@ final class UNIXProcess extends Process { } UNIXProcess(final byte[] prog, - final byte[] argBlock, final int argc, - final byte[] envBlock, final int envc, - final byte[] dir, - final boolean redirectErrorStream) + final byte[] argBlock, final int argc, + final byte[] envBlock, final int envc, + final byte[] dir, + final int[] std_fds, + final boolean redirectErrorStream) throws IOException { - stdin_fd = new FileDescriptor(); - stdout_fd = new FileDescriptor(); - stderr_fd = new FileDescriptor(); final Gate gate = new Gate(); - /* - * For each subprocess forked a corresponding reaper thread - * is started. That thread is the only thread which waits - * for the subprocess to terminate and it doesn't hold any - * locks while doing so. This design allows waitFor() and - * exitStatus() to be safely executed in parallel (and they - * need no native code). - */ + /* + * For each subprocess forked a corresponding reaper thread + * is started. That thread is the only thread which waits + * for the subprocess to terminate and it doesn't hold any + * locks while doing so. This design allows waitFor() and + * exitStatus() to be safely executed in parallel (and they + * need no native code). + */ - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - Thread t = new Thread("process reaper") { - public void run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + Thread t = new Thread("process reaper") { + public void run() { try { pid = forkAndExec(prog, - argBlock, argc, - envBlock, envc, - dir, - redirectErrorStream, - stdin_fd, stdout_fd, stderr_fd); + argBlock, argc, + envBlock, envc, + dir, + std_fds, + redirectErrorStream); } catch (IOException e) { gate.setException(e); /*remember to rethrow later*/ gate.exit(); return; } java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - stdin_stream = new BufferedOutputStream(new - FileOutputStream(stdin_fd)); - stdout_stream = new BufferedInputStream(new - FileInputStream(stdout_fd)); - stderr_stream = new FileInputStream(stderr_fd); - return null; + new java.security.PrivilegedAction() { + public Void run() { + if (std_fds[0] == -1) + stdin_stream = new ProcessBuilder.NullOutputStream(); + else { + FileDescriptor stdin_fd = new FileDescriptor(); + fdAccess.set(stdin_fd, std_fds[0]); + stdin_stream = new BufferedOutputStream( + new FileOutputStream(stdin_fd)); } - }); + + if (std_fds[1] == -1) + stdout_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stdout_fd = new FileDescriptor(); + fdAccess.set(stdout_fd, std_fds[1]); + stdout_stream = new BufferedInputStream( + new FileInputStream(stdout_fd)); + } + + if (std_fds[2] == -1) + stderr_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stderr_fd = new FileDescriptor(); + fdAccess.set(stderr_fd, std_fds[2]); + stderr_stream = new FileInputStream(stderr_fd); + } + + return null; }}); gate.exit(); /* exit from constructor */ - int res = waitForProcessExit(pid); - synchronized (UNIXProcess.this) { - hasExited = true; - exitcode = res; - UNIXProcess.this.notifyAll(); - } - } - }; + int res = waitForProcessExit(pid); + synchronized (UNIXProcess.this) { + hasExited = true; + exitcode = res; + UNIXProcess.this.notifyAll(); + } + } + }; t.setDaemon(true); t.start(); - return null; - } - }); + return null; }}); gate.waitForExit(); IOException e = gate.getException(); if (e != null) @@ -165,43 +191,43 @@ final class UNIXProcess extends Process { } public OutputStream getOutputStream() { - return stdin_stream; + return stdin_stream; } public InputStream getInputStream() { - return stdout_stream; + return stdout_stream; } public InputStream getErrorStream() { - return stderr_stream; + return stderr_stream; } public synchronized int waitFor() throws InterruptedException { while (!hasExited) { - wait(); - } - return exitcode; + wait(); + } + return exitcode; } public synchronized int exitValue() { - if (!hasExited) { - throw new IllegalThreadStateException("process hasn't exited"); - } - return exitcode; + if (!hasExited) { + throw new IllegalThreadStateException("process hasn't exited"); + } + return exitcode; } private static native void destroyProcess(int pid); public void destroy() { - // There is a risk that pid will be recycled, causing us to - // kill the wrong process! So we only terminate processes - // that appear to still be running. Even with this check, - // there is an unavoidable race condition here, but the window - // is very small, and OSes try hard to not recycle pids too - // soon, so this is quite safe. - synchronized (this) { - if (!hasExited) - destroyProcess(pid); - } + // There is a risk that pid will be recycled, causing us to + // kill the wrong process! So we only terminate processes + // that appear to still be running. Even with this check, + // there is an unavoidable race condition here, but the window + // is very small, and OSes try hard to not recycle pids too + // soon, so this is quite safe. + synchronized (this) { + if (!hasExited) + destroyProcess(pid); + } try { stdin_stream.close(); stdout_stream.close(); @@ -215,6 +241,6 @@ final class UNIXProcess extends Process { private static native void initIDs(); static { - initIDs(); + initIDs(); } } diff --git a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris index ae29a09e562..f47d1043175 100644 --- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris +++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris @@ -1,5 +1,5 @@ -/* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. +/* + * Copyright 1995-2008 Sun Microsystems, Inc. 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,129 +33,155 @@ import java.io.*; */ final class UNIXProcess extends Process { - private FileDescriptor stdin_fd; - private FileDescriptor stdout_fd; - private FileDescriptor stderr_fd; - private int pid; + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); + + private final int pid; private int exitcode; private boolean hasExited; private OutputStream stdin_stream; - private BufferedInputStream stdout_stream; + private InputStream stdout_stream; private DeferredCloseInputStream stdout_inner_stream; - private DeferredCloseInputStream stderr_stream; + private InputStream stderr_stream; /* this is for the reaping thread */ private native int waitForProcessExit(int pid); + /** + * Create a process using fork(2) and exec(2). + * + * @param std_fds array of file descriptors. Indexes 0, 1, and + * 2 correspond to standard input, standard output and + * standard error, respectively. On input, a value of -1 + * means to create a pipe to connect child and parent + * processes. On output, a value which is not -1 is the + * parent pipe fd corresponding to the pipe which has + * been created. An element of this array is -1 on input + * if and only if it is not -1 on output. + * @return the pid of the subprocess + */ private native int forkAndExec(byte[] prog, - byte[] argBlock, int argc, - byte[] envBlock, int envc, - byte[] dir, - boolean redirectErrorStream, - FileDescriptor stdin_fd, - FileDescriptor stdout_fd, - FileDescriptor stderr_fd) - throws IOException; + byte[] argBlock, int argc, + byte[] envBlock, int envc, + byte[] dir, + int[] std_fds, + boolean redirectErrorStream) + throws IOException; UNIXProcess(final byte[] prog, - final byte[] argBlock, int argc, - final byte[] envBlock, int envc, - final byte[] dir, - final boolean redirectErrorStream) + final byte[] argBlock, int argc, + final byte[] envBlock, int envc, + final byte[] dir, + final int[] std_fds, + final boolean redirectErrorStream) throws IOException { - stdin_fd = new FileDescriptor(); - stdout_fd = new FileDescriptor(); - stderr_fd = new FileDescriptor(); + pid = forkAndExec(prog, + argBlock, argc, + envBlock, envc, + dir, + std_fds, + redirectErrorStream); - pid = forkAndExec(prog, - argBlock, argc, - envBlock, envc, - dir, - redirectErrorStream, - stdin_fd, stdout_fd, stderr_fd); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { public Void run() { + if (std_fds[0] == -1) + stdin_stream = new ProcessBuilder.NullOutputStream(); + else { + FileDescriptor stdin_fd = new FileDescriptor(); + fdAccess.set(stdin_fd, std_fds[0]); + stdin_stream = new BufferedOutputStream( + new FileOutputStream(stdin_fd)); + } - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - stdin_stream - = new BufferedOutputStream(new FileOutputStream(stdin_fd)); - stdout_inner_stream = new DeferredCloseInputStream(stdout_fd); - stdout_stream = new BufferedInputStream(stdout_inner_stream); - stderr_stream = new DeferredCloseInputStream(stderr_fd); - return null; - } - }); + if (std_fds[1] == -1) + stdout_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stdout_fd = new FileDescriptor(); + fdAccess.set(stdout_fd, std_fds[1]); + stdout_inner_stream = new DeferredCloseInputStream(stdout_fd); + stdout_stream = new BufferedInputStream(stdout_inner_stream); + } - /* - * For each subprocess forked a corresponding reaper thread - * is started. That thread is the only thread which waits - * for the subprocess to terminate and it doesn't hold any - * locks while doing so. This design allows waitFor() and - * exitStatus() to be safely executed in parallel (and they - * need no native code). - */ + if (std_fds[2] == -1) + stderr_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stderr_fd = new FileDescriptor(); + fdAccess.set(stderr_fd, std_fds[2]); + stderr_stream = new DeferredCloseInputStream(stderr_fd); + } - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - Thread t = new Thread("process reaper") { - public void run() { - int res = waitForProcessExit(pid); - synchronized (UNIXProcess.this) { - hasExited = true; - exitcode = res; - UNIXProcess.this.notifyAll(); - } - } - }; - t.setDaemon(true); - t.start(); - return null; - } - }); + return null; }}); + + /* + * For each subprocess forked a corresponding reaper thread + * is started. That thread is the only thread which waits + * for the subprocess to terminate and it doesn't hold any + * locks while doing so. This design allows waitFor() and + * exitStatus() to be safely executed in parallel (and they + * need no native code). + */ + + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { public Void run() { + Thread t = new Thread("process reaper") { + public void run() { + int res = waitForProcessExit(pid); + synchronized (UNIXProcess.this) { + hasExited = true; + exitcode = res; + UNIXProcess.this.notifyAll(); + } + } + }; + t.setDaemon(true); + t.start(); + return null; }}); } public OutputStream getOutputStream() { - return stdin_stream; + return stdin_stream; } public InputStream getInputStream() { - return stdout_stream; + return stdout_stream; } public InputStream getErrorStream() { - return stderr_stream; + return stderr_stream; } public synchronized int waitFor() throws InterruptedException { while (!hasExited) { - wait(); - } - return exitcode; + wait(); + } + return exitcode; } public synchronized int exitValue() { - if (!hasExited) { - throw new IllegalThreadStateException("process hasn't exited"); - } - return exitcode; + if (!hasExited) { + throw new IllegalThreadStateException("process hasn't exited"); + } + return exitcode; } private static native void destroyProcess(int pid); public synchronized void destroy() { - // There is a risk that pid will be recycled, causing us to - // kill the wrong process! So we only terminate processes - // that appear to still be running. Even with this check, - // there is an unavoidable race condition here, but the window - // is very small, and OSes try hard to not recycle pids too - // soon, so this is quite safe. - if (!hasExited) - destroyProcess(pid); - try { + // There is a risk that pid will be recycled, causing us to + // kill the wrong process! So we only terminate processes + // that appear to still be running. Even with this check, + // there is an unavoidable race condition here, but the window + // is very small, and OSes try hard to not recycle pids too + // soon, so this is quite safe. + if (!hasExited) + destroyProcess(pid); + try { stdin_stream.close(); - stdout_inner_stream.closeDeferred(stdout_stream); - stderr_stream.closeDeferred(stderr_stream); + if (stdout_inner_stream != null) + stdout_inner_stream.closeDeferred(stdout_stream); + if (stderr_stream instanceof DeferredCloseInputStream) + ((DeferredCloseInputStream) stderr_stream) + .closeDeferred(stderr_stream); } catch (IOException e) { // ignore } @@ -172,99 +198,99 @@ final class UNIXProcess extends Process { // (EOF) as they did before. // private static class DeferredCloseInputStream - extends FileInputStream + extends FileInputStream { - private DeferredCloseInputStream(FileDescriptor fd) { - super(fd); - } + private DeferredCloseInputStream(FileDescriptor fd) { + super(fd); + } - private Object lock = new Object(); // For the following fields - private boolean closePending = false; - private int useCount = 0; - private InputStream streamToClose; + private Object lock = new Object(); // For the following fields + private boolean closePending = false; + private int useCount = 0; + private InputStream streamToClose; - private void raise() { - synchronized (lock) { - useCount++; - } - } + private void raise() { + synchronized (lock) { + useCount++; + } + } - private void lower() throws IOException { - synchronized (lock) { - useCount--; - if (useCount == 0 && closePending) { - streamToClose.close(); - } - } - } + private void lower() throws IOException { + synchronized (lock) { + useCount--; + if (useCount == 0 && closePending) { + streamToClose.close(); + } + } + } - // stc is the actual stream to be closed; it might be this object, or - // it might be an upstream object for which this object is downstream. - // - private void closeDeferred(InputStream stc) throws IOException { - synchronized (lock) { - if (useCount == 0) { - stc.close(); - } else { - closePending = true; - streamToClose = stc; - } - } - } + // stc is the actual stream to be closed; it might be this object, or + // it might be an upstream object for which this object is downstream. + // + private void closeDeferred(InputStream stc) throws IOException { + synchronized (lock) { + if (useCount == 0) { + stc.close(); + } else { + closePending = true; + streamToClose = stc; + } + } + } - public void close() throws IOException { - synchronized (lock) { - useCount = 0; - closePending = false; - } - super.close(); - } + public void close() throws IOException { + synchronized (lock) { + useCount = 0; + closePending = false; + } + super.close(); + } - public int read() throws IOException { - raise(); - try { - return super.read(); - } finally { - lower(); - } - } + public int read() throws IOException { + raise(); + try { + return super.read(); + } finally { + lower(); + } + } - public int read(byte[] b) throws IOException { - raise(); - try { - return super.read(b); - } finally { - lower(); - } - } + public int read(byte[] b) throws IOException { + raise(); + try { + return super.read(b); + } finally { + lower(); + } + } - public int read(byte[] b, int off, int len) throws IOException { - raise(); - try { - return super.read(b, off, len); - } finally { - lower(); - } - } + public int read(byte[] b, int off, int len) throws IOException { + raise(); + try { + return super.read(b, off, len); + } finally { + lower(); + } + } - public long skip(long n) throws IOException { - raise(); - try { - return super.skip(n); - } finally { - lower(); - } - } + public long skip(long n) throws IOException { + raise(); + try { + return super.skip(n); + } finally { + lower(); + } + } - public int available() throws IOException { - raise(); - try { - return super.available(); - } finally { - lower(); - } - } + public int available() throws IOException { + raise(); + try { + return super.available(); + } finally { + lower(); + } + } } @@ -272,6 +298,6 @@ final class UNIXProcess extends Process { private static native void initIDs(); static { - initIDs(); + initIDs(); } } diff --git a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c index a14496e7456..480298cde58 100644 --- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c +++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. 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 @@ -491,10 +491,8 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, jbyteArray argBlock, jint argc, jbyteArray envBlock, jint envc, jbyteArray dir, - jboolean redirectErrorStream, - jobject stdin_fd, - jobject stdout_fd, - jobject stderr_fd) + jintArray std_fds, + jboolean redirectErrorStream) { int errnum; int resultPid = -1; @@ -505,6 +503,7 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, const char *pargBlock = getBytes(env, argBlock); const char *penvBlock = getBytes(env, envBlock); const char *pdir = getBytes(env, dir); + jint *fds = NULL; in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1; @@ -527,9 +526,13 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, initVectorFromBlock(envv, penvBlock, envc); } - if ((pipe(in) < 0) || - (pipe(out) < 0) || - (pipe(err) < 0) || + assert(std_fds != NULL); + fds = (*env)->GetIntArrayElements(env, std_fds, NULL); + if (fds == NULL) goto Catch; + + if ((fds[0] == -1 && pipe(in) < 0) || + (fds[1] == -1 && pipe(out) < 0) || + (fds[2] == -1 && pipe(err) < 0) || (pipe(fail) < 0)) { throwIOException(env, errno, "Bad file descriptor"); goto Catch; @@ -544,23 +547,26 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, if (resultPid == 0) { /* Child process */ - /* Close the parent sides of the pipe. - Give the child sides of the pipes the right fileno's. + /* Close the parent sides of the pipes. Closing pipe fds here is redundant, since closeDescriptors() would do it anyways, but a little paranoia is a good thing. */ + closeSafely(in[1]); + closeSafely(out[0]); + closeSafely(err[0]); + closeSafely(fail[0]); + + /* Give the child sides of the pipes the right fileno's. */ /* Note: it is possible for in[0] == 0 */ - close(in[1]); - moveDescriptor(in[0], STDIN_FILENO); - close(out[0]); - moveDescriptor(out[1], STDOUT_FILENO); - close(err[0]); + moveDescriptor(in[0] != -1 ? in[0] : fds[0], STDIN_FILENO); + moveDescriptor(out[1]!= -1 ? out[1] : fds[1], STDOUT_FILENO); + if (redirectErrorStream) { - close(err[1]); + closeSafely(err[1]); dup2(STDOUT_FILENO, STDERR_FILENO); } else { - moveDescriptor(err[1], STDERR_FILENO); + moveDescriptor(err[1] != -1 ? err[1] : fds[2], STDERR_FILENO); } - close(fail[0]); + moveDescriptor(fail[1], FAIL_FILENO); /* close everything */ @@ -606,9 +612,9 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, goto Catch; } - (*env)->SetIntField(env, stdin_fd, IO_fd_fdID, in [1]); - (*env)->SetIntField(env, stdout_fd, IO_fd_fdID, out[0]); - (*env)->SetIntField(env, stderr_fd, IO_fd_fdID, err[0]); + fds[0] = (in [1] != -1) ? in [1] : -1; + fds[1] = (out[0] != -1) ? out[0] : -1; + fds[2] = (err[0] != -1) ? err[0] : -1; Finally: /* Always clean up the child's side of the pipes */ @@ -628,6 +634,9 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, releaseBytes(env, envBlock, penvBlock); releaseBytes(env, dir, pdir); + if (fds != NULL) + (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0); + return resultPid; Catch: diff --git a/jdk/src/windows/classes/java/io/FileDescriptor.java b/jdk/src/windows/classes/java/io/FileDescriptor.java index c02c1619c10..f2036263e8d 100644 --- a/jdk/src/windows/classes/java/io/FileDescriptor.java +++ b/jdk/src/windows/classes/java/io/FileDescriptor.java @@ -29,17 +29,14 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Instances of the file descriptor class serve as an opaque handle - * to the underlying machine-specific structure representing an open - * file, an open socket, or another source or sink of bytes. The - * main practical use for a file descriptor is to create a - * FileInputStream or FileOutputStream to - * contain it. - *

    - * Applications should not create their own file descriptors. + * to the underlying machine-specific structure representing an + * open file, an open socket, or another source or sink of bytes. + * The main practical use for a file descriptor is to create a + * {@link FileInputStream} or {@link FileOutputStream} to contain it. + * + *

    Applications should not create their own file descriptors. * * @author Pavani Diwanji - * @see java.io.FileInputStream - * @see java.io.FileOutputStream * @since JDK1.0 */ public final class FileDescriptor { @@ -81,6 +78,14 @@ public final class FileDescriptor { public int get(FileDescriptor obj) { return obj.fd; } + + public void setHandle(FileDescriptor obj, long handle) { + obj.handle = handle; + } + + public long getHandle(FileDescriptor obj) { + return obj.handle; + } } ); } @@ -88,7 +93,7 @@ public final class FileDescriptor { /** * A handle to the standard input stream. Usually, this file * descriptor is not used directly, but rather via the input stream - * known as System.in. + * known as {@code System.in}. * * @see java.lang.System#in */ @@ -97,7 +102,7 @@ public final class FileDescriptor { /** * A handle to the standard output stream. Usually, this file * descriptor is not used directly, but rather via the output stream - * known as System.out. + * known as {@code System.out}. * @see java.lang.System#out */ public static final FileDescriptor out = standardStream(1); @@ -105,7 +110,7 @@ public final class FileDescriptor { /** * A handle to the standard error stream. Usually, this file * descriptor is not used directly, but rather via the output stream - * known as System.err. + * known as {@code System.err}. * * @see java.lang.System#err */ @@ -114,9 +119,9 @@ public final class FileDescriptor { /** * Tests if this file descriptor object is valid. * - * @return true if the file descriptor object represents a + * @return {@code true} if the file descriptor object represents a * valid, open file, socket, or other active I/O connection; - * false otherwise. + * {@code false} otherwise. */ public boolean valid() { return ((handle != -1) || (fd != -1)); diff --git a/jdk/src/windows/classes/java/lang/ProcessImpl.java b/jdk/src/windows/classes/java/lang/ProcessImpl.java index 9db29772571..910575c4447 100644 --- a/jdk/src/windows/classes/java/lang/ProcessImpl.java +++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java @@ -25,7 +25,16 @@ package java.lang; -import java.io.*; +import java.io.IOException; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileDescriptor; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.lang.ProcessBuilder.Redirect; /* This class is for the exclusive use of ProcessBuilder.start() to * create new processes. @@ -35,30 +44,82 @@ import java.io.*; */ final class ProcessImpl extends Process { + private static final sun.misc.JavaIOFileDescriptorAccess fdAccess + = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); // System-dependent portion of ProcessBuilder.start() static Process start(String cmdarray[], java.util.Map environment, String dir, + ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException { String envblock = ProcessEnvironment.toEnvironmentBlock(environment); - return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream); + + FileInputStream f0 = null; + FileOutputStream f1 = null; + FileOutputStream f2 = null; + + try { + long[] stdHandles; + if (redirects == null) { + stdHandles = new long[] { -1L, -1L, -1L }; + } else { + stdHandles = new long[3]; + + if (redirects[0] == Redirect.PIPE) + stdHandles[0] = -1L; + else if (redirects[0] == Redirect.INHERIT) + stdHandles[0] = fdAccess.getHandle(FileDescriptor.in); + else { + f0 = new FileInputStream(redirects[0].file()); + stdHandles[0] = fdAccess.getHandle(f0.getFD()); + } + + if (redirects[1] == Redirect.PIPE) + stdHandles[1] = -1L; + else if (redirects[1] == Redirect.INHERIT) + stdHandles[1] = fdAccess.getHandle(FileDescriptor.out); + else { + f1 = redirects[1].toFileOutputStream(); + stdHandles[1] = fdAccess.getHandle(f1.getFD()); + } + + if (redirects[2] == Redirect.PIPE) + stdHandles[2] = -1L; + else if (redirects[2] == Redirect.INHERIT) + stdHandles[2] = fdAccess.getHandle(FileDescriptor.err); + else { + f2 = redirects[2].toFileOutputStream(); + stdHandles[2] = fdAccess.getHandle(f2.getFD()); + } + } + + return new ProcessImpl(cmdarray, envblock, dir, + stdHandles, redirectErrorStream); + } finally { + // In theory, close() can throw IOException + // (although it is rather unlikely to happen here) + try { if (f0 != null) f0.close(); } + finally { + try { if (f1 != null) f1.close(); } + finally { if (f2 != null) f2.close(); } + } + } + } private long handle = 0; - private FileDescriptor stdin_fd; - private FileDescriptor stdout_fd; - private FileDescriptor stderr_fd; private OutputStream stdin_stream; private InputStream stdout_stream; private InputStream stderr_stream; - private ProcessImpl(String cmd[], - String envblock, - String path, - boolean redirectErrorStream) + private ProcessImpl(final String cmd[], + final String envblock, + final String path, + final long[] stdHandles, + final boolean redirectErrorStream) throws IOException { // Win32 CreateProcess requires cmd[0] to be normalized @@ -91,25 +152,39 @@ final class ProcessImpl extends Process { } String cmdstr = cmdbuf.toString(); - stdin_fd = new FileDescriptor(); - stdout_fd = new FileDescriptor(); - stderr_fd = new FileDescriptor(); - - handle = create(cmdstr, envblock, path, redirectErrorStream, - stdin_fd, stdout_fd, stderr_fd); + handle = create(cmdstr, envblock, path, + stdHandles, redirectErrorStream); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - stdin_stream = - new BufferedOutputStream(new FileOutputStream(stdin_fd)); - stdout_stream = - new BufferedInputStream(new FileInputStream(stdout_fd)); - stderr_stream = - new FileInputStream(stderr_fd); - return null; + new java.security.PrivilegedAction() { + public Void run() { + if (stdHandles[0] == -1L) + stdin_stream = new ProcessBuilder.NullOutputStream(); + else { + FileDescriptor stdin_fd = new FileDescriptor(); + fdAccess.setHandle(stdin_fd, stdHandles[0]); + stdin_stream = new BufferedOutputStream( + new FileOutputStream(stdin_fd)); } - }); + + if (stdHandles[1] == -1L) + stdout_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stdout_fd = new FileDescriptor(); + fdAccess.setHandle(stdout_fd, stdHandles[1]); + stdout_stream = new BufferedInputStream( + new FileInputStream(stdout_fd)); + } + + if (stdHandles[2] == -1L) + stderr_stream = new ProcessBuilder.NullInputStream(); + else { + FileDescriptor stderr_fd = new FileDescriptor(); + fdAccess.setHandle(stderr_fd, stdHandles[2]); + stderr_stream = new FileInputStream(stderr_fd); + } + + return null; }}); } public OutputStream getOutputStream() { @@ -150,13 +225,30 @@ final class ProcessImpl extends Process { public void destroy() { terminateProcess(handle); } private static native void terminateProcess(long handle); + /** + * Create a process using the win32 function CreateProcess. + * + * @param cmdstr the Windows commandline + * @param envblock NUL-separated, double-NUL-terminated list of + * environment strings in VAR=VALUE form + * @param dir the working directory of the process, or null if + * inheriting the current directory from the parent process + * @param stdHandles array of windows HANDLEs. Indexes 0, 1, and + * 2 correspond to standard input, standard output and + * standard error, respectively. On input, a value of -1 + * means to create a pipe to connect child and parent + * processes. On output, a value which is not -1 is the + * parent pipe handle corresponding to the pipe which has + * been created. An element of this array is -1 on input + * if and only if it is not -1 on output. + * @param redirectErrorStream redirectErrorStream attribute + * @return the native subprocess HANDLE returned by CreateProcess + */ private static native long create(String cmdstr, String envblock, String dir, - boolean redirectErrorStream, - FileDescriptor in_fd, - FileDescriptor out_fd, - FileDescriptor err_fd) + long[] stdHandles, + boolean redirectErrorStream) throws IOException; private static native boolean closeHandle(long handle); diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c index 71113a7d5b4..f6a8cad4e4b 100644 --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c @@ -125,7 +125,7 @@ win32Error(JNIEnv *env, const char *functionName) static void closeSafely(HANDLE handle) { - if (handle) + if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle); } @@ -134,23 +134,22 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, jstring cmd, jstring envBlock, jstring dir, - jboolean redirectErrorStream, - jobject in_fd, - jobject out_fd, - jobject err_fd) + jlongArray stdHandles, + jboolean redirectErrorStream) { - HANDLE inRead = 0; - HANDLE inWrite = 0; - HANDLE outRead = 0; - HANDLE outWrite = 0; - HANDLE errRead = 0; - HANDLE errWrite = 0; + HANDLE inRead = INVALID_HANDLE_VALUE; + HANDLE inWrite = INVALID_HANDLE_VALUE; + HANDLE outRead = INVALID_HANDLE_VALUE; + HANDLE outWrite = INVALID_HANDLE_VALUE; + HANDLE errRead = INVALID_HANDLE_VALUE; + HANDLE errWrite = INVALID_HANDLE_VALUE; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; STARTUPINFO si; LPTSTR pcmd = NULL; LPCTSTR pdir = NULL; LPVOID penvBlock = NULL; + jlong *handles = NULL; jlong ret = 0; OSVERSIONINFO ver; jboolean onNT = JNI_FALSE; @@ -161,17 +160,6 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) onNT = JNI_TRUE; - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = 0; - sa.bInheritHandle = TRUE; - - if (!(CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE) && - CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE) && - CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE))) { - win32Error(env, "CreatePipe"); - goto Catch; - } - assert(cmd != NULL); pcmd = (LPTSTR) JNU_GetStringPlatformChars(env, cmd, NULL); if (pcmd == NULL) goto Catch; @@ -189,19 +177,62 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, if (penvBlock == NULL) goto Catch; } + assert(stdHandles != NULL); + handles = (*env)->GetLongArrayElements(env, stdHandles, NULL); + if (handles == NULL) goto Catch; + memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = inRead; - si.hStdOutput = outWrite; - si.hStdError = redirectErrorStream ? outWrite : errWrite; - SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE); - SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE); - SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE); + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = 0; + sa.bInheritHandle = TRUE; - if (redirectErrorStream) - SetHandleInformation(errWrite, HANDLE_FLAG_INHERIT, FALSE); + if (handles[0] != (jlong) -1) { + si.hStdInput = (HANDLE) handles[0]; + handles[0] = (jlong) -1; + } else { + if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) { + win32Error(env, "CreatePipe"); + goto Catch; + } + si.hStdInput = inRead; + SetHandleInformation(inWrite, HANDLE_FLAG_INHERIT, FALSE); + handles[0] = (jlong) inWrite; + } + SetHandleInformation(si.hStdInput, HANDLE_FLAG_INHERIT, TRUE); + + if (handles[1] != (jlong) -1) { + si.hStdOutput = (HANDLE) handles[1]; + handles[1] = (jlong) -1; + } else { + if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) { + win32Error(env, "CreatePipe"); + goto Catch; + } + si.hStdOutput = outWrite; + SetHandleInformation(outRead, HANDLE_FLAG_INHERIT, FALSE); + handles[1] = (jlong) outRead; + } + SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, TRUE); + + if (redirectErrorStream) { + si.hStdError = si.hStdOutput; + handles[2] = (jlong) -1; + } else if (handles[2] != (jlong) -1) { + si.hStdError = (HANDLE) handles[2]; + handles[2] = (jlong) -1; + } else { + if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) { + win32Error(env, "CreatePipe"); + goto Catch; + } + si.hStdError = errWrite; + SetHandleInformation(errRead, HANDLE_FLAG_INHERIT, FALSE); + handles[2] = (jlong) errRead; + } + SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE); if (onNT) processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; @@ -237,9 +268,6 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, CloseHandle(pi.hThread); ret = (jlong)pi.hProcess; - (*env)->SetLongField(env, in_fd, IO_handle_fdID, (jlong)inWrite); - (*env)->SetLongField(env, out_fd, IO_handle_fdID, (jlong)outRead); - (*env)->SetLongField(env, err_fd, IO_handle_fdID, (jlong)errRead); Finally: /* Always clean up the child's side of the pipes */ @@ -257,6 +285,9 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, else JNU_ReleaseStringPlatformChars(env, dir, (char *) penvBlock); } + if (handles != NULL) + (*env)->ReleaseLongArrayElements(env, stdHandles, handles, 0); + return ret; Catch: diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index 4a57ad94ba6..b0bfe12f250 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -25,12 +25,15 @@ * @test * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689 * 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313 - * 6464154 6523983 6206031 + * 6464154 6523983 6206031 4960438 6631352 6631966 * @summary Basic tests for Process and Environment Variable code * @run main/othervm Basic * @author Martin Buchholz */ +import java.lang.ProcessBuilder.Redirect; +import static java.lang.ProcessBuilder.Redirect.*; + import java.io.*; import java.util.*; import java.security.*; @@ -257,7 +260,29 @@ public class Basic { public static class JavaChild { public static void main(String args[]) throws Throwable { String action = args[0]; - if (action.equals("System.getenv(String)")) { + if (action.equals("testIO")) { + String expected = "standard input"; + char[] buf = new char[expected.length()+1]; + int n = new InputStreamReader(System.in).read(buf,0,buf.length); + if (n != expected.length()) + System.exit(5); + if (! new String(buf,0,n).equals(expected)) + System.exit(5); + System.err.print("standard error"); + System.out.print("standard output"); + } else if (action.equals("testInheritIO")) { + List childArgs = new ArrayList(javaChildArgs); + childArgs.add("testIO"); + ProcessBuilder pb = new ProcessBuilder(childArgs); + pb.inheritIO(); + ProcessResults r = run(pb); + if (! r.out().equals("")) + System.exit(7); + if (! r.err().equals("")) + System.exit(8); + if (r.exitValue() != 0) + System.exit(9); + } else if (action.equals("System.getenv(String)")) { String val = System.getenv(args[1]); printUTF8(val == null ? "null" : val); } else if (action.equals("System.getenv(\\u1234)")) { @@ -599,6 +624,333 @@ public class Basic { } catch (Throwable t) { unexpected(t); } } + static void checkRedirects(ProcessBuilder pb, + Redirect in, Redirect out, Redirect err) { + equal(pb.redirectInput(), in); + equal(pb.redirectOutput(), out); + equal(pb.redirectError(), err); + } + + static void redirectIO(ProcessBuilder pb, + Redirect in, Redirect out, Redirect err) { + pb.redirectInput(in); + pb.redirectOutput(out); + pb.redirectError(err); + } + + static void setFileContents(File file, String contents) { + try { + Writer w = new FileWriter(file); + w.write(contents); + w.close(); + } catch (Throwable t) { unexpected(t); } + } + + static String fileContents(File file) { + try { + Reader r = new FileReader(file); + StringBuilder sb = new StringBuilder(); + char[] buffer = new char[1024]; + int n; + while ((n = r.read(buffer)) != -1) + sb.append(buffer,0,n); + r.close(); + return new String(sb); + } catch (Throwable t) { unexpected(t); return ""; } + } + + static void testIORedirection() throws Throwable { + final File ifile = new File("ifile"); + final File ofile = new File("ofile"); + final File efile = new File("efile"); + ifile.delete(); + ofile.delete(); + efile.delete(); + + //---------------------------------------------------------------- + // Check mutual inequality of different types of Redirect + //---------------------------------------------------------------- + Redirect[] redirects = + { PIPE, + INHERIT, + Redirect.from(ifile), + Redirect.to(ifile), + Redirect.appendTo(ifile), + Redirect.from(ofile), + Redirect.to(ofile), + Redirect.appendTo(ofile), + }; + for (int i = 0; i < redirects.length; i++) + for (int j = 0; j < redirects.length; j++) + equal(redirects[i].equals(redirects[j]), (i == j)); + + //---------------------------------------------------------------- + // Check basic properties of different types of Redirect + //---------------------------------------------------------------- + equal(PIPE.type(), Redirect.Type.PIPE); + equal(PIPE.toString(), "PIPE"); + equal(PIPE.file(), null); + + equal(INHERIT.type(), Redirect.Type.INHERIT); + equal(INHERIT.toString(), "INHERIT"); + equal(INHERIT.file(), null); + + equal(Redirect.from(ifile).type(), Redirect.Type.READ); + equal(Redirect.from(ifile).toString(), + "redirect to read from file \"ifile\""); + equal(Redirect.from(ifile).file(), ifile); + equal(Redirect.from(ifile), + Redirect.from(ifile)); + equal(Redirect.from(ifile).hashCode(), + Redirect.from(ifile).hashCode()); + + equal(Redirect.to(ofile).type(), Redirect.Type.WRITE); + equal(Redirect.to(ofile).toString(), + "redirect to write to file \"ofile\""); + equal(Redirect.to(ofile).file(), ofile); + equal(Redirect.to(ofile), + Redirect.to(ofile)); + equal(Redirect.to(ofile).hashCode(), + Redirect.to(ofile).hashCode()); + + equal(Redirect.appendTo(ofile).type(), Redirect.Type.APPEND); + equal(Redirect.appendTo(efile).toString(), + "redirect to append to file \"efile\""); + equal(Redirect.appendTo(efile).file(), efile); + equal(Redirect.appendTo(efile), + Redirect.appendTo(efile)); + equal(Redirect.appendTo(efile).hashCode(), + Redirect.appendTo(efile).hashCode()); + + //---------------------------------------------------------------- + // Check initial values of redirects + //---------------------------------------------------------------- + List childArgs = new ArrayList(javaChildArgs); + childArgs.add("testIO"); + final ProcessBuilder pb = new ProcessBuilder(childArgs); + checkRedirects(pb, PIPE, PIPE, PIPE); + + //---------------------------------------------------------------- + // Check inheritIO + //---------------------------------------------------------------- + pb.inheritIO(); + checkRedirects(pb, INHERIT, INHERIT, INHERIT); + + //---------------------------------------------------------------- + // Check setters and getters agree + //---------------------------------------------------------------- + pb.redirectInput(ifile); + equal(pb.redirectInput().file(), ifile); + equal(pb.redirectInput(), Redirect.from(ifile)); + + pb.redirectOutput(ofile); + equal(pb.redirectOutput().file(), ofile); + equal(pb.redirectOutput(), Redirect.to(ofile)); + + pb.redirectError(efile); + equal(pb.redirectError().file(), efile); + equal(pb.redirectError(), Redirect.to(efile)); + + THROWS(IllegalArgumentException.class, + new Fun(){void f() { + pb.redirectInput(Redirect.to(ofile)); }}, + new Fun(){void f() { + pb.redirectInput(Redirect.appendTo(ofile)); }}, + new Fun(){void f() { + pb.redirectOutput(Redirect.from(ifile)); }}, + new Fun(){void f() { + pb.redirectError(Redirect.from(ifile)); }}); + + THROWS(IOException.class, + // Input file does not exist + new Fun(){void f() throws Throwable { pb.start(); }}); + setFileContents(ifile, "standard input"); + + //---------------------------------------------------------------- + // Writing to non-existent files + //---------------------------------------------------------------- + { + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Both redirectErrorStream + redirectError + //---------------------------------------------------------------- + { + pb.redirectErrorStream(true); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), + "standard error" + "standard output"); + equal(fileContents(efile), ""); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Appending to existing files + //---------------------------------------------------------------- + { + setFileContents(ofile, "ofile-contents"); + setFileContents(efile, "efile-contents"); + pb.redirectOutput(Redirect.appendTo(ofile)); + pb.redirectError(Redirect.appendTo(efile)); + pb.redirectErrorStream(false); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), + "ofile-contents" + "standard output"); + equal(fileContents(efile), + "efile-contents" + "standard error"); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Replacing existing files + //---------------------------------------------------------------- + { + setFileContents(ofile, "ofile-contents"); + setFileContents(efile, "efile-contents"); + pb.redirectOutput(ofile); + pb.redirectError(Redirect.to(efile)); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + equal(r.out(), ""); + equal(r.err(), ""); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Appending twice to the same file? + //---------------------------------------------------------------- + { + setFileContents(ofile, "ofile-contents"); + setFileContents(efile, "efile-contents"); + Redirect appender = Redirect.appendTo(ofile); + pb.redirectOutput(appender); + pb.redirectError(appender); + ProcessResults r = run(pb); + equal(r.exitValue(), 0); + equal(fileContents(ofile), + "ofile-contents" + + "standard error" + + "standard output"); + equal(fileContents(efile), "efile-contents"); + equal(r.out(), ""); + equal(r.err(), ""); + ifile.delete(); + ofile.delete(); + efile.delete(); + } + + //---------------------------------------------------------------- + // Testing INHERIT is harder. + // Note that this requires __FOUR__ nested JVMs involved in one test, + // if you count the harness JVM. + //---------------------------------------------------------------- + { + redirectIO(pb, PIPE, PIPE, PIPE); + List command = pb.command(); + command.set(command.size() - 1, "testInheritIO"); + Process p = pb.start(); + new PrintStream(p.getOutputStream()).print("standard input"); + p.getOutputStream().close(); + ProcessResults r = run(p); + equal(r.exitValue(), 0); + equal(r.out(), "standard output"); + equal(r.err(), "standard error"); + } + + //---------------------------------------------------------------- + // Test security implications of I/O redirection + //---------------------------------------------------------------- + + // Read access to current directory is always granted; + // So create a tmpfile for input instead. + final File tmpFile = File.createTempFile("Basic", "tmp"); + setFileContents(tmpFile, "standard input"); + + final Policy policy = new Policy(); + Policy.setPolicy(policy); + System.setSecurityManager(new SecurityManager()); + try { + final Permission xPermission + = new FilePermission("<>", "execute"); + final Permission rxPermission + = new FilePermission("<>", "read,execute"); + final Permission wxPermission + = new FilePermission("<>", "write,execute"); + final Permission rwxPermission + = new FilePermission("<>", "read,write,execute"); + + THROWS(SecurityException.class, + new Fun() { void f() throws IOException { + policy.setPermissions(xPermission); + redirectIO(pb, from(tmpFile), PIPE, PIPE); + pb.start();}}, + new Fun() { void f() throws IOException { + policy.setPermissions(rxPermission); + redirectIO(pb, PIPE, to(ofile), PIPE); + pb.start();}}, + new Fun() { void f() throws IOException { + policy.setPermissions(rxPermission); + redirectIO(pb, PIPE, PIPE, to(efile)); + pb.start();}}); + + { + policy.setPermissions(rxPermission); + redirectIO(pb, from(tmpFile), PIPE, PIPE); + ProcessResults r = run(pb); + equal(r.out(), "standard output"); + equal(r.err(), "standard error"); + } + + { + policy.setPermissions(wxPermission); + redirectIO(pb, PIPE, to(ofile), to(efile)); + Process p = pb.start(); + new PrintStream(p.getOutputStream()).print("standard input"); + p.getOutputStream().close(); + ProcessResults r = run(p); + policy.setPermissions(rwxPermission); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + } + + { + policy.setPermissions(rwxPermission); + redirectIO(pb, from(tmpFile), to(ofile), to(efile)); + ProcessResults r = run(pb); + policy.setPermissions(rwxPermission); + equal(fileContents(ofile), "standard output"); + equal(fileContents(efile), "standard error"); + } + + } finally { + policy.setPermissions(new RuntimePermission("setSecurityManager")); + System.setSecurityManager(null); + tmpFile.delete(); + ifile.delete(); + ofile.delete(); + efile.delete(); + } + } + private static void realMain(String[] args) throws Throwable { if (Windows.is()) System.out.println("This appears to be a Windows system."); @@ -607,6 +959,9 @@ public class Basic { if (UnicodeOS.is()) System.out.println("This appears to be a Unicode-based OS."); + try { testIORedirection(); } + catch (Throwable t) { unexpected(t); } + //---------------------------------------------------------------- // Basic tests for setting, replacing and deleting envvars //---------------------------------------------------------------- @@ -1354,7 +1709,8 @@ public class Basic { execPermission); ProcessBuilder pb = new ProcessBuilder("env"); pb.environment().put("foo","bar"); - pb.start(); + Process p = pb.start(); + closeStreams(p); } catch (IOException e) { // OK } catch (Throwable t) { unexpected(t); } @@ -1378,6 +1734,14 @@ public class Basic { } + static void closeStreams(Process p) { + try { + p.getOutputStream().close(); + p.getInputStream().close(); + p.getErrorStream().close(); + } catch (Throwable t) { unexpected(t); } + } + //---------------------------------------------------------------- // A Policy class designed to make permissions fiddling very easy. //---------------------------------------------------------------- @@ -1432,10 +1796,19 @@ public class Basic { } } catch (Throwable t) { throwable = t; + } finally { + try { is.close(); } + catch (Throwable t) { throwable = t; } } } } + static ProcessResults run(ProcessBuilder pb) { + try { + return run(pb.start()); + } catch (Throwable t) { unexpected(t); return null; } + } + private static ProcessResults run(Process p) { Throwable throwable = null; int exitValue = -1; From 4385dbf930a65e17f5fbe41f09421c0de1430f90 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:51 -0700 Subject: [PATCH 109/274] 6642034: System.getProperty("os.name") returns Windows Vista on Windows Server 2008 (longhorn) Reviewed-by: iris --- .../windows/native/java/lang/java_props_md.c | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/jdk/src/windows/native/java/lang/java_props_md.c b/jdk/src/windows/native/java/lang/java_props_md.c index ec0561c04e1..7c758e5a994 100644 --- a/jdk/src/windows/native/java/lang/java_props_md.c +++ b/jdk/src/windows/native/java/lang/java_props_md.c @@ -673,13 +673,13 @@ GetJavaProperties(JNIEnv* env) /* OS properties */ { char buf[100]; - OSVERSIONINFO ver; + OSVERSIONINFOEX ver; ver.dwOSVersionInfoSize = sizeof(ver); - GetVersionEx(&ver); + GetVersionEx((OSVERSIONINFO *) &ver); /* * From msdn page on OSVERSIONINFOEX, current as of this - * writing decoding of dwMajorVersion and dwMinorVersion. + * writing, decoding of dwMajorVersion and dwMinorVersion. * * Operating system dwMajorVersion dwMinorVersion * ================== ============== ============== @@ -692,7 +692,7 @@ GetJavaProperties(JNIEnv* env) * Windows 2000 5 0 * Windows XP 5 1 * Windows Server 2003 family 5 2 - * Windows Vista 6 0 + * Windows Vista family 6 0 * * This mapping will presumably be augmented as new Windows * versions are released. @@ -724,7 +724,20 @@ GetJavaProperties(JNIEnv* env) default: sprops.os_name = "Windows NT (unknown)"; break; } } else if (ver.dwMajorVersion == 6) { - sprops.os_name = "Windows Vista"; + /* + * From MSDN OSVERSIONINFOEX documentation: + * + * "Because the version numbers for Windows Server 2008 + * and Windows Vista are identical, you must also test + * whether the wProductType member is VER_NT_WORKSTATION. + * If wProductType is VER_NT_WORKSTATION, the operating + * system is Windows Vista; otherwise, it is Windows + * Server 2008." + */ + if (ver.wProductType == VER_NT_WORKSTATION) + sprops.os_name = "Windows Vista"; + else + sprops.os_name = "Windows Server 2008"; } else { sprops.os_name = "Windows NT (unknown)"; } From f3d6a3bd3b1d68a51ad1d27ca91b7d8e53aaf5ba Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 14:32:51 -0700 Subject: [PATCH 110/274] 6671051: (process) Runtime.exec() hangs if signalled during fork/exec Reviewed-by: iris --- .../solaris/native/java/lang/UNIXProcess_md.c | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c index 480298cde58..8390a2baad5 100644 --- a/jdk/src/solaris/native/java/lang/UNIXProcess_md.c +++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c @@ -479,6 +479,37 @@ closeSafely(int fd) close(fd); } +/* + * Reads nbyte bytes from file descriptor fd into buf, + * The read operation is retried in case of EINTR or partial reads. + * + * Returns number of bytes read (normally nbyte, but may be less in + * case of EOF). In case of read errors, returns -1 and sets errno. + */ +static ssize_t +readFully(int fd, void *buf, size_t nbyte) +{ + ssize_t remaining = nbyte; + for (;;) { + ssize_t n = read(fd, buf, remaining); + if (n == 0) { + return nbyte - remaining; + } else if (n > 0) { + remaining -= n; + if (remaining <= 0) + return nbyte; + /* We were interrupted in the middle of reading the bytes. + * Unlikely, but possible. */ + buf = (void *) (((char *)buf) + n); + } else if (errno == EINTR) { + /* Strange signals like SIGJVM1 are possible at any time. + * See http://www.dreamsongs.com/WorseIsBetter.html */ + } else { + return -1; + } + } +} + #ifndef __solaris__ #undef fork1 #define fork1() fork() @@ -606,10 +637,16 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env, /* parent process */ close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */ - if (read(fail[0], &errnum, sizeof(errnum)) != 0) { + + switch (readFully(fail[0], &errnum, sizeof(errnum))) { + case 0: break; /* Exec succeeded */ + case sizeof(errnum): waitpid(resultPid, NULL, 0); throwIOException(env, errnum, "Exec failed"); goto Catch; + default: + throwIOException(env, errno, "Read failed"); + goto Catch; } fds[0] = (in [1] != -1) ? in [1] : -1; From 4341094bebf4ae27ee43ac85a0c87538699ae5ea Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 15:07:09 -0700 Subject: [PATCH 111/274] 6600143: Remove another 450 unnecessary casts Reviewed-by: alanb, iris, lmalvent, bristor, peterjones, darcy, wetmore --- .../src/build/tools/jdwpgen/CommandNode.java | 8 +- .../build/tools/jdwpgen/ConstantSetNode.java | 2 +- .../src/build/tools/jdwpgen/RepeatNode.java | 2 +- .../example/debug/bdi/EventRequestSpec.java | 4 +- .../debug/bdi/EventRequestSpecList.java | 32 +-- .../example/debug/bdi/ExecutionManager.java | 37 ++-- .../example/debug/bdi/JDIEventSource.java | 4 +- .../example/debug/bdi/LineBreakpointSpec.java | 4 +- .../debug/bdi/MethodBreakpointSpec.java | 28 +-- .../debug/bdi/ThreadGroupIterator.java | 10 +- .../example/debug/bdi/ThreadIterator.java | 8 +- .../sun/tools/example/debug/expr/LValue.java | 52 +++-- .../example/debug/gui/ClassTreeTool.java | 4 +- .../example/debug/gui/CommandInterpreter.java | 75 +++---- .../example/debug/gui/JDBFileFilter.java | 6 +- .../tools/example/debug/gui/LaunchTool.java | 15 +- .../tools/example/debug/gui/SearchPath.java | 6 +- .../example/debug/gui/SourceManager.java | 6 +- .../tools/example/debug/gui/SourceModel.java | 17 +- .../example/debug/gui/StackTraceTool.java | 2 +- .../example/debug/gui/ThreadTreeTool.java | 20 +- .../example/debug/tty/BreakpointSpec.java | 32 ++- .../sun/tools/example/debug/tty/Commands.java | 202 ++++++------------ .../com/sun/tools/example/debug/tty/Env.java | 37 ++-- .../tools/example/debug/tty/EventHandler.java | 4 +- .../example/debug/tty/EventRequestSpec.java | 10 +- .../debug/tty/EventRequestSpecList.java | 22 +- .../tools/example/debug/tty/SourceMapper.java | 10 +- .../com/sun/tools/example/debug/tty/TTY.java | 24 +-- .../debug/tty/ThreadGroupIterator.java | 10 +- .../tools/example/debug/tty/ThreadInfo.java | 17 +- .../example/debug/tty/ThreadIterator.java | 8 +- .../tools/example/debug/tty/VMConnection.java | 12 +- .../tools/hat/internal/server/ClassQuery.java | 3 +- .../hat/internal/server/PlatformClasses.java | 4 +- .../com/sun/tools/jdi/AbstractLauncher.java | 2 +- .../com/sun/tools/jdi/ClassTypeImpl.java | 18 +- .../com/sun/tools/jdi/ConcreteMethodImpl.java | 8 +- .../com/sun/tools/jdi/EventSetImpl.java | 10 +- .../com/sun/tools/jdi/JNITypeParser.java | 4 +- .../classes/com/sun/tools/jdi/MethodImpl.java | 14 +- .../sun/tools/jdi/ObjectReferenceImpl.java | 4 +- .../com/sun/tools/jdi/PacketStream.java | 2 +- .../com/sun/tools/jdi/ReferenceTypeImpl.java | 36 ++-- .../share/classes/com/sun/tools/jdi/SDE.java | 2 +- .../com/sun/tools/jdi/StackFrameImpl.java | 4 +- .../classes/com/sun/tools/jdi/TargetVM.java | 2 +- .../tools/jdi/ThreadGroupReferenceImpl.java | 24 +-- .../com/sun/tools/jdi/VirtualMachineImpl.java | 5 +- .../tools/jdi/VirtualMachineManagerImpl.java | 4 +- .../classes/java/io/ObjectInputStream.java | 13 +- .../classes/java/io/ObjectStreamClass.java | 79 ++++--- jdk/src/share/classes/java/lang/Class.java | 119 +++++------ .../share/classes/java/lang/ClassLoader.java | 164 +++++++------- jdk/src/share/classes/java/lang/Compiler.java | 6 +- jdk/src/share/classes/java/lang/Long.java | 2 +- jdk/src/share/classes/java/lang/Package.java | 21 +- .../classes/java/lang/ref/Finalizer.java | 8 +- .../java/lang/reflect/AccessibleObject.java | 6 +- .../classes/java/lang/reflect/Modifier.java | 5 +- .../classes/java/lang/reflect/Proxy.java | 27 +-- .../classes/java/net/DatagramSocket.java | 5 +- .../share/classes/java/net/ServerSocket.java | 5 +- jdk/src/share/classes/java/net/Socket.java | 12 +- .../classes/java/net/SocksSocketImpl.java | 34 +-- .../classes/java/net/URLClassLoader.java | 36 ++-- .../nio/channels/spi/SelectorProvider.java | 6 +- .../rmi/activation/ActivationGroupDesc.java | 2 +- jdk/src/share/classes/java/rmi/dgc/VMID.java | 6 +- .../java/security/cert/TrustAnchor.java | 4 +- .../java/security/cert/X509CertSelector.java | 18 +- .../share/classes/java/util/ArrayList.java | 3 +- jdk/src/share/classes/java/util/Arrays.java | 8 +- jdk/src/share/classes/java/util/EnumMap.java | 8 +- .../classes/java/util/IdentityHashMap.java | 8 +- .../share/classes/java/util/JumboEnumSet.java | 2 +- jdk/src/share/classes/java/util/Random.java | 2 +- jdk/src/share/classes/java/util/TreeSet.java | 6 +- .../java/util/prefs/AbstractPreferences.java | 40 ++-- .../classes/java/util/regex/Matcher.java | 2 +- .../rmi/ssl/SslRMIClientSocketFactory.java | 4 +- .../rmi/ssl/SslRMIServerSocketFactory.java | 26 ++- .../auth/kerberos/KerberosTicket.java | 11 +- .../javax/security/auth/kerberos/KeyImpl.java | 4 +- .../sun/misc/ClassFileTransformer.java | 10 +- jdk/src/share/classes/sun/misc/Cleaner.java | 4 +- .../classes/sun/misc/ExtensionDependency.java | 24 +-- jdk/src/share/classes/sun/misc/GC.java | 16 +- jdk/src/share/classes/sun/misc/Launcher.java | 28 +-- .../classes/sun/misc/PerformanceLogger.java | 16 +- .../classes/sun/misc/ProxyGenerator.java | 31 +-- .../share/classes/sun/misc/URLClassPath.java | 58 ++--- .../share/classes/sun/net/NetProperties.java | 4 +- .../share/classes/sun/net/NetworkClient.java | 10 +- .../share/classes/sun/net/ftp/FtpClient.java | 10 +- .../sun/net/spi/DefaultProxySelector.java | 12 +- .../classes/sun/net/www/MessageHeader.java | 23 +- .../share/classes/sun/net/www/MimeTable.java | 41 ++-- .../classes/sun/net/www/http/HttpClient.java | 21 +- .../sun/net/www/http/KeepAliveCache.java | 43 ++-- .../sun/net/www/http/KeepAliveStream.java | 4 +- .../net/www/http/KeepAliveStreamCleaner.java | 20 +- .../www/protocol/ftp/FtpURLConnection.java | 9 +- .../www/protocol/http/HttpURLConnection.java | 102 ++++----- .../sun/net/www/protocol/jar/URLJarFile.java | 22 +- jdk/src/share/classes/sun/nio/ch/Reflect.java | 8 +- .../classes/sun/nio/ch/SocketAdaptor.java | 12 +- jdk/src/share/classes/sun/nio/ch/Util.java | 46 ++-- .../classes/sun/reflect/ClassDefiner.java | 6 +- .../sun/reflect/MethodAccessorGenerator.java | 9 +- .../sun/reflect/ReflectionFactory.java | 33 +-- .../AnnotationInvocationHandler.java | 4 +- .../classes/sun/reflect/misc/MethodUtil.java | 36 ++-- .../classes/sun/rmi/log/ReliableLog.java | 8 +- .../sun/rmi/registry/RegistryImpl.java | 23 +- .../classes/sun/rmi/rmic/RemoteClass.java | 33 +-- .../rmi/rmic/newrmic/jrmp/RemoteClass.java | 6 +- .../share/classes/sun/rmi/runtime/Log.java | 15 +- .../classes/sun/rmi/server/LoaderHandler.java | 39 ++-- .../sun/rmi/server/MarshalInputStream.java | 19 +- .../sun/rmi/server/MarshalOutputStream.java | 4 +- .../share/classes/sun/rmi/server/Util.java | 20 +- .../sun/rmi/server/WeakClassHashMap.java | 2 +- .../classes/sun/rmi/transport/DGCClient.java | 19 +- .../classes/sun/rmi/transport/Target.java | 6 +- .../classes/sun/rmi/transport/Transport.java | 6 +- .../sun/rmi/transport/proxy/CGIHandler.java | 4 +- .../rmi/transport/proxy/HttpSendSocket.java | 2 +- .../proxy/RMIMasterSocketFactory.java | 22 +- .../transport/tcp/ConnectionMultiplexer.java | 2 +- .../sun/security/jgss/GSSManagerImpl.java | 2 +- .../jgss/krb5/InitSecContextToken.java | 3 +- .../classes/sun/security/ssl/CipherSuite.java | 4 +- .../classes/sun/security/ssl/DHCrypt.java | 3 +- .../classes/sun/security/ssl/JsseJce.java | 3 +- .../sun/security/ssl/ProtocolList.java | 2 +- .../sun/security/ssl/SSLSessionImpl.java | 6 +- .../classes/sun/security/ssl/SessionId.java | 2 +- .../security/ssl/SunX509KeyManagerImpl.java | 6 +- .../security/x509/CertificatePolicySet.java | 2 +- .../classes/sun/security/x509/X509Cert.java | 2 +- .../sun/tools/jar/JarVerifierStream.java | 22 +- .../sun/tools/native2ascii/N2AFilter.java | 2 +- .../util/prefs/FileSystemPreferences.java | 88 ++++---- .../sun/nio/ch/DevPollArrayWrapper.java | 3 +- .../sun/security/provider/NativePRNG.java | 6 +- .../sun/security/mscapi/SunMSCAPI.java | 4 +- 147 files changed, 1215 insertions(+), 1415 deletions(-) diff --git a/jdk/make/tools/src/build/tools/jdwpgen/CommandNode.java b/jdk/make/tools/src/build/tools/jdwpgen/CommandNode.java index 4cdda4249cb..ec8666453ae 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/CommandNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/CommandNode.java @@ -32,9 +32,9 @@ class CommandNode extends AbstractCommandNode { void constrain(Context ctx) { if (components.size() == 3) { - Node out = (Node)components.get(0); - Node reply = (Node)components.get(1); - Node error = (Node)components.get(2); + Node out = components.get(0); + Node reply = components.get(1); + Node error = components.get(2); if (!(out instanceof OutNode)) { error("Expected 'Out' item, got: " + out); } @@ -45,7 +45,7 @@ class CommandNode extends AbstractCommandNode { error("Expected 'ErrorSet' item, got: " + error); } } else if (components.size() == 1) { - Node evt = (Node)components.get(0); + Node evt = components.get(0); if (!(evt instanceof EventNode)) { error("Expected 'Event' item, got: " + evt); } diff --git a/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java b/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java index 6d688dd7f72..325ebc9ef46 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java @@ -98,7 +98,7 @@ class ConstantSetNode extends AbstractNamedNode { if (constantMap == null) { return ""; } - String com = (String) constantMap.get(key); + String com = constantMap.get(key); if(com == null){ return ""; } else { diff --git a/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java b/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java index 40d4e0899bd..4c8f20982f2 100644 --- a/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java +++ b/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java @@ -37,7 +37,7 @@ class RepeatNode extends AbstractTypeNode { if (components.size() != 1) { error("Repeat must have exactly one member, use Group for more"); } - member = (Node)(components.get(0)); + member = components.get(0); if (!(member instanceof TypeNode)) { error("Repeat member must be type specifier"); } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java index 07b38826496..96a9ef5322b 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java @@ -91,9 +91,7 @@ abstract public class EventRequestSpec { void attemptImmediateResolve(VirtualMachine vm) { // try to resolve immediately - Iterator iter = vm.allClasses().iterator(); - while (iter.hasNext()) { - ReferenceType refType = (ReferenceType)iter.next(); + for (ReferenceType refType : vm.allClasses()) { if (refSpec.matches(refType)) { try { resolve(refType); diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java index dcc9b0c3517..e04c851f186 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java @@ -47,9 +47,8 @@ class EventRequestSpecList { */ void resolve(ReferenceType refType) { synchronized(eventRequestSpecs) { - Iterator iter = eventRequestSpecs.iterator(); - while (iter.hasNext()) { - ((EventRequestSpec)iter.next()).attemptResolve(refType); + for (EventRequestSpec spec : eventRequestSpecs) { + spec.attemptResolve(refType); } } } @@ -79,7 +78,7 @@ class EventRequestSpecList { BreakpointSpec createMethodBreakpoint(String classPattern, - String methodId, List methodArgs) { + String methodId, List methodArgs) { ReferenceTypeSpec refSpec = new PatternReferenceTypeSpec(classPattern); return new MethodBreakpointSpec(this, refSpec, @@ -132,47 +131,48 @@ class EventRequestSpecList { // -------- notify routines -------------------- - private Vector specListeners() { - return (Vector)runtime.specListeners.clone(); + @SuppressWarnings("unchecked") + private Vector specListeners() { + return (Vector)runtime.specListeners.clone(); } void notifySet(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifySet((SpecListener)l.elementAt(i), evt); + spec.notifySet(l.elementAt(i), evt); } } void notifyDeferred(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifyDeferred((SpecListener)l.elementAt(i), evt); + spec.notifyDeferred(l.elementAt(i), evt); } } void notifyDeleted(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifyDeleted((SpecListener)l.elementAt(i), evt); + spec.notifyDeleted(l.elementAt(i), evt); } } void notifyResolved(EventRequestSpec spec) { - Vector l = specListeners(); + Vector l = specListeners(); SpecEvent evt = new SpecEvent(spec); for (int i = 0; i < l.size(); i++) { - spec.notifyResolved((SpecListener)l.elementAt(i), evt); + spec.notifyResolved(l.elementAt(i), evt); } } void notifyError(EventRequestSpec spec, Exception exc) { - Vector l = specListeners(); + Vector l = specListeners(); SpecErrorEvent evt = new SpecErrorEvent(spec, exc); for (int i = 0; i < l.size(); i++) { - spec.notifyError((SpecListener)l.elementAt(i), evt); + spec.notifyError(l.elementAt(i), evt); } } } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java index e533bb54c83..245590ec7fd 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java @@ -232,10 +232,7 @@ public class ExecutionManager { if (pattern.startsWith("*.")) { // Wildcard matches any leading package name. pattern = pattern.substring(1); - List classes = vm().allClasses(); - Iterator iter = classes.iterator(); - while (iter.hasNext()) { - ReferenceType type = ((ReferenceType)iter.next()); + for (ReferenceType type : vm().allClasses()) { if (type.name().endsWith(pattern)) { result.add(type); } @@ -278,7 +275,7 @@ public class ExecutionManager { public ThreadGroupReference systemThreadGroup() throws NoSessionException { ensureActiveSession(); - return (ThreadGroupReference)vm().topLevelThreadGroups().get(0); + return vm().topLevelThreadGroups().get(0); } /* @@ -349,10 +346,9 @@ public class ExecutionManager { * attach sessions. */ VirtualMachineManager mgr = Bootstrap.virtualMachineManager(); - List connectors = mgr.attachingConnectors(); - AttachingConnector connector = (AttachingConnector)connectors.get(0); + AttachingConnector connector = mgr.attachingConnectors().get(0); Map arguments = connector.defaultArguments(); - ((Connector.Argument)arguments.get("port")).setValue(portName); + arguments.get("port").setValue(portName); Session newSession = internalAttach(connector, arguments); if (newSession != null) { @@ -504,10 +500,7 @@ public class ExecutionManager { * if so, it gets removed here. */ EventRequestManager mgr = vm().eventRequestManager(); - List requests = mgr.stepRequests(); - Iterator iter = requests.iterator(); - while (iter.hasNext()) { - StepRequest request = (StepRequest)iter.next(); + for (StepRequest request : mgr.stepRequests()) { if (request.thread().equals(thread)) { mgr.deleteEventRequest(request); break; @@ -591,7 +584,7 @@ public class ExecutionManager { if (session == null || thread == null) { return null; } - ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread); + ThreadInfo info = threadInfoMap.get(thread); if (info == null) { //### Should not hardcode initial frame count and prefetch here! //info = new ThreadInfo(thread, 10, 10); @@ -607,24 +600,22 @@ public class ExecutionManager { void validateThreadInfo() { session.interrupted = true; - Iterator iter = threadInfoList.iterator(); - while (iter.hasNext()) { - ((ThreadInfo)iter.next()).validate(); + for (ThreadInfo threadInfo : threadInfoList) { + threadInfo.validate(); } } private void invalidateThreadInfo() { if (session != null) { session.interrupted = false; - Iterator iter = threadInfoList.iterator(); - while (iter.hasNext()) { - ((ThreadInfo)iter.next()).invalidate(); + for (ThreadInfo threadInfo : threadInfoList) { + threadInfo.invalidate(); } } } void removeThreadInfo(ThreadReference thread) { - ThreadInfo info = (ThreadInfo)threadInfoMap.get(thread); + ThreadInfo info = threadInfoMap.get(thread); if (info != null) { info.invalidate(); threadInfoMap.remove(thread); @@ -702,7 +693,7 @@ public class ExecutionManager { while (inputBuffer.size() < 1) { inputLock.wait(); } - line = (String)inputBuffer.removeLast(); + line = inputBuffer.removeLast(); } catch (InterruptedException e) {} } } @@ -774,7 +765,7 @@ public class ExecutionManager { public BreakpointSpec createMethodBreakpoint(String classPattern, - String methodId, List methodArgs) { + String methodId, List methodArgs) { return specList.createMethodBreakpoint(classPattern, methodId, methodArgs); } @@ -811,7 +802,7 @@ public class ExecutionManager { specList.install(spec, vm()); } - public List eventRequestSpecs() { + public List eventRequestSpecs() { return specList.eventRequestSpecs(); } } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java index 2bd45c2fc38..97fc6a7f2b0 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java @@ -82,9 +82,7 @@ class JDIEventSource extends Thread { boolean interrupted = es.suspendedAll(); es.notify(firstListener); boolean wantInterrupt = JDIEventSource.this.wantInterrupt; - for (Iterator it = session.runtime.jdiListeners.iterator(); - it.hasNext(); ) { - JDIListener jl = (JDIListener)it.next(); + for (JDIListener jl : session.runtime.jdiListeners) { es.notify(jl); } if (interrupted && !wantInterrupt) { diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java index 0d9c0cc05dd..29f05ced6b7 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java @@ -58,12 +58,12 @@ public class LineBreakpointSpec extends BreakpointSpec { LineNotFoundException { Location location = null; try { - List locs = clazz.locationsOfLine(lineNumber()); + List locs = clazz.locationsOfLine(lineNumber()); if (locs.size() == 0) { throw new LineNotFoundException(); } // TODO handle multiple locations - location = (Location)locs.get(0); + location = locs.get(0); if (location.method() == null) { throw new LineNotFoundException(); } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java index 6a4f5e5a263..0732ed9c2c1 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java @@ -34,11 +34,11 @@ import java.util.Iterator; public class MethodBreakpointSpec extends BreakpointSpec { String methodId; - List methodArgs; + List methodArgs; MethodBreakpointSpec(EventRequestSpecList specs, ReferenceTypeSpec refSpec, - String methodId, List methodArgs) { + String methodId, List methodArgs) { super(specs, refSpec); this.methodId = methodId; this.methodArgs = methodArgs; @@ -76,7 +76,7 @@ public class MethodBreakpointSpec extends BreakpointSpec { return methodId; } - public List methodArgs() { + public List methodArgs() { return methodArgs; } @@ -120,14 +120,13 @@ public class MethodBreakpointSpec extends BreakpointSpec { buffer.append('.'); buffer.append(methodId); if (methodArgs != null) { - Iterator iter = methodArgs.iterator(); boolean first = true; buffer.append('('); - while (iter.hasNext()) { + for (String name : methodArgs) { if (!first) { buffer.append(','); } - buffer.append((String)iter.next()); + buffer.append(name); first = false; } buffer.append(")"); @@ -151,8 +150,8 @@ public class MethodBreakpointSpec extends BreakpointSpec { * and if the number of arguments in the method matches the * number of names passed */ - private boolean compareArgTypes(Method method, List nameList) { - List argTypeNames = method.argumentTypeNames(); + private boolean compareArgTypes(Method method, List nameList) { + List argTypeNames = method.argumentTypeNames(); // If argument counts differ, we can stop here if (argTypeNames.size() != nameList.size()) { @@ -162,8 +161,8 @@ public class MethodBreakpointSpec extends BreakpointSpec { // Compare each argument type's name int nTypes = argTypeNames.size(); for (int i = 0; i < nTypes; ++i) { - String comp1 = (String)argTypeNames.get(i); - String comp2 = (String)nameList.get(i); + String comp1 = argTypeNames.get(i); + String comp2 = nameList.get(i); if (! comp1.equals(comp2)) { /* * We have to handle varargs. EG, the @@ -288,22 +287,17 @@ public class MethodBreakpointSpec extends BreakpointSpec { List argTypeNames = null; if (methodArgs() != null) { argTypeNames = new ArrayList(methodArgs().size()); - Iterator iter = methodArgs().iterator(); - while (iter.hasNext()) { - String name = (String)iter.next(); + for (String name : methodArgs()) { name = normalizeArgTypeName(name); argTypeNames.add(name); } } // Check each method in the class for matches - Iterator iter = clazz.methods().iterator(); Method firstMatch = null; // first method with matching name Method exactMatch = null; // (only) method with same name & sig int matchCount = 0; // > 1 implies overload - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); - + for (Method candidate : clazz.methods()) { if (candidate.name().equals(methodName())) { matchCount++; diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java index d9b375cfde8..d41901320dd 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java @@ -36,7 +36,7 @@ import java.util.Iterator; * Descend the tree of thread groups. * @author Robert G. Field */ -public class ThreadGroupIterator implements Iterator { +public class ThreadGroupIterator implements Iterator { private final Stack> stack = new Stack>(); @@ -56,8 +56,8 @@ public class ThreadGroupIterator implements Iterator { } */ - private Iterator top() { - return (Iterator)stack.peek(); + private Iterator top() { + return stack.peek(); } /** @@ -77,12 +77,12 @@ public class ThreadGroupIterator implements Iterator { return !stack.isEmpty(); } - public Object next() { + public ThreadGroupReference next() { return nextThreadGroup(); } public ThreadGroupReference nextThreadGroup() { - ThreadGroupReference tg = (ThreadGroupReference)top().next(); + ThreadGroupReference tg = top().next(); push(tg.threadGroups()); return tg; } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java index 36b71e46023..bfe57d14a92 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java @@ -30,8 +30,8 @@ import com.sun.jdi.ThreadReference; import java.util.List; import java.util.Iterator; -public class ThreadIterator implements Iterator { - Iterator it = null; +public class ThreadIterator implements Iterator { + Iterator it = null; ThreadGroupIterator tgi; public ThreadIterator(ThreadGroupReference tg) { @@ -53,12 +53,12 @@ public class ThreadIterator implements Iterator { return true; } - public Object next() { + public ThreadReference next() { return it.next(); } public ThreadReference nextThread() { - return (ThreadReference)next(); + return next(); } public void remove() { diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java b/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java index 6b65e0c57a2..ae9711d9f09 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java @@ -191,11 +191,12 @@ abstract class LValue { return field; } - static List methodsByName(ReferenceType refType, String name, int kind) { - List list = refType.methodsByName(name); - Iterator iter = list.iterator(); + static List methodsByName(ReferenceType refType, + String name, int kind) { + List list = refType.methodsByName(name); + Iterator iter = list.iterator(); while (iter.hasNext()) { - Method method = (Method)iter.next(); + Method method = iter.next(); boolean isStatic = method.isStatic(); if (((kind == STATIC) && !isStatic) || ((kind == INSTANCE) && isStatic)) { @@ -231,21 +232,21 @@ abstract class LValue { * argType is not assignable from the type of the argument value. * IE, one is an Apple and the other is an Orange. */ - static int argumentsMatch(List argTypes, List arguments) { + static int argumentsMatch(List argTypes, List arguments) { if (argTypes.size() != arguments.size()) { return DIFFERENT; } - Iterator typeIter = argTypes.iterator(); - Iterator valIter = arguments.iterator(); + Iterator typeIter = argTypes.iterator(); + Iterator valIter = arguments.iterator(); int result = SAME; // If any pair aren't the same, change the // result to ASSIGNABLE. If any pair aren't // assignable, return DIFFERENT while (typeIter.hasNext()) { - Type argType = (Type)typeIter.next(); - Value value = (Value)valIter.next(); + Type argType = typeIter.next(); + Value value = valIter.next(); if (value == null) { // Null values can be passed to any non-primitive argument if (primitiveTypeNames.contains(argType.name())) { @@ -333,7 +334,7 @@ abstract class LValue { if (fromType instanceof ArrayType) { return isArrayAssignableTo((ArrayType)fromType, toType); } - List interfaces; + List interfaces; if (fromType instanceof ClassType) { ClassType superclazz = ((ClassType)fromType).superclass(); if ((superclazz != null) && isAssignableTo(superclazz, toType)) { @@ -344,9 +345,7 @@ abstract class LValue { // fromType must be an InterfaceType interfaces = ((InterfaceType)fromType).superinterfaces(); } - Iterator iter = interfaces.iterator(); - while (iter.hasNext()) { - InterfaceType interfaze = (InterfaceType)iter.next(); + for (InterfaceType interfaze : interfaces) { if (isAssignableTo(interfaze, toType)) { return true; } @@ -354,7 +353,8 @@ abstract class LValue { return false; } - static Method resolveOverload(List overloads, List arguments) + static Method resolveOverload(List overloads, + List arguments) throws ParseException { // If there is only one method to call, we'll just choose @@ -362,7 +362,7 @@ abstract class LValue { // the invoke will return a better error message than we // could generate here. if (overloads.size() == 1) { - return (Method)overloads.get(0); + return overloads.get(0); } // Resolving overloads is beyond the scope of this exercise. @@ -374,12 +374,10 @@ abstract class LValue { // methods to call. And, since casts aren't implemented, // the user can't use them to pick a particular overload to call. // IE, the user is out of luck in this case. - Iterator iter = overloads.iterator(); Method retVal = null; int assignableCount = 0; - while (iter.hasNext()) { - Method mm = (Method)iter.next(); - List argTypes; + for (Method mm : overloads) { + List argTypes; try { argTypes = mm.argumentTypes(); } catch (ClassNotLoadedException ee) { @@ -443,7 +441,7 @@ abstract class LValue { final ObjectReference obj; final ThreadReference thread; final Field matchingField; - final List overloads; + final List overloads; Method matchingMethod = null; List methodArguments = null; @@ -510,7 +508,7 @@ abstract class LValue { final ReferenceType refType; final ThreadReference thread; final Field matchingField; - final List overloads; + final List overloads; Method matchingMethod = null; List methodArguments = null; @@ -765,7 +763,7 @@ abstract class LValue { static LValue makeNewObject(VirtualMachine vm, ExpressionParser.GetFrame frameGetter, String className, List arguments) throws ParseException { - List classes = vm.classesByName(className); + List classes = vm.classesByName(className); if (classes.size() == 0) { throw new ParseException("No class named: " + className); } @@ -774,7 +772,7 @@ abstract class LValue { throw new ParseException("More than one class named: " + className); } - ReferenceType refType = (ReferenceType)classes.get(0); + ReferenceType refType = classes.get(0); if (!(refType instanceof ClassType)) { @@ -784,9 +782,9 @@ abstract class LValue { ClassType classType = (ClassType)refType; List methods = new ArrayList(classType.methods()); // writable - Iterator iter = methods.iterator(); + Iterator iter = methods.iterator(); while (iter.hasNext()) { - Method method = (Method)iter.next(); + Method method = iter.next(); if (!method.isConstructor()) { iter.remove(); } @@ -858,13 +856,13 @@ abstract class LValue { } // check for class name while (izer.hasMoreTokens()) { - List classes = vm.classesByName(first); + List classes = vm.classesByName(first); if (classes.size() > 0) { if (classes.size() > 1) { throw new ParseException("More than one class named: " + first); } else { - ReferenceType refType = (ReferenceType)classes.get(0); + ReferenceType refType = classes.get(0); LValue lval = new LValueStaticMember(refType, izer.nextToken(), thread); return nFields(lval, izer, thread); diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java index 6ddb558c4f2..bea3a2745e7 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java @@ -124,9 +124,7 @@ public class ClassTreeTool extends JPanel { public void sessionStart(EventObject e) { // Get system classes and any others loaded before attaching. try { - Iterator iter = runtime.allClasses().iterator(); - while (iter.hasNext()) { - ReferenceType type = ((ReferenceType)iter.next()); + for (ReferenceType type : runtime.allClasses()) { root.addClass(type); } } catch (VMDisconnectedException ee) { diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java index e0f96e01316..7b6aaf54695 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java @@ -77,7 +77,7 @@ public class CommandInterpreter { while (ti.hasNext()) { tlist.add(ti.nextThread()); } - threads = (ThreadReference[])tlist.toArray(new ThreadReference[tlist.size()]); + threads = tlist.toArray(new ThreadReference[tlist.size()]); } return threads; } @@ -146,11 +146,9 @@ public class CommandInterpreter { // Command: classes private void commandClasses() throws NoSessionException { - List list = runtime.allClasses(); OutputSink out = env.getOutputSink(); //out.println("** classes list **"); - for (int i = 0 ; i < list.size() ; i++) { - ReferenceType refType = (ReferenceType)list.get(i); + for (ReferenceType refType : runtime.allClasses()) { out.println(refType.name()); } out.show(); @@ -167,16 +165,16 @@ public class CommandInterpreter { String idClass = t.nextToken(); ReferenceType cls = findClass(idClass); if (cls != null) { - List methods = cls.allMethods(); + List methods = cls.allMethods(); OutputSink out = env.getOutputSink(); for (int i = 0; i < methods.size(); i++) { - Method method = (Method)methods.get(i); + Method method = methods.get(i); out.print(method.declaringType().name() + " " + method.name() + "("); - Iterator it = method.argumentTypeNames().iterator(); + Iterator it = method.argumentTypeNames().iterator(); if (it.hasNext()) { while (true) { - out.print((String)it.next()); + out.print(it.next()); if (!it.hasNext()) { break; } @@ -193,10 +191,10 @@ public class CommandInterpreter { } private ReferenceType findClass(String pattern) throws NoSessionException { - List results = runtime.findClassesMatchingPattern(pattern); + List results = runtime.findClassesMatchingPattern(pattern); if (results.size() > 0) { //### Should handle multiple results sensibly. - return (ReferenceType)results.get(0); + return results.get(0); } return null; } @@ -235,11 +233,11 @@ public class CommandInterpreter { private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) { out.println("Group " + tg.name() + ":"); - List tlist = tg.threads(); + List tlist = tg.threads(); int maxId = 0; int maxName = 0; for (int i = 0 ; i < tlist.size() ; i++) { - ThreadReference thr = (ThreadReference)tlist.get(i); + ThreadReference thr = tlist.get(i); int len = Utils.description(thr).length(); if (len > maxId) maxId = len; @@ -254,7 +252,7 @@ public class CommandInterpreter { String maxNumString = String.valueOf(iThread + tlist.size()); int maxNumDigits = maxNumString.length(); for (int i = 0 ; i < tlist.size() ; i++) { - ThreadReference thr = (ThreadReference)tlist.get(i); + ThreadReference thr = tlist.get(i); char buf[] = new char[80]; for (int j = 0; j < 79; j++) { buf[j] = ' '; @@ -283,9 +281,7 @@ public class CommandInterpreter { sbOut.setLength(79); out.println(sbOut.toString()); } - List tglist = tg.threadGroups(); - for (int ig = 0; ig < tglist.size(); ig++) { - ThreadGroupReference tg0 = (ThreadGroupReference)tglist.get(ig); + for (ThreadGroupReference tg0 : tg.threadGroups()) { if (!tg.equals(tg0)) { // TODO ref mgt iThread += printThreadGroup(out, tg0, iThread + tlist.size()); } @@ -733,7 +729,7 @@ public class CommandInterpreter { if (token.toLowerCase().equals("all")) { ThreadIterator it = allThreads(); while (it.hasNext()) { - ThreadReference thread = (ThreadReference)it.next(); + ThreadReference thread = it.next(); out.println(thread.name() + ": "); dumpStack(thread, showPC); } @@ -755,7 +751,7 @@ public class CommandInterpreter { //env.failure("Target VM must be in interrupted state."); //env.failure("Current thread isn't suspended."); //### Should handle extremely long stack traces sensibly for user. - List stack = null; + List stack = null; try { stack = thread.frames(); } catch (IncompatibleThreadStateException e) { @@ -772,7 +768,7 @@ public class CommandInterpreter { OutputSink out = env.getOutputSink(); int nFrames = stack.size(); for (int i = frameIndex; i < nFrames; i++) { - StackFrame frame = (StackFrame)stack.get(i); + StackFrame frame = stack.get(i); Location loc = frame.location(); Method meth = loc.method(); out.print(" [" + (i + 1) + "] "); @@ -780,7 +776,7 @@ public class CommandInterpreter { out.print('.'); out.print(meth.name()); out.print(" ("); - if (meth instanceof Method && ((Method)meth).isNative()) { + if (meth.isNative()) { out.print("native method"); } else if (loc.lineNumber() != -1) { try { @@ -806,14 +802,13 @@ public class CommandInterpreter { private void listEventRequests() throws NoSessionException { // Print set breakpoints - Iterator iter = runtime.eventRequestSpecs().iterator(); - if (!iter.hasNext()) { + List specs = runtime.eventRequestSpecs(); + if (specs.isEmpty()) { env.notice("No breakpoints/watchpoints/exceptions set."); } else { OutputSink out = env.getOutputSink(); out.println("Current breakpoints/watchpoints/exceptions set:"); - while (iter.hasNext()) { - EventRequestSpec bp = (EventRequestSpec)iter.next(); + for (EventRequestSpec bp : specs) { out.println("\t" + bp); } out.show(); @@ -926,13 +921,13 @@ public class CommandInterpreter { //### need 'clear all' BreakpointSpec bpSpec = parseBreakpointSpec(t.nextToken()); if (bpSpec != null) { - Iterator iter = runtime.eventRequestSpecs().iterator(); - if (!iter.hasNext()) { + List specs = runtime.eventRequestSpecs(); + + if (specs.isEmpty()) { env.notice("No breakpoints set."); } else { - List toDelete = new ArrayList(); - while (iter.hasNext()) { - BreakpointSpec spec = (BreakpointSpec)iter.next(); + List toDelete = new ArrayList(); + for (EventRequestSpec spec : specs) { if (spec.equals(bpSpec)) { toDelete.add(spec); } @@ -941,7 +936,7 @@ public class CommandInterpreter { if (toDelete.size() <= 1) { env.notice("No matching breakpoint set."); } - for (BreakpointSpec spec : toDelete) { + for (EventRequestSpec spec : toDelete) { runtime.delete(spec); } } @@ -988,7 +983,7 @@ public class CommandInterpreter { lineno = Integer.valueOf(id).intValue(); } catch (NumberFormatException nfe) { // It isn't -- see if it's a method name. - List meths = refType.methodsByName(id); + List meths = refType.methodsByName(id); if (meths == null || meths.size() == 0) { env.failure(id + " is not a valid line number or " + @@ -1001,7 +996,7 @@ public class CommandInterpreter { refType.name()); return; } - loc = ((Method)meths.get(0)).location(); + loc = meths.get(0).location(); lineno = loc.lineNumber(); } } @@ -1121,7 +1116,7 @@ public class CommandInterpreter { return; } - List vars; + List vars; try { vars = frame.visibleVariables(); if (vars == null || vars.size() == 0) { @@ -1136,15 +1131,13 @@ public class CommandInterpreter { OutputSink out = env.getOutputSink(); out.println("Method arguments:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (var.isArgument()) { printVar(out, var, frame); } } out.println("Local variables:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (!var.isArgument()) { printVar(out, var, frame); } @@ -1245,8 +1238,7 @@ public class CommandInterpreter { private void dump(OutputSink out, ObjectReference obj, ReferenceType refType, ReferenceType refTypeBase) { - for (Iterator it = refType.fields().iterator(); it.hasNext(); ) { - Field field = (Field)it.next(); + for (Field field : refType.fields()) { out.print(" "); if (!refType.equals(refTypeBase)) { out.print(refType.name() + "."); @@ -1261,9 +1253,8 @@ public class CommandInterpreter { dump(out, obj, sup, refTypeBase); } } else if (refType instanceof InterfaceType) { - List sups = ((InterfaceType)refType).superinterfaces(); - for (Iterator it = sups.iterator(); it.hasNext(); ) { - dump(out, obj, (ReferenceType)it.next(), refTypeBase); + for (InterfaceType sup : ((InterfaceType)refType).superinterfaces()) { + dump(out, obj, sup, refTypeBase); } } } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java index ddb71921dc1..5963ef2e0df 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java @@ -201,11 +201,11 @@ public class JDBFileFilter extends FileFilter { if(description == null || isExtensionListInDescription()) { fullDescription = description==null ? "(" : description + " ("; // build the description from the extension list - Enumeration extensions = filters.keys(); + Enumeration extensions = filters.keys(); if(extensions != null) { - fullDescription += "." + (String) extensions.nextElement(); + fullDescription += "." + extensions.nextElement(); while (extensions.hasMoreElements()) { - fullDescription += ", " + (String) extensions.nextElement(); + fullDescription += ", " + extensions.nextElement(); } } fullDescription += ")"; diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java index 7aed53869e1..fc115b9078e 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java @@ -131,14 +131,13 @@ class LaunchTool { final JPanel radioPanel = new JPanel(); final ButtonGroup radioGroup = new ButtonGroup(); VirtualMachineManager manager = Bootstrap.virtualMachineManager(); - List all = manager.allConnectors(); + List all = manager.allConnectors(); Map modelToConnector = new HashMap(all.size(), 0.5f); dialog.setModal(true); dialog.setTitle("Select Connector Type"); radioPanel.setLayout(new BoxLayout(radioPanel, BoxLayout.Y_AXIS)); - for (Iterator it = all.iterator(); it.hasNext(); ) { - Connector connector = (Connector)it.next(); + for (Connector connector : all) { JRadioButton radio = new JRadioButton(connector.description()); modelToConnector.put(radio.getModel(), connector); radioPanel.add(radio); @@ -166,7 +165,7 @@ class LaunchTool { dialog.show(); return oked[0] ? - (Connector)(modelToConnector.get(radioGroup.getSelection())) : + modelToConnector.get(radioGroup.getSelection()) : null; } @@ -188,13 +187,12 @@ class LaunchTool { // guts.add(new JLabel(connector.description())); final List argReps = new ArrayList(args.size()); - for (Iterator it = args.values().iterator(); it.hasNext(); ) { - Object arg = it.next(); + for (Connector.Argument arg : args.values()) { ArgRep ar; if (arg instanceof Connector.BooleanArgument) { ar = new BooleanArgRep((Connector.BooleanArgument)arg, guts); } else { - ar = new StringArgRep((Connector.Argument)arg, guts); + ar = new StringArgRep(arg, guts); } argReps.add(ar); } @@ -202,8 +200,7 @@ class LaunchTool { JPanel buttonPanel = okCancel( dialog, new ActionListener() { public void actionPerformed(ActionEvent event) { - for (Iterator it = argReps.iterator(); it.hasNext(); ) { - ArgRep ar = (ArgRep)it.next(); + for (ArgRep ar : argReps) { if (!ar.isSpecified()) { JOptionPane.showMessageDialog(dialog, ar.arg.label() + diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java index 45f7ac7eb4d..1d61c8fa068 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java @@ -42,7 +42,7 @@ public class SearchPath { dlist.add(st.nextToken()); } pathString = searchPath; - pathArray = (String[])dlist.toArray(new String[dlist.size()]); + pathArray = dlist.toArray(new String[dlist.size()]); } public boolean isEmpty() { @@ -54,7 +54,7 @@ public class SearchPath { } public String[] asArray() { - return (String[])pathArray.clone(); + return pathArray.clone(); } public File resolve(String relativeFileName) { @@ -89,7 +89,7 @@ public class SearchPath { } } } - return (String[])s.toArray(new String[s.size()]); + return s.toArray(new String[s.size()]); } } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java index 56667100dd1..7173b5f1014 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java @@ -113,7 +113,7 @@ public class SourceManager { * Returns null if not available. */ public SourceModel sourceForClass(ReferenceType refType) { - SourceModel sm = (SourceModel)classToSource.get(refType); + SourceModel sm = classToSource.get(refType); if (sm != null) { return sm; } @@ -140,10 +140,10 @@ public class SourceManager { */ //### Use hash table for this? public SourceModel sourceForFile(File path) { - Iterator iter = sourceList.iterator(); + Iterator iter = sourceList.iterator(); SourceModel sm = null; while (iter.hasNext()) { - SourceModel candidate = (SourceModel)iter.next(); + SourceModel candidate = iter.next(); if (candidate.fileName().equals(path)) { sm = candidate; iter.remove(); // Will move to start of list. diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java index 6bb1e551e42..75cdca6857d 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java @@ -187,22 +187,17 @@ public class SourceModel extends AbstractListModel { * when sourceLines is set. */ private void markClassLines(ReferenceType refType) { - List methods = refType.methods(); - for (Iterator mit = methods.iterator(); mit.hasNext();) { - Method meth = (Method)mit.next(); + for (Method meth : refType.methods()) { try { - List lines = meth.allLineLocations(); - for (Iterator lit = lines.iterator(); lit.hasNext();) { - Location loc = (Location)lit.next(); + for (Location loc : meth.allLineLocations()) { showExecutable(loc.lineNumber(), refType); } } catch (AbsentInformationException exc) { // do nothing } } - List bps = env.getExecutionManager().eventRequestManager().breakpointRequests(); - for (Iterator it = bps.iterator(); it.hasNext();) { - BreakpointRequest bp = (BreakpointRequest)it.next(); + for (BreakpointRequest bp : + env.getExecutionManager().eventRequestManager().breakpointRequests()) { if (bp.location() != null) { Location loc = bp.location(); if (loc.declaringType().equals(refType)) { @@ -224,8 +219,8 @@ public class SourceModel extends AbstractListModel { } finally { reader.close(); } - for (Iterator it = classes.iterator(); it.hasNext();) { - markClassLines((ClassType)it.next()); + for (ReferenceType refType : classes) { + markClassLines(refType); } } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java index 7f4c857895a..78476f0d98b 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java @@ -139,7 +139,7 @@ public class StackTraceTool extends JPanel { String methName = meth.declaringType().name() + '.' + meth.name(); String position = ""; - if (meth instanceof Method && ((Method)meth).isNative()) { + if (meth.isNative()) { position = " (native method)"; } else if (loc.lineNumber() != -1) { position = ":" + loc.lineNumber(); diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java b/jdk/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java index 3b6d5fc4181..955c5b6cbc1 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java @@ -133,9 +133,7 @@ public class ThreadTreeTool extends JPanel { public void sessionStart(EventObject e) { try { - Iterator iter = runtime.allThreads().iterator(); - while (iter.hasNext()) { - ThreadReference thread = ((ThreadReference)iter.next()); + for (ThreadReference thread : runtime.allThreads()) { root.addThread(thread); } } catch (VMDisconnectedException ee) { @@ -244,16 +242,16 @@ public class ThreadTreeTool extends JPanel { } } - private void addThread(List threadPath, ThreadReference thread) { + private void addThread(List threadPath, ThreadReference thread) { int size = threadPath.size(); if (size == 0) { return; } else if (size == 1) { - String name = (String)threadPath.get(0); + String name = threadPath.get(0); insertNode(name, thread); } else { - String head = (String)threadPath.get(0); - List tail = threadPath.subList(1, size); + String head = threadPath.get(0); + List tail = threadPath.subList(1, size); ThreadTreeNode child = insertNode(head, null); child.addThread(tail, thread); } @@ -288,17 +286,17 @@ public class ThreadTreeTool extends JPanel { } } - private void removeThread(List threadPath, ThreadReference thread) { + private void removeThread(List threadPath, ThreadReference thread) { int size = threadPath.size(); if (size == 0) { return; } else if (size == 1) { - String name = (String)threadPath.get(0); + String name = threadPath.get(0); ThreadTreeNode child = findLeafNode(thread, name); treeModel.removeNodeFromParent(child); } else { - String head = (String)threadPath.get(0); - List tail = threadPath.subList(1, size); + String head = threadPath.get(0); + List tail = threadPath.subList(1, size); ThreadTreeNode child = findInternalNode(head); child.removeThread(tail, thread); if (child.isThreadGroup() && child.getChildCount() < 1) { diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java index c79f17e3608..c6d437d29e6 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java @@ -34,7 +34,7 @@ import java.util.Iterator; class BreakpointSpec extends EventRequestSpec { String methodId; - List methodArgs; + List methodArgs; int lineNumber; BreakpointSpec(ReferenceTypeSpec refSpec, int lineNumber) { @@ -45,7 +45,7 @@ class BreakpointSpec extends EventRequestSpec { } BreakpointSpec(ReferenceTypeSpec refSpec, String methodId, - List methodArgs) throws MalformedMemberNameException { + List methodArgs) throws MalformedMemberNameException { super(refSpec); this.methodId = methodId; this.methodArgs = methodArgs; @@ -83,7 +83,7 @@ class BreakpointSpec extends EventRequestSpec { return lineNumber; } - List methodArgs() { + List methodArgs() { return methodArgs; } @@ -146,14 +146,13 @@ class BreakpointSpec extends EventRequestSpec { buffer.append('.'); buffer.append(methodId); if (methodArgs != null) { - Iterator iter = methodArgs.iterator(); boolean first = true; buffer.append('('); - while (iter.hasNext()) { + for (String arg : methodArgs) { if (!first) { buffer.append(','); } - buffer.append((String)iter.next()); + buffer.append(arg); first = false; } buffer.append(")"); @@ -176,12 +175,12 @@ class BreakpointSpec extends EventRequestSpec { location = method.location(); } else { // let AbsentInformationException be thrown - List locs = refType.locationsOfLine(lineNumber()); + List locs = refType.locationsOfLine(lineNumber()); if (locs.size() == 0) { throw new LineNotFoundException(); } // TO DO: handle multiple locations - location = (Location)locs.get(0); + location = locs.get(0); if (location.method() == null) { throw new LineNotFoundException(); } @@ -202,8 +201,8 @@ class BreakpointSpec extends EventRequestSpec { * and if the number of arguments in the method matches the * number of names passed */ - private boolean compareArgTypes(Method method, List nameList) { - List argTypeNames = method.argumentTypeNames(); + private boolean compareArgTypes(Method method, List nameList) { + List argTypeNames = method.argumentTypeNames(); // If argument counts differ, we can stop here if (argTypeNames.size() != nameList.size()) { @@ -213,8 +212,8 @@ class BreakpointSpec extends EventRequestSpec { // Compare each argument type's name int nTypes = argTypeNames.size(); for (int i = 0; i < nTypes; ++i) { - String comp1 = (String)argTypeNames.get(i); - String comp2 = (String)nameList.get(i); + String comp1 = argTypeNames.get(i); + String comp2 = nameList.get(i); if (! comp1.equals(comp2)) { /* * We have to handle varargs. EG, the @@ -331,22 +330,17 @@ class BreakpointSpec extends EventRequestSpec { List argTypeNames = null; if (methodArgs() != null) { argTypeNames = new ArrayList(methodArgs().size()); - Iterator iter = methodArgs().iterator(); - while (iter.hasNext()) { - String name = (String)iter.next(); + for (String name : methodArgs()) { name = normalizeArgTypeName(name); argTypeNames.add(name); } } // Check each method in the class for matches - Iterator iter = refType.methods().iterator(); Method firstMatch = null; // first method with matching name Method exactMatch = null; // (only) method with same name & sig int matchCount = 0; // > 1 implies overload - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); - + for (Method candidate : refType.methods()) { if (candidate.name().equals(methodName())) { matchCount++; diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java index 0f913eabaec..e607d7165d4 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java @@ -157,16 +157,16 @@ class Commands { buf.append(method.name()); buf.append("("); - List args = method.argumentTypeNames(); + List args = method.argumentTypeNames(); int lastParam = args.size() - 1; // output param types except for the last for (int ii = 0; ii < lastParam; ii++) { - buf.append((String)args.get(ii)); + buf.append(args.get(ii)); buf.append(", "); } if (lastParam >= 0) { // output the last param - String lastStr = (String)args.get(lastParam); + String lastStr = args.get(lastParam); if (method.isVarArgs()) { // lastParam is an array. Replace the [] with ... buf.append(lastStr.substring(0, lastStr.length() - 2)); @@ -180,12 +180,11 @@ class Commands { } void commandConnectors(VirtualMachineManager vmm) { - Iterator iter = vmm.allConnectors().iterator(); - if (iter.hasNext()) { + Collection ccs = vmm.allConnectors(); + if (ccs.isEmpty()) { MessageOutput.println("Connectors available"); } - while (iter.hasNext()) { - Connector cc = (Connector)iter.next(); + for (Connector cc : ccs) { String transportName = cc.transport() == null ? "null" : cc.transport().name(); MessageOutput.println(); @@ -193,10 +192,7 @@ class Commands { new Object [] {cc.name(), transportName}); MessageOutput.println("Connector description", cc.description()); - Iterator argIter = cc.defaultArguments().values().iterator(); - if (argIter.hasNext()) { - while (argIter.hasNext()) { - Connector.Argument aa = (Connector.Argument)argIter.next(); + for (Connector.Argument aa : cc.defaultArguments().values()) { MessageOutput.println(); boolean requiredArgument = aa.mustSpecify(); @@ -215,16 +211,12 @@ class Commands { } } - } } void commandClasses() { - List list = Env.vm().allClasses(); - StringBuffer classList = new StringBuffer(); - for (int i = 0 ; i < list.size() ; i++) { - ReferenceType refType = (ReferenceType)list.get(i); + for (ReferenceType refType : Env.vm().allClasses()) { classList.append(refType.name()); classList.append("\n"); } @@ -232,7 +224,7 @@ class Commands { } void commandClass(StringTokenizer t) { - List list = Env.vm().allClasses(); + List list = Env.vm().allClasses(); if (!t.hasMoreTokens()) { MessageOutput.println("No class specified."); @@ -265,51 +257,31 @@ class Commands { superclass = showAll ? superclass.superclass() : null; } - List interfaces = showAll ? clazz.allInterfaces() - : clazz.interfaces(); - Iterator iter = interfaces.iterator(); - while (iter.hasNext()) { - InterfaceType interfaze = (InterfaceType)iter.next(); + List interfaces = + showAll ? clazz.allInterfaces() : clazz.interfaces(); + for (InterfaceType interfaze : interfaces) { MessageOutput.println("implements:", interfaze.name()); } - List subs = clazz.subclasses(); - iter = subs.iterator(); - while (iter.hasNext()) { - ClassType sub = (ClassType)iter.next(); + for (ClassType sub : clazz.subclasses()) { MessageOutput.println("subclass:", sub.name()); } - List nested = clazz.nestedTypes(); - iter = nested.iterator(); - while (iter.hasNext()) { - ReferenceType nest = (ReferenceType)iter.next(); + for (ReferenceType nest : clazz.nestedTypes()) { MessageOutput.println("nested:", nest.name()); } } else if (type instanceof InterfaceType) { InterfaceType interfaze = (InterfaceType)type; MessageOutput.println("Interface:", interfaze.name()); - List supers = interfaze.superinterfaces(); - Iterator iter = supers.iterator(); - while (iter.hasNext()) { - InterfaceType superinterface = (InterfaceType)iter.next(); + for (InterfaceType superinterface : interfaze.superinterfaces()) { MessageOutput.println("extends:", superinterface.name()); } - List subs = interfaze.subinterfaces(); - iter = subs.iterator(); - while (iter.hasNext()) { - InterfaceType sub = (InterfaceType)iter.next(); + for (InterfaceType sub : interfaze.subinterfaces()) { MessageOutput.println("subinterface:", sub.name()); } - List implementors = interfaze.implementors(); - iter = implementors.iterator(); - while (iter.hasNext()) { - ClassType implementor = (ClassType)iter.next(); + for (ClassType implementor : interfaze.implementors()) { MessageOutput.println("implementor:", implementor.name()); } - List nested = interfaze.nestedTypes(); - iter = nested.iterator(); - while (iter.hasNext()) { - ReferenceType nest = (ReferenceType)iter.next(); + for (ReferenceType nest : interfaze.nestedTypes()) { MessageOutput.println("nested:", nest.name()); } } else { // array type @@ -327,10 +299,8 @@ class Commands { String idClass = t.nextToken(); ReferenceType cls = Env.getReferenceTypeFromToken(idClass); if (cls != null) { - List methods = cls.allMethods(); StringBuffer methodsList = new StringBuffer(); - for (int i = 0; i < methods.size(); i++) { - Method method = (Method)methods.get(i); + for (Method method : cls.allMethods()) { methodsList.append(method.declaringType().name()); methodsList.append(" "); methodsList.append(typedName(method)); @@ -351,11 +321,10 @@ class Commands { String idClass = t.nextToken(); ReferenceType cls = Env.getReferenceTypeFromToken(idClass); if (cls != null) { - List fields = cls.allFields(); - List visible = cls.visibleFields(); + List fields = cls.allFields(); + List visible = cls.visibleFields(); StringBuffer fieldsList = new StringBuffer(); - for (int i = 0; i < fields.size(); i++) { - Field field = (Field)fields.get(i); + for (Field field : fields) { String s; if (!visible.contains(field)) { s = MessageOutput.format("list field typename and name hidden", @@ -386,7 +355,7 @@ class Commands { int maxIdLength = 0; int maxNameLength = 0; while (threadIter.hasNext()) { - ThreadReference thr = (ThreadReference)threadIter.next(); + ThreadReference thr = threadIter.next(); maxIdLength = Math.max(maxIdLength, Env.description(thr).length()); maxNameLength = Math.max(maxNameLength, @@ -395,7 +364,7 @@ class Commands { threadIter = new ThreadIterator(tg); while (threadIter.hasNext()) { - ThreadReference thr = (ThreadReference)threadIter.next(); + ThreadReference thr = threadIter.next(); if (thr.threadGroup() == null) { continue; } @@ -588,9 +557,7 @@ class Commands { private List allThreads(ThreadGroupReference group) { List list = new ArrayList(); list.addAll(group.threads()); - Iterator iter = group.threadGroups().iterator(); - while (iter.hasNext()) { - ThreadGroupReference child = (ThreadGroupReference)iter.next(); + for (ThreadGroupReference child : group.threadGroups()) { list.addAll(allThreads(child)); } return list; @@ -641,10 +608,7 @@ class Commands { * if so, it gets removed here. */ EventRequestManager mgr = Env.vm().eventRequestManager(); - List requests = mgr.stepRequests(); - Iterator iter = requests.iterator(); - while (iter.hasNext()) { - StepRequest request = (StepRequest)iter.next(); + for (StepRequest request : mgr.stepRequests()) { if (request.thread().equals(thread)) { mgr.deleteEventRequest(request); break; @@ -768,9 +732,7 @@ class Commands { boolean noExceptions = true; // Print a listing of the catch patterns currently in place - Iterator iter = Env.specList.eventRequestSpecs().iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : Env.specList.eventRequestSpecs()) { if (spec instanceof ExceptionSpec) { if (noExceptions) { noExceptions = false; @@ -928,7 +890,7 @@ class Commands { } private void dumpStack(ThreadInfo threadInfo, boolean showPC) { - List stack = null; + List stack = null; try { stack = threadInfo.getStack(); } catch (IncompatibleThreadStateException e) { @@ -940,7 +902,7 @@ class Commands { } else { int nFrames = stack.size(); for (int i = threadInfo.getCurrentFrameIndex(); i < nFrames; i++) { - StackFrame frame = (StackFrame)stack.get(i); + StackFrame frame = stack.get(i); dumpFrame (i, showPC, frame); } } @@ -956,7 +918,7 @@ class Commands { long lineNumber = loc.lineNumber(); String methodInfo = null; - if (meth instanceof Method && ((Method)meth).isNative()) { + if (meth.isNative()) { methodInfo = MessageOutput.format("native method"); } else if (lineNumber != -1) { try { @@ -994,9 +956,7 @@ class Commands { } else { String token = t.nextToken(); if (token.toLowerCase().equals("all")) { - Iterator iter = ThreadInfo.threads().iterator(); - while (iter.hasNext()) { - ThreadInfo threadInfo = (ThreadInfo)iter.next(); + for (ThreadInfo threadInfo : ThreadInfo.threads()) { MessageOutput.println("Thread:", threadInfo.getThread().name()); dumpStack(threadInfo, showPC); @@ -1051,9 +1011,7 @@ class Commands { boolean noBreakpoints = true; // Print set breakpoints - Iterator iter = Env.specList.eventRequestSpecs().iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : Env.specList.eventRequestSpecs()) { if (spec instanceof BreakpointSpec) { if (noBreakpoints) { noBreakpoints = false; @@ -1075,7 +1033,7 @@ class Commands { protected BreakpointSpec parseBreakpointSpec(StringTokenizer t, String atForm, String inForm) { - EventRequestSpec breakpoint = null; + BreakpointSpec breakpoint = null; try { String token = t.nextToken(":( \t\n\r"); @@ -1149,7 +1107,7 @@ class Commands { printBreakpointCommandUsage(atForm, inForm); return null; } - return (BreakpointSpec)breakpoint; + return breakpoint; } private void resolveNow(EventRequestSpec spec) { @@ -1209,8 +1167,8 @@ class Commands { } } - private List parseWatchpointSpec(StringTokenizer t) { - List list = new ArrayList(); + private List parseWatchpointSpec(StringTokenizer t) { + List list = new ArrayList(); boolean access = false; boolean modification = false; int suspendPolicy = EventRequest.SUSPEND_ALL; @@ -1242,7 +1200,7 @@ class Commands { fieldName = fieldName.substring(dot+1); try { - EventRequestSpec spec; + WatchpointSpec spec; if (access) { spec = Env.specList.createAccessWatchpoint(className, fieldName); @@ -1269,9 +1227,8 @@ class Commands { return; } - Iterator iter = parseWatchpointSpec(t).iterator(); - while (iter.hasNext()) { - resolveNow((WatchpointSpec)iter.next()); + for (WatchpointSpec spec : parseWatchpointSpec(t)) { + resolveNow(spec); } } @@ -1281,9 +1238,7 @@ class Commands { return; } - Iterator iter = parseWatchpointSpec(t).iterator(); - while (iter.hasNext()) { - WatchpointSpec spec = (WatchpointSpec)iter.next(); + for (WatchpointSpec spec : parseWatchpointSpec(t)) { if (Env.specList.delete(spec)) { MessageOutput.println("Removed:", spec.toString()); } else { @@ -1482,7 +1437,7 @@ class Commands { lineno = n.intValue(); } catch (java.text.ParseException jtpe) { // It isn't -- see if it's a method name. - List meths = refType.methodsByName(id); + List meths = refType.methodsByName(id); if (meths == null || meths.size() == 0) { MessageOutput.println("is not a valid line number or method name for", new Object [] {id, refType.name()}); @@ -1492,7 +1447,7 @@ class Commands { new Object [] {id, refType.name()}); return; } - loc = ((Method)meths.get(0)).location(); + loc = meths.get(0).location(); lineno = loc.lineNumber(); } } @@ -1539,14 +1494,11 @@ class Commands { try { ReferenceType refType = Env.getReferenceTypeFromToken(idClass); if (refType != null) { - List lines = null; + List lines = null; if (idMethod == null) { lines = refType.allLineLocations(); } else { - List methods = refType.allMethods(); - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method method = (Method)iter.next(); + for (Method method : refType.allMethods()) { if (method.name().equals(idMethod)) { lines = method.allLineLocations(); } @@ -1555,9 +1507,7 @@ class Commands { MessageOutput.println("is not a valid method name", idMethod); } } - Iterator iter = lines.iterator(); - while (iter.hasNext()) { - Location line = (Location)iter.next(); + for (Location line : lines) { MessageOutput.printDirectln(line.toString());// Special case: use printDirectln() } } else { @@ -1620,21 +1570,19 @@ class Commands { MessageOutput.println("No local variables"); return; } - Map values = frame.getValues(vars); + Map values = frame.getValues(vars); MessageOutput.println("Method arguments:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (var.isArgument()) { - Value val = (Value)values.get(var); + Value val = values.get(var); printVar(var, val); } } MessageOutput.println("Local variables:"); - for (Iterator it = vars.iterator(); it.hasNext(); ) { - LocalVariable var = (LocalVariable)it.next(); + for (LocalVariable var : vars) { if (!var.isArgument()) { - Value val = (Value)values.get(var); + Value val = values.get(var); printVar(var, val); } } @@ -1647,9 +1595,8 @@ class Commands { private void dump(ObjectReference obj, ReferenceType refType, ReferenceType refTypeBase) { - for (Iterator it = refType.fields().iterator(); it.hasNext(); ) { + for (Field field : refType.fields()) { StringBuffer o = new StringBuffer(); - Field field = (Field)it.next(); o.append(" "); if (!refType.equals(refTypeBase)) { o.append(refType.name()); @@ -1666,14 +1613,13 @@ class Commands { dump(obj, sup, refTypeBase); } } else if (refType instanceof InterfaceType) { - List sups = ((InterfaceType)refType).superinterfaces(); - for (Iterator it = sups.iterator(); it.hasNext(); ) { - dump(obj, (ReferenceType)it.next(), refTypeBase); + for (InterfaceType sup : ((InterfaceType)refType).superinterfaces()) { + dump(obj, sup, refTypeBase); } } else { /* else refType is an instanceof ArrayType */ if (obj instanceof ArrayReference) { - for (Iterator it = ((ArrayReference)obj).getValues().iterator(); + for (Iterator it = ((ArrayReference)obj).getValues().iterator(); it.hasNext(); ) { MessageOutput.printDirect(it.next().toString());// Special case: use printDirect() if (it.hasNext()) { @@ -1770,13 +1716,11 @@ class Commands { new Object [] {owner.name(), new Integer (object.entryCount())}); } - List waiters = object.waitingThreads(); + List waiters = object.waitingThreads(); if (waiters.size() == 0) { MessageOutput.println("No waiters"); } else { - Iterator iter = waiters.iterator(); - while (iter.hasNext()) { - ThreadReference waiter = (ThreadReference)iter.next(); + for (ThreadReference waiter : waiters) { MessageOutput.println("Waiting thread:", waiter.name()); } } @@ -1800,13 +1744,11 @@ class Commands { ThreadReference thread = threadInfo.getThread(); try { MessageOutput.println("Monitor information for thread", thread.name()); - List owned = thread.ownedMonitors(); + List owned = thread.ownedMonitors(); if (owned.size() == 0) { MessageOutput.println("No monitors owned"); } else { - Iterator iter = owned.iterator(); - while (iter.hasNext()) { - ObjectReference monitor = (ObjectReference)iter.next(); + for (ObjectReference monitor : owned) { MessageOutput.println("Owned monitor:", monitor.toString()); } } @@ -1833,9 +1775,7 @@ class Commands { } String token = t.nextToken(); if (token.toLowerCase().equals("all")) { - Iterator iter = ThreadInfo.threads().iterator(); - while (iter.hasNext()) { - ThreadInfo threadInfo = (ThreadInfo)iter.next(); + for (ThreadInfo threadInfo : ThreadInfo.threads()) { printThreadLockInfo(threadInfo); } } else { @@ -1930,14 +1870,12 @@ class Commands { void commandSave(final StringTokenizer t) { // Undocumented command: useful for testing. if (!t.hasMoreTokens()) { - Set keys = Env.getSaveKeys(); - Iterator iter = keys.iterator(); - if (!iter.hasNext()) { + Set keys = Env.getSaveKeys(); + if (keys.isEmpty()) { MessageOutput.println("No saved values"); return; } - while (iter.hasNext()) { - String key = (String)iter.next(); + for (String key : keys) { Value value = Env.getSavedValue(key); if ((value instanceof ObjectReference) && ((ObjectReference)value).isCollected()) { @@ -1976,7 +1914,7 @@ class Commands { // Overloading is not handled here. String methodName = t.nextToken(); - List classes = Env.vm().classesByName(className); + List classes = Env.vm().classesByName(className); // TO DO: handle multiple classes found if (classes.size() == 0) { if (className.indexOf('.') < 0) { @@ -1987,17 +1925,14 @@ class Commands { return; } - ReferenceType rt = (ReferenceType)classes.get(0); + ReferenceType rt = classes.get(0); if (!(rt instanceof ClassType)) { MessageOutput.println("not a class", className); return; } byte[] bytecodes = null; - List list = rt.methodsByName(methodName); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - Method method = (Method)iter.next(); + for (Method method : rt.methodsByName(methodName)) { if (!method.isAbstract()) { bytecodes = method.bytecodes(); break; @@ -2047,7 +1982,7 @@ class Commands { MessageOutput.println("Specify classes to redefine"); } else { String className = t.nextToken(); - List classes = Env.vm().classesByName(className); + List classes = Env.vm().classesByName(className); if (classes.size() == 0) { MessageOutput.println("No class named", className); return; @@ -2057,7 +1992,7 @@ class Commands { return; } Env.setSourcePath(Env.getSourcePath()); - ReferenceType refType = (ReferenceType)classes.get(0); + ReferenceType refType = classes.get(0); if (!t.hasMoreTokens()) { MessageOutput.println("Specify file name for class", className); return; @@ -2074,7 +2009,8 @@ class Commands { new Object [] {fileName, exc.toString()}); return; } - Map map = new HashMap(); + Map map + = new HashMap(); map.put(refType, bytes); try { Env.vm().redefineClasses(map); diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/Env.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Env.java index be3fb306a57..9d848a0205b 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/Env.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Env.java @@ -89,7 +89,7 @@ class Env { sourceCache.clear(); } - static void setSourcePath(List srcList) { + static void setSourcePath(List srcList) { sourceMapper = new SourceMapper(srcList); sourceCache.clear(); } @@ -106,10 +106,8 @@ class Env { } static String excludesString() { - Iterator iter = excludes().iterator(); StringBuffer buffer = new StringBuffer(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { buffer.append(pattern); buffer.append(","); } @@ -117,25 +115,19 @@ class Env { } static void addExcludes(StepRequest request) { - Iterator iter = excludes().iterator(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { request.addClassExclusionFilter(pattern); } } static void addExcludes(MethodEntryRequest request) { - Iterator iter = excludes().iterator(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { request.addClassExclusionFilter(pattern); } } static void addExcludes(MethodExitRequest request) { - Iterator iter = excludes().iterator(); - while (iter.hasNext()) { - String pattern = (String)iter.next(); + for (String pattern : excludes()) { request.addClassExclusionFilter(pattern); } } @@ -175,10 +167,10 @@ class Env { try { String fileName = location.sourceName(); - Iterator iter = sourceCache.iterator(); + Iterator iter = sourceCache.iterator(); SourceCode code = null; while (iter.hasNext()) { - SourceCode candidate = (SourceCode)iter.next(); + SourceCode candidate = iter.next(); if (candidate.fileName().equals(fileName)) { code = candidate; iter.remove(); @@ -269,10 +261,7 @@ class Env { // loaded class whose name matches this limited regular // expression is selected. idToken = idToken.substring(1); - List classes = Env.vm().allClasses(); - Iterator iter = classes.iterator(); - while (iter.hasNext()) { - ReferenceType type = ((ReferenceType)iter.next()); + for (ReferenceType type : Env.vm().allClasses()) { if (type.name().endsWith(idToken)) { cls = type; break; @@ -280,21 +269,21 @@ class Env { } } else { // It's a class name - List classes = Env.vm().classesByName(idToken); + List classes = Env.vm().classesByName(idToken); if (classes.size() > 0) { // TO DO: handle multiples - cls = (ReferenceType)classes.get(0); + cls = classes.get(0); } } return cls; } - static Set getSaveKeys() { + static Set getSaveKeys() { return savedValues.keySet(); } static Value getSavedValue(String key) { - return (Value)savedValues.get(key); + return savedValues.get(key); } static void setSavedValue(String key, Value value) { @@ -327,7 +316,7 @@ class Env { if (index >= sourceLines.size()) { return null; } else { - return (String)sourceLines.get(index); + return sourceLines.get(index); } } } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java index 27ef3913ece..ee80f9df538 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java @@ -150,7 +150,7 @@ public class EventHandler implements Runnable { EventSet eventSet = queue.remove(); EventIterator iter = eventSet.eventIterator(); while (iter.hasNext()) { - handleExitEvent((Event)iter.next()); + handleExitEvent(iter.next()); } } catch (InterruptedException exc) { // ignore @@ -183,7 +183,7 @@ public class EventHandler implements Runnable { * If any event in the set has a thread associated with it, * they all will, so just grab the first one. */ - Event event = (Event)set.iterator().next(); // Is there a better way? + Event event = set.iterator().next(); // Is there a better way? thread = eventThread(event); } else { thread = null; diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java index bb86c2f3af0..7169e33f6f0 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java @@ -101,10 +101,8 @@ abstract class EventRequestSpec { * so that is all we need to examine. */ ArrayList deleteList = new ArrayList(); - Iterator iter = - Env.vm().eventRequestManager().exceptionRequests().iterator(); - while (iter.hasNext()) { - ExceptionRequest er = (ExceptionRequest)iter.next(); + for (ExceptionRequest er : + Env.vm().eventRequestManager().exceptionRequests()) { if (prs.matches(er.exception())) { deleteList.add (er); } @@ -115,9 +113,7 @@ abstract class EventRequestSpec { } private EventRequest resolveAgainstPreparedClasses() throws Exception { - Iterator iter = Env.vm().allClasses().iterator(); - while (iter.hasNext()) { - ReferenceType refType = (ReferenceType)iter.next(); + for (ReferenceType refType : Env.vm().allClasses()) { if (refType.isPrepared() && refSpec.matches(refType)) { resolved = resolveEventRequest(refType); } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java index 2f3286d1a7e..e5741efc706 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java @@ -55,9 +55,7 @@ class EventRequestSpecList { boolean resolve(ClassPrepareEvent event) { boolean failure = false; synchronized(eventRequestSpecs) { - Iterator iter = eventRequestSpecs.iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : eventRequestSpecs) { if (!spec.isResolved()) { try { EventRequest eventRequest = spec.resolve(event); @@ -77,9 +75,7 @@ class EventRequestSpecList { } void resolveAll() { - Iterator iter = eventRequestSpecs.iterator(); - while (iter.hasNext()) { - EventRequestSpec spec = (EventRequestSpec)iter.next(); + for (EventRequestSpec spec : eventRequestSpecs) { try { EventRequest eventRequest = spec.resolveEagerly(); if (eventRequest != null) { @@ -106,16 +102,16 @@ class EventRequestSpecList { } } - EventRequestSpec createBreakpoint(String classPattern, - int line) throws ClassNotFoundException { + BreakpointSpec createBreakpoint(String classPattern, int line) + throws ClassNotFoundException { ReferenceTypeSpec refSpec = new PatternReferenceTypeSpec(classPattern); return new BreakpointSpec(refSpec, line); } - EventRequestSpec createBreakpoint(String classPattern, + BreakpointSpec createBreakpoint(String classPattern, String methodId, - List methodArgs) + List methodArgs) throws MalformedMemberNameException, ClassNotFoundException { ReferenceTypeSpec refSpec = @@ -132,7 +128,7 @@ class EventRequestSpecList { return new ExceptionSpec(refSpec, notifyCaught, notifyUncaught); } - EventRequestSpec createAccessWatchpoint(String classPattern, + WatchpointSpec createAccessWatchpoint(String classPattern, String fieldId) throws MalformedMemberNameException, ClassNotFoundException { @@ -141,7 +137,7 @@ class EventRequestSpecList { return new AccessWatchpointSpec(refSpec, fieldId); } - EventRequestSpec createModificationWatchpoint(String classPattern, + WatchpointSpec createModificationWatchpoint(String classPattern, String fieldId) throws MalformedMemberNameException, ClassNotFoundException { @@ -154,7 +150,7 @@ class EventRequestSpecList { synchronized (eventRequestSpecs) { int inx = eventRequestSpecs.indexOf(proto); if (inx != -1) { - EventRequestSpec spec = (EventRequestSpec)eventRequestSpecs.get(inx); + EventRequestSpec spec = eventRequestSpecs.get(inx); spec.remove(); eventRequestSpecs.remove(inx); return true; diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java index da8af944890..618f41a622c 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java @@ -39,15 +39,13 @@ class SourceMapper { private final String[] dirs; - SourceMapper(List sourcepath) { + SourceMapper(List sourcepath) { /* * sourcepath can arrive from the debugee as a List. * (via PathSearchingVirtualMachine.classPath()) */ List dirList = new ArrayList(); - Iterator iter = sourcepath.iterator(); - while (iter.hasNext()) { - String element = (String)iter.next(); + for (String element : sourcepath) { //XXX remove .jar and .zip files; we want only directories on //the source path. (Bug ID 4186582) if ( ! (element.endsWith(".jar") || @@ -55,7 +53,7 @@ class SourceMapper { dirList.add(element); } } - dirs = (String[])dirList.toArray(new String[0]); + dirs = dirList.toArray(new String[0]); } SourceMapper(String sourcepath) { @@ -79,7 +77,7 @@ class SourceMapper { dirList.add(s); } } - dirs = (String[])dirList.toArray(new String[0]); + dirs = dirList.toArray(new String[0]); } /* diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTY.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTY.java index 620891af757..ec1dc51c6da 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTY.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTY.java @@ -160,9 +160,7 @@ public class TTY implements EventNotifier { // here the next time. Env.setAtExitMethod(null); EventRequestManager erm = Env.vm().eventRequestManager(); - Iterator it = erm.methodExitRequests().iterator(); - while (it.hasNext()) { - EventRequest eReq = (EventRequest)it.next(); + for (EventRequest eReq : erm.methodExitRequests()) { if (eReq.equals(me.request())) { eReq.disable(); } @@ -178,9 +176,8 @@ public class TTY implements EventNotifier { public void vmInterrupted() { Thread.yield(); // fetch output printCurrentLocation(); - Iterator it = monitorCommands.iterator(); - while (it.hasNext()) { - StringTokenizer t = new StringTokenizer((String)it.next()); + for (String cmd : monitorCommands) { + StringTokenizer t = new StringTokenizer(cmd); t.nextToken(); // get rid of monitor number executeCommand(t); } @@ -563,9 +560,8 @@ public class TTY implements EventNotifier { ++monitorCount; monitorCommands.add(monitorCount + ": " + t.nextToken("")); } else { - Iterator it = monitorCommands.iterator(); - while (it.hasNext()) { - MessageOutput.printDirectln((String)it.next());// Special case: use printDirectln() + for (String cmd : monitorCommands) { + MessageOutput.printDirectln(cmd);// Special case: use printDirectln() } } } @@ -581,9 +577,7 @@ public class TTY implements EventNotifier { return; } String monStr = monTok + ":"; - Iterator it = monitorCommands.iterator(); - while (it.hasNext()) { - String cmd = (String)it.next(); + for (String cmd : monitorCommands) { StringTokenizer ct = new StringTokenizer(cmd); if (ct.nextToken().equals(monStr)) { monitorCommands.remove(cmd); @@ -768,10 +762,8 @@ public class TTY implements EventNotifier { } private static boolean supportsSharedMemory() { - List connectors = Bootstrap.virtualMachineManager().allConnectors(); - Iterator iter = connectors.iterator(); - while (iter.hasNext()) { - Connector connector = (Connector)iter.next(); + for (Connector connector : + Bootstrap.virtualMachineManager().allConnectors()) { if (connector.transport() == null) { continue; } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java index c62a8822003..dc2dc118074 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java @@ -36,7 +36,7 @@ import java.util.Iterator; * Descend the tree of thread groups. * @author Robert G. Field */ -class ThreadGroupIterator implements Iterator { +class ThreadGroupIterator implements Iterator { private final Stack> stack = new Stack>(); ThreadGroupIterator(List tgl) { @@ -53,8 +53,8 @@ class ThreadGroupIterator implements Iterator { this(Env.vm().topLevelThreadGroups()); } - private Iterator top() { - return (Iterator)stack.peek(); + private Iterator top() { + return stack.peek(); } /** @@ -74,12 +74,12 @@ class ThreadGroupIterator implements Iterator { return !stack.isEmpty(); } - public Object next() { + public ThreadGroupReference next() { return nextThreadGroup(); } public ThreadGroupReference nextThreadGroup() { - ThreadGroupReference tg = (ThreadGroupReference)top().next(); + ThreadGroupReference tg = top().next(); push(tg.threadGroups()); return tg; } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java index 97c6a880828..e823821c04c 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java @@ -56,9 +56,7 @@ class ThreadInfo { private static void initThreads() { if (!gotInitialThreads) { - Iterator iter = Env.vm().allThreads().iterator(); - while (iter.hasNext()) { - ThreadReference thread = (ThreadReference)iter.next(); + for (ThreadReference thread : Env.vm().allThreads()) { threads.add(new ThreadInfo(thread)); } gotInitialThreads = true; @@ -113,9 +111,7 @@ class ThreadInfo { current = null; group = null; synchronized (threads) { - Iterator iter = threads().iterator(); - while (iter.hasNext()) { - ThreadInfo ti = (ThreadInfo)iter.next(); + for (ThreadInfo ti : threads()) { ti.invalidate(); } } @@ -163,8 +159,7 @@ class ThreadInfo { if (group == null) { // Current thread group defaults to the first top level // thread group. - setThreadGroup((ThreadGroupReference) - Env.vm().topLevelThreadGroups().get(0)); + setThreadGroup(Env.vm().topLevelThreadGroups().get(0)); } return group; } @@ -173,9 +168,7 @@ class ThreadInfo { ThreadInfo retInfo = null; synchronized (threads) { - Iterator iter = threads().iterator(); - while (iter.hasNext()) { - ThreadInfo ti = (ThreadInfo)iter.next(); + for (ThreadInfo ti : threads()) { if (ti.thread.uniqueID() == id) { retInfo = ti; break; @@ -208,7 +201,7 @@ class ThreadInfo { * * @return a List of the stack frames. */ - List getStack() throws IncompatibleThreadStateException { + List getStack() throws IncompatibleThreadStateException { return thread.frames(); } diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java index b753cf742a3..8baff8ebd48 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java @@ -30,8 +30,8 @@ import com.sun.jdi.ThreadReference; import java.util.List; import java.util.Iterator; -class ThreadIterator implements Iterator { - Iterator it = null; +class ThreadIterator implements Iterator { + Iterator it = null; ThreadGroupIterator tgi; ThreadIterator(ThreadGroupReference tg) { @@ -56,12 +56,12 @@ class ThreadIterator implements Iterator { return true; } - public Object next() { + public ThreadReference next() { return it.next(); } public ThreadReference nextThread() { - return (ThreadReference)next(); + return next(); } public void remove() { diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java b/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java index 6d3c3be20f8..7ab34280f89 100644 --- a/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java +++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java @@ -61,10 +61,8 @@ class VMConnection { } private Connector findConnector(String name) { - List connectors = Bootstrap.virtualMachineManager().allConnectors(); - Iterator iter = connectors.iterator(); - while (iter.hasNext()) { - Connector connector = (Connector)iter.next(); + for (Connector connector : + Bootstrap.virtualMachineManager().allConnectors()) { if (connector.name().equals(name)) { return connector; } @@ -108,7 +106,7 @@ class VMConnection { String value = token.substring(index + 1, token.length() - 1); // Remove comma delimiter - Connector.Argument argument = (Connector.Argument)arguments.get(name); + Connector.Argument argument = arguments.get(name); if (argument == null) { throw new IllegalArgumentException (MessageOutput.format("Argument is not defined for connector:", @@ -195,7 +193,7 @@ class VMConnection { return false; } - Connector.Argument argument = (Connector.Argument)connectorArgs.get(name); + Connector.Argument argument = connectorArgs.get(name); if (argument == null) { return false; } @@ -204,7 +202,7 @@ class VMConnection { } String connectorArg(String name) { - Connector.Argument argument = (Connector.Argument)connectorArgs.get(name); + Connector.Argument argument = connectorArgs.get(name); if (argument == null) { return ""; } diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java index 60c48f1bce4..4fc235f7e2a 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java @@ -99,8 +99,7 @@ class ClassQuery extends QueryHandler { } out.println("

    Instance Data Members:

    "); - JavaField[] ff = clazz.getFields(); - ff = (JavaField[]) ff.clone(); + JavaField[] ff = clazz.getFields().clone(); ArraySorter.sort(ff, new Comparer() { public int compare(Object lhs, Object rhs) { JavaField left = (JavaField) lhs; diff --git a/jdk/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java b/jdk/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java index 1f6d3bf9d8f..24db65e2fe7 100644 --- a/jdk/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java +++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java @@ -90,9 +90,7 @@ public class PlatformClasses { // is the right thing to do anyway. } } - int num = list.size(); - names = new String[num]; - names = (String[]) list.toArray(names); + names = list.toArray(new String[list.size()]); } return names; } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java b/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java index 23e9369050d..48d60f9d8b9 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java @@ -119,7 +119,7 @@ abstract class AbstractLauncher extends ConnectorImpl implements LaunchingConnec String[] tokenArray = new String[tokenList.size()]; for (int i = 0; i < tokenList.size(); i++) { - tokenArray[i] = (String)tokenList.get(i); + tokenArray[i] = tokenList.get(i); } return tokenArray; } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java index fbb613b119a..3e68aa72746 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java @@ -95,11 +95,8 @@ public class ClassTypeImpl extends ReferenceTypeImpl } public List subclasses() { - List all = vm.allClasses(); List subs = new ArrayList(); - Iterator iter = all.iterator(); - while (iter.hasNext()) { - ReferenceType refType = (ReferenceType)iter.next(); + for (ReferenceType refType : vm.allClasses()) { if (refType instanceof ClassType) { ClassType clazz = (ClassType)refType; ClassType superclass = clazz.superclass(); @@ -223,7 +220,7 @@ public class ClassTypeImpl extends ReferenceTypeImpl List arguments = method.validateAndPrepareArgumentsForInvoke(origArguments); - ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]); + ValueImpl[] args = arguments.toArray(new ValueImpl[0]); JDWP.ClassType.InvokeMethod ret; try { PacketStream stream = @@ -271,7 +268,7 @@ public class ClassTypeImpl extends ReferenceTypeImpl List arguments = method.validateAndPrepareArgumentsForInvoke( origArguments); - ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]); + ValueImpl[] args = arguments.toArray(new ValueImpl[0]); JDWP.ClassType.NewInstance ret = null; try { PacketStream stream = @@ -301,11 +298,8 @@ public class ClassTypeImpl extends ReferenceTypeImpl } public Method concreteMethodByName(String name, String signature) { - List methods = visibleMethods(); Method method = null; - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); + for (Method candidate : visibleMethods()) { if (candidate.name().equals(name) && candidate.signature().equals(signature) && !candidate.isAbstract()) { @@ -330,9 +324,7 @@ public class ClassTypeImpl extends ReferenceTypeImpl * Avoid duplicate checking on each method by iterating through * duplicate-free allInterfaces() rather than recursing */ - Iterator iter = allInterfaces().iterator(); - while (iter.hasNext()) { - InterfaceType interfaze = (InterfaceType)iter.next(); + for (InterfaceType interfaze : allInterfaces()) { list.addAll(interfaze.methods()); } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java index b5d52e6c3e8..6e44338cdfd 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java @@ -247,7 +247,7 @@ public class ConcreteMethodImpl extends MethodImpl { public byte[] bytecodes() { byte[] bytecodes = (bytecodesRef == null) ? null : - (byte[])bytecodesRef.get(); + bytecodesRef.get(); if (bytecodes == null) { try { bytecodes = JDWP.Method.Bytecodes. @@ -262,7 +262,7 @@ public class ConcreteMethodImpl extends MethodImpl { * to return the cached bytecodes directly; instead, we * make a clone at the cost of using more memory. */ - return (byte[])bytecodes.clone(); + return bytecodes.clone(); } int argSlotCount() throws AbsentInformationException { @@ -279,7 +279,7 @@ public class ConcreteMethodImpl extends MethodImpl { String stratumID = stratum.id(); SoftLocationXRefs info = (softOtherLocationXRefsRef == null) ? null : - (SoftLocationXRefs)softOtherLocationXRefsRef.get(); + softOtherLocationXRefsRef.get(); if (info != null && info.stratumID.equals(stratumID)) { return info; } @@ -348,7 +348,7 @@ public class ConcreteMethodImpl extends MethodImpl { private SoftLocationXRefs getBaseLocations() { SoftLocationXRefs info = (softBaseLocationXRefsRef == null) ? null : - (SoftLocationXRefs)softBaseLocationXRefsRef.get(); + softBaseLocationXRefsRef.get(); if (info != null) { return info; } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java index da96ad494ce..1a2c61c7bc9 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java @@ -56,10 +56,8 @@ public class EventSetImpl extends ArrayList implements EventSet { public String toString() { String string = "event set, policy:" + suspendPolicy + ", count:" + this.size() + " = {"; - Iterator iter = this.iterator(); boolean first = true; - while (iter.hasNext()) { - Event event = (Event)iter.next(); + for (Event event : this) { if (!first) { string += ", "; } @@ -787,9 +785,7 @@ public class EventSetImpl extends ArrayList implements EventSet { } private ThreadReference eventThread() { - Iterator iter = this.iterator(); - while (iter.hasNext()) { - Event event = (Event)iter.next(); + for (Event event : this) { if (event instanceof ThreadedEventImpl) { return ((ThreadedEventImpl)event).thread(); } @@ -846,7 +842,7 @@ public class EventSetImpl extends ArrayList implements EventSet { } public Event nextEvent() { - return (Event)next(); + return next(); } public void remove() { diff --git a/jdk/src/share/classes/com/sun/tools/jdi/JNITypeParser.java b/jdk/src/share/classes/com/sun/tools/jdi/JNITypeParser.java index 6151d5293e2..6add99fa6eb 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/JNITypeParser.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/JNITypeParser.java @@ -82,7 +82,7 @@ public class JNITypeParser { } String typeName() { - return (String)typeNameList().get(typeNameList().size()-1); + return typeNameList().get(typeNameList().size()-1); } List argumentTypeNames() { @@ -90,7 +90,7 @@ public class JNITypeParser { } String signature() { - return (String)signatureList().get(signatureList().size()-1); + return signatureList().get(signatureList().size()-1); } List argumentSignatures() { diff --git a/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java index 39664935521..4ad9da94882 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java @@ -158,7 +158,7 @@ public abstract class MethodImpl extends TypeComponentImpl Type argumentType(int index) throws ClassNotLoadedException { ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType(); - String signature = (String)argumentSignatures().get(index); + String signature = argumentSignatures().get(index); return enclosing.findType(signature); } @@ -263,10 +263,10 @@ public abstract class MethodImpl extends TypeComponentImpl return argumentType(index); } public String typeName(){ - return (String)argumentTypeNames().get(index); + return argumentTypeNames().get(index); } public String signature() { - return (String)argumentSignatures().get(index); + return argumentSignatures().get(index); } public Type findType(String signature) throws ClassNotLoadedException { return MethodImpl.this.findType(signature); @@ -307,7 +307,7 @@ public abstract class MethodImpl extends TypeComponentImpl arguments.add(argArray); return; } - Value nthArgValue = (Value)arguments.get(paramCount - 1); + Value nthArgValue = arguments.get(paramCount - 1); if (nthArgValue == null) { return; } @@ -371,7 +371,7 @@ public abstract class MethodImpl extends TypeComponentImpl } for (int i = 0; i < argSize; i++) { - Value value = (Value)arguments.get(i); + Value value = arguments.get(i); value = ValueImpl.prepareForAssignment(value, new ArgumentContainer(i)); arguments.set(i, value); @@ -386,11 +386,11 @@ public abstract class MethodImpl extends TypeComponentImpl sb.append(name()); sb.append("("); boolean first = true; - for (Iterator it = argumentTypeNames().iterator(); it.hasNext();) { + for (String name : argumentTypeNames()) { if (!first) { sb.append(", "); } - sb.append((String)it.next()); + sb.append(name); first = false; } sb.append(")"); diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java index 82aed8e96be..79f84cdb2b4 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java @@ -383,7 +383,7 @@ public class ObjectReferenceImpl extends ValueImpl List arguments = method.validateAndPrepareArgumentsForInvoke( origArguments); - ValueImpl[] args = (ValueImpl[])arguments.toArray(new ValueImpl[0]); + ValueImpl[] args = arguments.toArray(new ValueImpl[0]); JDWP.ObjectReference.InvokeMethod ret; try { PacketStream stream = @@ -583,7 +583,7 @@ public class ObjectReferenceImpl extends ValueImpl // Validate assignment ReferenceType destType = (ReferenceTypeImpl)destination.type(); ReferenceTypeImpl myType = (ReferenceTypeImpl)referenceType(); - if (!myType.isAssignableTo((ReferenceType)destType)) { + if (!myType.isAssignableTo(destType)) { JNITypeParser parser = new JNITypeParser(destType.signature()); String destTypeName = parser.typeName(); throw new InvalidTypeException("Can't assign " + diff --git a/jdk/src/share/classes/com/sun/tools/jdi/PacketStream.java b/jdk/src/share/classes/com/sun/tools/jdi/PacketStream.java index 5ad2fd1b451..65db8b31740 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/PacketStream.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/PacketStream.java @@ -485,7 +485,7 @@ class PacketStream { * Read field represented as vm specific byte sequence. */ Field readField() { - ReferenceTypeImpl refType = (ReferenceTypeImpl)readReferenceType(); + ReferenceTypeImpl refType = readReferenceType(); long fieldRef = readFieldRef(); return refType.getFieldMirror(fieldRef); } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java index 4af0e8e8a45..f66c202f744 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java @@ -59,7 +59,7 @@ implements ReferenceType { private boolean constantPoolInfoGotten = false; private int constanPoolCount; private byte[] constantPoolBytes; - private SoftReference constantPoolBytesRef = null; + private SoftReference constantPoolBytesRef = null; /* to mark a SourceFile request that returned a genuine JDWP.Error.ABSENT_INFORMATION */ private static final String ABSENT_BASE_SOURCE_NAME = "**ABSENT_BASE_SOURCE_NAME**"; @@ -352,13 +352,10 @@ implements ReferenceType { abstract List inheritedTypes(); void addVisibleFields(List visibleList, Map visibleTable, List ambiguousNames) { - List list = visibleFields(); - Iterator iter = list.iterator(); - while (iter.hasNext()) { - Field field = (Field)iter.next(); + for (Field field : visibleFields()) { String name = field.name(); if (!ambiguousNames.contains(name)) { - Field duplicate = (Field)visibleTable.get(name); + Field duplicate = visibleTable.get(name); if (duplicate == null) { visibleList.add(field); visibleTable.put(name, field); @@ -402,10 +399,8 @@ implements ReferenceType { * hide. */ List retList = new ArrayList(fields()); - iter = retList.iterator(); - while (iter.hasNext()) { - Field field = (Field)iter.next(); - Field hidden = (Field)visibleTable.get(field.name()); + for (Field field : retList) { + Field hidden = visibleTable.get(field.name()); if (hidden != null) { visibleList.remove(hidden); } @@ -515,12 +510,9 @@ implements ReferenceType { * methods. */ void addToMethodMap(Map methodMap, List methodList) { - Iterator iter = methodList.iterator(); - while (iter.hasNext()) { - Method method = (Method)iter.next(); + for (Method method : methodList) methodMap.put(method.name().concat(method.signature()), method); } - } abstract void addVisibleMethods(Map methodMap); @@ -549,9 +541,7 @@ implements ReferenceType { public List methodsByName(String name) { List methods = visibleMethods(); ArrayList retList = new ArrayList(methods.size()); - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); + for (Method candidate : methods) { if (candidate.name().equals(name)) { retList.add(candidate); } @@ -563,9 +553,7 @@ implements ReferenceType { public List methodsByName(String name, String signature) { List methods = visibleMethods(); ArrayList retList = new ArrayList(methods.size()); - Iterator iter = methods.iterator(); - while (iter.hasNext()) { - Method candidate = (Method)iter.next(); + for (Method candidate : methods) { if (candidate.name().equals(name) && candidate.signature().equals(signature)) { retList.add(candidate); @@ -706,7 +694,7 @@ implements ReferenceType { } public String sourceName() throws AbsentInformationException { - return (String)(sourceNames(vm.getDefaultStratum()).get(0)); + return sourceNames(vm.getDefaultStratum()).get(0); } public List sourceNames(String stratumID) @@ -796,7 +784,7 @@ implements ReferenceType { if (!vm.canGetSourceDebugExtension()) { return NO_SDE_INFO_MARK; } - SDE sde = (sdeRef == null) ? null : (SDE)sdeRef.get(); + SDE sde = (sdeRef == null) ? null : sdeRef.get(); if (sde == null) { String extension = null; try { @@ -1034,13 +1022,13 @@ implements ReferenceType { throw exc; } if (constantPoolBytesRef != null) { - byte[] cpbytes = (byte[])constantPoolBytesRef.get(); + byte[] cpbytes = constantPoolBytesRef.get(); /* * Arrays are always modifiable, so it is a little unsafe * to return the cached bytecodes directly; instead, we * make a clone at the cost of using more memory. */ - return (byte[])cpbytes.clone(); + return cpbytes.clone(); } else { return null; } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/SDE.java b/jdk/src/share/classes/com/sun/tools/jdi/SDE.java index dd054c1ba0c..6f46c81f811 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/SDE.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/SDE.java @@ -327,7 +327,7 @@ class SDE { ignoreWhite(); while (((ch = sdeRead()) != '\n') && (ch != '\r')) { - sb.append((char)ch); + sb.append(ch); } // check for CR LF if ((ch == '\r') && (sdePeek() == '\n')) { diff --git a/jdk/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java index 5cfd2cbc901..a6f867379a0 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java @@ -162,7 +162,7 @@ public class StackFrameImpl extends MirrorImpl for (LocalVariable variable : allVariables) { String name = variable.name(); if (variable.isVisible(this)) { - LocalVariable existing = (LocalVariable)map.get(name); + LocalVariable existing = map.get(name); if ((existing == null) || ((LocalVariableImpl)variable).hides(existing)) { map.put(name, variable); @@ -330,7 +330,7 @@ public class StackFrameImpl extends MirrorImpl slot = 1; } for (int ii = 0; ii < count; ++ii) { - char sigChar = (char)argSigs.get(ii).charAt(0); + char sigChar = argSigs.get(ii).charAt(0); slots[ii] = new JDWP.StackFrame.GetValues.SlotInfo(slot++,(byte)sigChar); if (sigChar == 'J' || sigChar == 'D') { slot++; diff --git a/jdk/src/share/classes/com/sun/tools/jdi/TargetVM.java b/jdk/src/share/classes/com/sun/tools/jdi/TargetVM.java index 2ff9bb1d126..54ae6af0de4 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/TargetVM.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/TargetVM.java @@ -148,7 +148,7 @@ public class TargetVM implements Runnable { idString = String.valueOf(p.id); synchronized(waitingQueue) { - p2 = (Packet)waitingQueue.get(idString); + p2 = waitingQueue.get(idString); if (p2 != null) waitingQueue.remove(idString); diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java index 4e1286ba2e4..8dac1f3a330 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java @@ -86,30 +86,22 @@ public class ThreadGroupReferenceImpl extends ObjectReferenceImpl } public void suspend() { - List threads = threads(); - Iterator iter = threads.iterator(); - while (iter.hasNext()) { - ((ThreadReference)iter.next()).suspend(); + for (ThreadReference thread : threads()) { + thread.suspend(); } - List groups = threadGroups(); - iter = groups.iterator(); - while (iter.hasNext()) { - ((ThreadGroupReference)iter.next()).suspend(); + for (ThreadGroupReference threadGroup : threadGroups()) { + threadGroup.suspend(); } } public void resume() { - List threads = threads(); - Iterator iter = threads.iterator(); - while (iter.hasNext()) { - ((ThreadReference)iter.next()).resume(); + for (ThreadReference thread : threads()) { + thread.resume(); } - List groups = threadGroups(); - iter = groups.iterator(); - while (iter.hasNext()) { - ((ThreadGroupReference)iter.next()).resume(); + for (ThreadGroupReference threadGroup : threadGroups()) { + threadGroup.resume(); } } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java index 54cb8974b72..e6dd311e152 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java @@ -1191,8 +1191,7 @@ class VirtualMachineImpl extends MirrorImpl } requests = new JDWP.VirtualMachine.DisposeObjects.Request[size]; for (int i = 0; i < requests.length; i++) { - SoftObjectReference ref = - (SoftObjectReference)batchedDisposeRequests.get(i); + SoftObjectReference ref = batchedDisposeRequests.get(i); if ((traceFlags & TRACE_OBJREFS) != 0) { printTrace("Disposing object " + ref.key().longValue() + " (ref count = " + ref.count() + ")"); @@ -1436,7 +1435,7 @@ class VirtualMachineImpl extends MirrorImpl } ObjectReferenceImpl object() { - return (ObjectReferenceImpl)get(); + return get(); } } } diff --git a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java index 97131841074..2efcdd65154 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java @@ -92,7 +92,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService { Connector connector; try { - connector = (Connector)connectors.next(); + connector = connectors.next(); } catch (ThreadDeath x) { throw x; } catch (Exception x) { @@ -121,7 +121,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService { TransportService transportService; try { - transportService = (TransportService)transportServices.next(); + transportService = transportServices.next(); } catch (ThreadDeath x) { throw x; } catch (Exception x) { diff --git a/jdk/src/share/classes/java/io/ObjectInputStream.java b/jdk/src/share/classes/java/io/ObjectInputStream.java index 9acc30cf7c1..d4dd289a3b3 100644 --- a/jdk/src/share/classes/java/io/ObjectInputStream.java +++ b/jdk/src/share/classes/java/io/ObjectInputStream.java @@ -212,7 +212,8 @@ public class ObjectInputStream private static final Object unsharedMarker = new Object(); /** table mapping primitive type names to corresponding class objects */ - private static final HashMap primClasses = new HashMap(8, 1.0F); + private static final HashMap> primClasses + = new HashMap>(8, 1.0F); static { primClasses.put("boolean", boolean.class); primClasses.put("byte", byte.class); @@ -620,7 +621,7 @@ public class ObjectInputStream try { return Class.forName(name, false, latestUserDefinedLoader()); } catch (ClassNotFoundException ex) { - Class cl = (Class) primClasses.get(name); + Class cl = primClasses.get(name); if (cl != null) { return cl; } else { @@ -1254,11 +1255,11 @@ public class ObjectInputStream * override security-sensitive non-final methods. Returns true if subclass * is "safe", false otherwise. */ - private static boolean auditSubclass(final Class subcl) { + private static boolean auditSubclass(final Class subcl) { Boolean result = AccessController.doPrivileged( new PrivilegedAction() { public Boolean run() { - for (Class cl = subcl; + for (Class cl = subcl; cl != ObjectInputStream.class; cl = cl.getSuperclass()) { @@ -2217,9 +2218,9 @@ public class ObjectInputStream try { while (list != null) { AccessController.doPrivileged( - new PrivilegedExceptionAction() + new PrivilegedExceptionAction() { - public Object run() throws InvalidObjectException { + public Void run() throws InvalidObjectException { list.obj.validateObject(); return null; } diff --git a/jdk/src/share/classes/java/io/ObjectStreamClass.java b/jdk/src/share/classes/java/io/ObjectStreamClass.java index 2a4553b11e9..af6da35458b 100644 --- a/jdk/src/share/classes/java/io/ObjectStreamClass.java +++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java @@ -77,7 +77,7 @@ public class ObjectStreamClass implements Serializable { NO_FIELDS; /** reflection factory for obtaining serialization constructors */ - private static final ReflectionFactory reflFactory = (ReflectionFactory) + private static final ReflectionFactory reflFactory = AccessController.doPrivileged( new ReflectionFactory.GetReflectionFactoryAction()); @@ -216,10 +216,10 @@ public class ObjectStreamClass implements Serializable { public long getSerialVersionUID() { // REMIND: synchronize instead of relying on volatile? if (suid == null) { - suid = (Long) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return Long.valueOf(computeDefaultSUID(cl)); + suid = AccessController.doPrivileged( + new PrivilegedAction() { + public Long run() { + return computeDefaultSUID(cl); } } ); @@ -392,8 +392,8 @@ public class ObjectStreamClass implements Serializable { } if (interrupted) { AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + new PrivilegedAction() { + public Void run() { Thread.currentThread().interrupt(); return null; } @@ -427,8 +427,8 @@ public class ObjectStreamClass implements Serializable { localDesc = this; if (serializable) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { if (isEnum) { suid = Long.valueOf(0); fields = NO_FIELDS; @@ -802,7 +802,7 @@ public class ObjectStreamClass implements Serializable { * non-primitive types, and any other non-null type matches assignable * types only. Returns matching field, or null if no match found. */ - ObjectStreamField getField(String name, Class type) { + ObjectStreamField getField(String name, Class type) { for (int i = 0; i < fields.length; i++) { ObjectStreamField f = fields[i]; if (f.getName().equals(name)) { @@ -811,7 +811,7 @@ public class ObjectStreamClass implements Serializable { { return f; } - Class ftype = f.getType(); + Class ftype = f.getType(); if (ftype != null && type.isAssignableFrom(ftype)) { return f; } @@ -1130,7 +1130,7 @@ public class ObjectStreamClass implements Serializable { private ClassDataSlot[] getClassDataLayout0() throws InvalidClassException { - ArrayList slots = new ArrayList(); + ArrayList slots = new ArrayList(); Class start = cl, end = cl; // locate closest non-serializable superclass @@ -1171,8 +1171,7 @@ public class ObjectStreamClass implements Serializable { // order slots from superclass -> subclass Collections.reverse(slots); - return (ClassDataSlot[]) - slots.toArray(new ClassDataSlot[slots.size()]); + return slots.toArray(new ClassDataSlot[slots.size()]); } /** @@ -1309,9 +1308,9 @@ public class ObjectStreamClass implements Serializable { * Access checks are disabled on the returned constructor (if any), since * the defining class may still be non-public. */ - private static Constructor getExternalizableConstructor(Class cl) { + private static Constructor getExternalizableConstructor(Class cl) { try { - Constructor cons = cl.getDeclaredConstructor((Class[]) null); + Constructor cons = cl.getDeclaredConstructor((Class[]) null); cons.setAccessible(true); return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ? cons : null; @@ -1325,15 +1324,15 @@ public class ObjectStreamClass implements Serializable { * superclass, or null if none found. Access checks are disabled on the * returned constructor (if any). */ - private static Constructor getSerializableConstructor(Class cl) { - Class initCl = cl; + private static Constructor getSerializableConstructor(Class cl) { + Class initCl = cl; while (Serializable.class.isAssignableFrom(initCl)) { if ((initCl = initCl.getSuperclass()) == null) { return null; } } try { - Constructor cons = initCl.getDeclaredConstructor((Class[]) null); + Constructor cons = initCl.getDeclaredConstructor((Class[]) null); int mods = cons.getModifiers(); if ((mods & Modifier.PRIVATE) != 0 || ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && @@ -1355,12 +1354,12 @@ public class ObjectStreamClass implements Serializable { * null if no match found. Access checks are disabled on the returned * method (if any). */ - private static Method getInheritableMethod(Class cl, String name, + private static Method getInheritableMethod(Class cl, String name, Class[] argTypes, Class returnType) { Method meth = null; - Class defCl = cl; + Class defCl = cl; while (defCl != null) { try { meth = defCl.getDeclaredMethod(name, argTypes); @@ -1391,9 +1390,9 @@ public class ObjectStreamClass implements Serializable { * class, or null if none found. Access checks are disabled on the * returned method (if any). */ - private static Method getPrivateMethod(Class cl, String name, - Class[] argTypes, - Class returnType) + private static Method getPrivateMethod(Class cl, String name, + Class[] argTypes, + Class returnType) { try { Method meth = cl.getDeclaredMethod(name, argTypes); @@ -1567,7 +1566,7 @@ public class ObjectStreamClass implements Serializable { ObjectStreamField[] boundFields = new ObjectStreamField[serialPersistentFields.length]; - Set fieldNames = new HashSet(serialPersistentFields.length); + Set fieldNames = new HashSet(serialPersistentFields.length); for (int i = 0; i < serialPersistentFields.length; i++) { ObjectStreamField spf = serialPersistentFields[i]; @@ -1605,7 +1604,7 @@ public class ObjectStreamClass implements Serializable { */ private static ObjectStreamField[] getDefaultSerialFields(Class cl) { Field[] clFields = cl.getDeclaredFields(); - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); int mask = Modifier.STATIC | Modifier.TRANSIENT; for (int i = 0; i < clFields.length; i++) { @@ -1615,7 +1614,7 @@ public class ObjectStreamClass implements Serializable { } int size = list.size(); return (size == 0) ? NO_FIELDS : - (ObjectStreamField[]) list.toArray(new ObjectStreamField[size]); + list.toArray(new ObjectStreamField[size]); } /** @@ -1688,11 +1687,9 @@ public class ObjectStreamClass implements Serializable { for (int i = 0; i < fields.length; i++) { fieldSigs[i] = new MemberSignature(fields[i]); } - Arrays.sort(fieldSigs, new Comparator() { - public int compare(Object o1, Object o2) { - String name1 = ((MemberSignature) o1).name; - String name2 = ((MemberSignature) o2).name; - return name1.compareTo(name2); + Arrays.sort(fieldSigs, new Comparator() { + public int compare(MemberSignature ms1, MemberSignature ms2) { + return ms1.name.compareTo(ms2.name); } }); for (int i = 0; i < fieldSigs.length; i++) { @@ -1721,11 +1718,9 @@ public class ObjectStreamClass implements Serializable { for (int i = 0; i < cons.length; i++) { consSigs[i] = new MemberSignature(cons[i]); } - Arrays.sort(consSigs, new Comparator() { - public int compare(Object o1, Object o2) { - String sig1 = ((MemberSignature) o1).signature; - String sig2 = ((MemberSignature) o2).signature; - return sig1.compareTo(sig2); + Arrays.sort(consSigs, new Comparator() { + public int compare(MemberSignature ms1, MemberSignature ms2) { + return ms1.signature.compareTo(ms2.signature); } }); for (int i = 0; i < consSigs.length; i++) { @@ -1746,10 +1741,8 @@ public class ObjectStreamClass implements Serializable { for (int i = 0; i < methods.length; i++) { methSigs[i] = new MemberSignature(methods[i]); } - Arrays.sort(methSigs, new Comparator() { - public int compare(Object o1, Object o2) { - MemberSignature ms1 = (MemberSignature) o1; - MemberSignature ms2 = (MemberSignature) o2; + Arrays.sort(methSigs, new Comparator() { + public int compare(MemberSignature ms1, MemberSignature ms2) { int comp = ms1.name.compareTo(ms2.name); if (comp == 0) { comp = ms1.signature.compareTo(ms2.signature); @@ -1859,7 +1852,7 @@ public class ObjectStreamClass implements Serializable { keys = new long[nfields]; offsets = new int[nfields]; typeCodes = new char[nfields]; - ArrayList typeList = new ArrayList(); + ArrayList> typeList = new ArrayList>(); for (int i = 0; i < nfields; i++) { ObjectStreamField f = fields[i]; @@ -1873,7 +1866,7 @@ public class ObjectStreamClass implements Serializable { } } - types = (Class[]) typeList.toArray(new Class[typeList.size()]); + types = typeList.toArray(new Class[typeList.size()]); numPrimFields = nfields - types.length; } diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index 6d878c56e78..632ddb6ed0e 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -345,9 +345,9 @@ public final // since we have to do the security check here anyway // (the stack depth is wrong for the Constructor's // security check to work) - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { c.setAccessible(true); return null; } @@ -1302,10 +1302,10 @@ public final // out anything other than public members and (2) public member access // has already been ok'd by the SecurityManager. - Class[] result = (Class[]) java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { - java.util.List list = new java.util.ArrayList(); + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Class[] run() { + List list = new ArrayList(); Class currentClass = Class.this; while (currentClass != null) { Class[] members = currentClass.getDeclaredClasses(); @@ -1316,12 +1316,9 @@ public final } currentClass = currentClass.getSuperclass(); } - Class[] empty = {}; - return list.toArray(empty); + return list.toArray(new Class[0]); } }); - - return result; } @@ -2215,15 +2212,15 @@ public final // Caches for certain reflective results private static boolean useCaches = true; - private volatile transient SoftReference declaredFields; - private volatile transient SoftReference publicFields; - private volatile transient SoftReference declaredMethods; - private volatile transient SoftReference publicMethods; - private volatile transient SoftReference declaredConstructors; - private volatile transient SoftReference publicConstructors; + private volatile transient SoftReference declaredFields; + private volatile transient SoftReference publicFields; + private volatile transient SoftReference declaredMethods; + private volatile transient SoftReference publicMethods; + private volatile transient SoftReference[]> declaredConstructors; + private volatile transient SoftReference[]> publicConstructors; // Intermediate results for getFields and getMethods - private volatile transient SoftReference declaredPublicFields; - private volatile transient SoftReference declaredPublicMethods; + private volatile transient SoftReference declaredPublicFields; + private volatile transient SoftReference declaredPublicMethods; // Incremented by the VM on each call to JVM TI RedefineClasses() // that redefines this class or a superclass. @@ -2295,11 +2292,11 @@ public final clearCachesOnClassRedefinition(); if (publicOnly) { if (declaredPublicFields != null) { - res = (Field[]) declaredPublicFields.get(); + res = declaredPublicFields.get(); } } else { if (declaredFields != null) { - res = (Field[]) declaredFields.get(); + res = declaredFields.get(); } } if (res != null) return res; @@ -2308,9 +2305,9 @@ public final res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicFields = new SoftReference(res); + declaredPublicFields = new SoftReference(res); } else { - declaredFields = new SoftReference(res); + declaredFields = new SoftReference(res); } } return res; @@ -2319,22 +2316,22 @@ public final // Returns an array of "root" fields. These Field objects must NOT // be propagated to the outside world, but must instead be copied // via ReflectionFactory.copyField. - private Field[] privateGetPublicFields(Set traversedInterfaces) { + private Field[] privateGetPublicFields(Set> traversedInterfaces) { checkInitted(); Field[] res = null; if (useCaches) { clearCachesOnClassRedefinition(); if (publicFields != null) { - res = (Field[]) publicFields.get(); + res = publicFields.get(); } if (res != null) return res; } // No cached value available; compute value recursively. // Traverse in correct order for getField(). - List fields = new ArrayList(); + List fields = new ArrayList(); if (traversedInterfaces == null) { - traversedInterfaces = new HashSet(); + traversedInterfaces = new HashSet>(); } // Local fields @@ -2342,9 +2339,7 @@ public final addAll(fields, tmp); // Direct superinterfaces, recursively - Class[] interfaces = getInterfaces(); - for (int i = 0; i < interfaces.length; i++) { - Class c = interfaces[i]; + for (Class c : getInterfaces()) { if (!traversedInterfaces.contains(c)) { traversedInterfaces.add(c); addAll(fields, c.privateGetPublicFields(traversedInterfaces)); @@ -2353,7 +2348,7 @@ public final // Direct superclass, recursively if (!isInterface()) { - Class c = getSuperclass(); + Class c = getSuperclass(); if (c != null) { addAll(fields, c.privateGetPublicFields(traversedInterfaces)); } @@ -2362,12 +2357,12 @@ public final res = new Field[fields.size()]; fields.toArray(res); if (useCaches) { - publicFields = new SoftReference(res); + publicFields = new SoftReference(res); } return res; } - private static void addAll(Collection c, Field[] o) { + private static void addAll(Collection c, Field[] o) { for (int i = 0; i < o.length; i++) { c.add(o[i]); } @@ -2383,18 +2378,18 @@ public final // Returns an array of "root" constructors. These Constructor // objects must NOT be propagated to the outside world, but must // instead be copied via ReflectionFactory.copyConstructor. - private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { + private Constructor[] privateGetDeclaredConstructors(boolean publicOnly) { checkInitted(); - Constructor[] res = null; + Constructor[] res = null; if (useCaches) { clearCachesOnClassRedefinition(); if (publicOnly) { if (publicConstructors != null) { - res = (Constructor[]) publicConstructors.get(); + res = publicConstructors.get(); } } else { if (declaredConstructors != null) { - res = (Constructor[]) declaredConstructors.get(); + res = declaredConstructors.get(); } } if (res != null) return res; @@ -2407,9 +2402,9 @@ public final } if (useCaches) { if (publicOnly) { - publicConstructors = new SoftReference(res); + publicConstructors = new SoftReference[]>(res); } else { - declaredConstructors = new SoftReference(res); + declaredConstructors = new SoftReference[]>(res); } } return res; @@ -2431,11 +2426,11 @@ public final clearCachesOnClassRedefinition(); if (publicOnly) { if (declaredPublicMethods != null) { - res = (Method[]) declaredPublicMethods.get(); + res = declaredPublicMethods.get(); } } else { if (declaredMethods != null) { - res = (Method[]) declaredMethods.get(); + res = declaredMethods.get(); } } if (res != null) return res; @@ -2444,9 +2439,9 @@ public final res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); if (useCaches) { if (publicOnly) { - declaredPublicMethods = new SoftReference(res); + declaredPublicMethods = new SoftReference(res); } else { - declaredMethods = new SoftReference(res); + declaredMethods = new SoftReference(res); } } return res; @@ -2552,7 +2547,7 @@ public final if (useCaches) { clearCachesOnClassRedefinition(); if (publicMethods != null) { - res = (Method[]) publicMethods.get(); + res = publicMethods.get(); } if (res != null) return res; } @@ -2602,7 +2597,7 @@ public final methods.compactAndTrim(); res = methods.getArray(); if (useCaches) { - publicMethods = new SoftReference(res); + publicMethods = new SoftReference(res); } return res; } @@ -2713,11 +2708,11 @@ public final private Constructor getConstructor0(Class[] parameterTypes, int which) throws NoSuchMethodException { - Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC)); - for (int i = 0; i < constructors.length; i++) { + Constructor[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC)); + for (Constructor constructor : constructors) { if (arrayContentsEq(parameterTypes, - constructors[i].getParameterTypes())) { - return getReflectionFactory().copyConstructor(constructors[i]); + constructor.getParameterTypes())) { + return getReflectionFactory().copyConstructor(constructor); } } throw new NoSuchMethodException(getName() + "." + argumentTypesToString(parameterTypes)); @@ -2767,18 +2762,18 @@ public final return out; } - private static Constructor[] copyConstructors(Constructor[] arg) { - Constructor[] out = new Constructor[arg.length]; + private static Constructor[] copyConstructors(Constructor[] arg) { + Constructor[] out = arg.clone(); ReflectionFactory fact = getReflectionFactory(); - for (int i = 0; i < arg.length; i++) { - out[i] = fact.copyConstructor(arg[i]); + for (int i = 0; i < out.length; i++) { + out[i] = fact.copyConstructor(out[i]); } return out; } private native Field[] getDeclaredFields0(boolean publicOnly); private native Method[] getDeclaredMethods0(boolean publicOnly); - private native Constructor[] getDeclaredConstructors0(boolean publicOnly); + private native Constructor[] getDeclaredConstructors0(boolean publicOnly); private native Class[] getDeclaredClasses0(); private static String argumentTypesToString(Class[] argTypes) { @@ -2883,7 +2878,7 @@ public final // Fetches the factory for reflective objects private static ReflectionFactory getReflectionFactory() { if (reflectionFactory == null) { - reflectionFactory = (ReflectionFactory) + reflectionFactory = java.security.AccessController.doPrivileged (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); } @@ -2895,8 +2890,8 @@ public final private static boolean initted = false; private static void checkInitted() { if (initted) return; - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { // Tests to ensure the system properties table is fully // initialized. This is needed because reflection code is // called very early in the initialization process (before @@ -2941,17 +2936,17 @@ public final /** * Returns the elements of this enum class or null if this * Class object does not represent an enum type; - * identical to getEnumConstantsShared except that - * the result is uncloned, cached, and shared by all callers. + * identical to getEnumConstants except that the result is + * uncloned, cached, and shared by all callers. */ T[] getEnumConstantsShared() { if (enumConstants == null) { if (!isEnum()) return null; try { final Method values = getMethod("values"); - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { values.setAccessible(true); return null; } diff --git a/jdk/src/share/classes/java/lang/ClassLoader.java b/jdk/src/share/classes/java/lang/ClassLoader.java index 391354ec38b..1b188e23f7c 100644 --- a/jdk/src/share/classes/java/lang/ClassLoader.java +++ b/jdk/src/share/classes/java/lang/ClassLoader.java @@ -39,6 +39,7 @@ import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; +import java.security.cert.Certificate; import java.util.Enumeration; import java.util.Hashtable; import java.util.HashMap; @@ -172,17 +173,18 @@ public abstract class ClassLoader { private ClassLoader parent; // Hashtable that maps packages to certs - private Hashtable package2certs = new Hashtable(11); + private Hashtable package2certs + = new Hashtable(11); // Shared among all packages with unsigned classes - java.security.cert.Certificate[] nocerts; + Certificate[] nocerts; // The classes loaded by this class loader. The only purpose of this table // is to keep the classes from being GC'ed until the loader is GC'ed. - private Vector classes = new Vector(); + private Vector> classes = new Vector>(); // The initiating protection domains for all classes loaded by this loader - private Set domains = new HashSet(); + private Set domains = new HashSet(); // Invoked by the VM to record every loaded class with this loader. void addClass(Class c) { @@ -191,7 +193,7 @@ public abstract class ClassLoader { // The packages defined in this class loader. Each package name is mapped // to its corresponding Package object. - private HashMap packages = new HashMap(); + private HashMap packages = new HashMap(); /** * Creates a new class loader using the specified parent class loader for @@ -342,8 +344,8 @@ public abstract class ClassLoader { final String name = cls.getName(); final int i = name.lastIndexOf('.'); if (i != -1) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { sm.checkPackageAccess(name.substring(0, i)); return null; } @@ -524,17 +526,20 @@ public abstract class ClassLoader { // Class format error - try to transform the bytecode and // define the class again // - Object[] transformers = ClassFileTransformer.getTransformers(); + ClassFileTransformer[] transformers = ClassFileTransformer.getTransformers(); Class c = null; - for (int i = 0; transformers != null && i < transformers.length; i++) { - try { - // Transform byte code using transformer - byte[] tb = ((ClassFileTransformer) transformers[i]).transform(b, off, len); - c = defineClass1(name, tb, 0, tb.length, protectionDomain, source); - break; - } catch (ClassFormatError cfe2) { - // If ClassFormatError occurs, try next transformer + if (transformers != null) { + for (ClassFileTransformer transformer : transformers) { + try { + // Transform byte code using transformer + byte[] tb = transformer.transform(b, off, len); + c = defineClass1(name, tb, 0, tb.length, + protectionDomain, source); + break; + } catch (ClassFormatError cfe2) { + // If ClassFormatError occurs, try next transformer + } } } @@ -550,7 +555,7 @@ public abstract class ClassLoader { private void postDefineClass(Class c, ProtectionDomain protectionDomain) { if (protectionDomain.getCodeSource() != null) { - java.security.cert.Certificate certs[] = + Certificate certs[] = protectionDomain.getCodeSource().getCertificates(); if (certs != null) setSigners(c, certs); @@ -767,8 +772,7 @@ public abstract class ClassLoader { private synchronized void checkCerts(String name, CodeSource cs) { int i = name.lastIndexOf('.'); String pname = (i == -1) ? "" : name.substring(0, i); - java.security.cert.Certificate[] pcerts = - (java.security.cert.Certificate[]) package2certs.get(pname); + Certificate[] pcerts = package2certs.get(pname); if (pcerts == null) { // first class in this package gets to define which // certificates must be the same for all other classes @@ -778,12 +782,12 @@ public abstract class ClassLoader { } if (pcerts == null) { if (nocerts == null) - nocerts = new java.security.cert.Certificate[0]; + nocerts = new Certificate[0]; pcerts = nocerts; } package2certs.put(pname, pcerts); } else { - java.security.cert.Certificate[] certs = null; + Certificate[] certs = null; if (cs != null) { certs = cs.getCertificates(); } @@ -799,8 +803,8 @@ public abstract class ClassLoader { * check to make sure the certs for the new class (certs) are the same as * the certs for the first class inserted in the package (pcerts) */ - private boolean compareCerts(java.security.cert.Certificate[] pcerts, - java.security.cert.Certificate[] certs) + private boolean compareCerts(Certificate[] pcerts, + Certificate[] certs) { // certs can be null, indicating no certs. if ((certs == null) || (certs.length == 0)) { @@ -1031,7 +1035,7 @@ public abstract class ClassLoader { } tmp[1] = findResources(name); - return new CompoundEnumeration(tmp); + return new CompoundEnumeration(tmp); } /** @@ -1068,7 +1072,7 @@ public abstract class ClassLoader { * @since 1.2 */ protected Enumeration findResources(String name) throws IOException { - return new CompoundEnumeration(new Enumeration[0]); + return java.util.Collections.emptyEnumeration(); } /** @@ -1134,13 +1138,13 @@ public abstract class ClassLoader { /** * Find resources from the VM's built-in classloader. */ - private static Enumeration getBootstrapResources(String name) + private static Enumeration getBootstrapResources(String name) throws IOException { - final Enumeration e = getBootstrapClassPath().getResources(name); - return new Enumeration () { - public Object nextElement() { - return ((Resource)e.nextElement()).getURL(); + final Enumeration e = getBootstrapClassPath().getResources(name); + return new Enumeration () { + public URL nextElement() { + return e.nextElement().getURL(); } public boolean hasMoreElements() { return e.hasMoreElements(); @@ -1323,9 +1327,8 @@ public abstract class ClassLoader { Throwable oops = null; scl = l.getClassLoader(); try { - PrivilegedExceptionAction a; - a = new SystemClassLoaderAction(scl); - scl = (ClassLoader) AccessController.doPrivileged(a); + scl = AccessController.doPrivileged( + new SystemClassLoaderAction(scl)); } catch (PrivilegedActionException pae) { oops = pae.getCause(); if (oops instanceof InvocationTargetException) { @@ -1456,7 +1459,7 @@ public abstract class ClassLoader { */ protected Package getPackage(String name) { synchronized (packages) { - Package pkg = (Package)packages.get(name); + Package pkg = packages.get(name); if (pkg == null) { if (parent != null) { pkg = parent.getPackage(name); @@ -1481,9 +1484,9 @@ public abstract class ClassLoader { * @since 1.2 */ protected Package[] getPackages() { - Map map; + Map map; synchronized (packages) { - map = (Map)packages.clone(); + map = new HashMap(packages); } Package[] pkgs; if (parent != null) { @@ -1499,7 +1502,7 @@ public abstract class ClassLoader { } } } - return (Package[])map.values().toArray(new Package[map.size()]); + return map.values().toArray(new Package[map.size()]); } @@ -1585,8 +1588,7 @@ public abstract class ClassLoader { // Invoked in the VM to determine the context class in // JNI_Load/JNI_Unload static Class getFromClass() { - return ((NativeLibrary) - (ClassLoader.nativeLibraryContext.peek())).fromClass; + return ClassLoader.nativeLibraryContext.peek().fromClass; } } @@ -1597,22 +1599,27 @@ public abstract class ClassLoader { // Returns (and initializes) the default domain. private synchronized ProtectionDomain getDefaultDomain() { if (defaultDomain == null) { - CodeSource cs = - new CodeSource(null, (java.security.cert.Certificate[]) null); + CodeSource cs = new CodeSource(null, (Certificate[]) null); defaultDomain = new ProtectionDomain(cs, null, this, null); } return defaultDomain; } // All native library names we've loaded. - private static Vector loadedLibraryNames = new Vector(); + private static Vector loadedLibraryNames + = new Vector(); + // Native libraries belonging to system classes. - private static Vector systemNativeLibraries = new Vector(); + private static Vector systemNativeLibraries + = new Vector(); + // Native libraries associated with the class loader. - private Vector nativeLibraries = new Vector(); + private Vector nativeLibraries + = new Vector(); // native libraries being loaded/unloaded. - private static Stack nativeLibraryContext = new Stack(); + private static Stack nativeLibraryContext + = new Stack(); // The paths searched for libraries static private String usr_paths[]; @@ -1699,13 +1706,13 @@ public abstract class ClassLoader { } private static boolean loadLibrary0(Class fromClass, final File file) { - Boolean exists = (Boolean) - AccessController.doPrivileged(new PrivilegedAction() { + boolean exists = AccessController.doPrivileged( + new PrivilegedAction() { public Object run() { - return new Boolean(file.exists()); - } - }); - if (!exists.booleanValue()) { + return file.exists() ? Boolean.TRUE : null; + }}) + != null; + if (!exists) { return false; } String name; @@ -1716,12 +1723,12 @@ public abstract class ClassLoader { } ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); - Vector libs = + Vector libs = loader != null ? loader.nativeLibraries : systemNativeLibraries; synchronized (libs) { int size = libs.size(); for (int i = 0; i < size; i++) { - NativeLibrary lib = (NativeLibrary)libs.elementAt(i); + NativeLibrary lib = libs.elementAt(i); if (name.equals(lib.name)) { return true; } @@ -1748,8 +1755,7 @@ public abstract class ClassLoader { */ int n = nativeLibraryContext.size(); for (int i = 0; i < n; i++) { - NativeLibrary lib = (NativeLibrary) - nativeLibraryContext.elementAt(i); + NativeLibrary lib = nativeLibraryContext.elementAt(i); if (name.equals(lib.name)) { if (loader == lib.fromClass.getClassLoader()) { return true; @@ -1780,12 +1786,12 @@ public abstract class ClassLoader { // Invoked in the VM class linking code. static long findNative(ClassLoader loader, String name) { - Vector libs = + Vector libs = loader != null ? loader.nativeLibraries : systemNativeLibraries; synchronized (libs) { int size = libs.size(); for (int i = 0; i < size; i++) { - NativeLibrary lib = (NativeLibrary)libs.elementAt(i); + NativeLibrary lib = libs.elementAt(i); long entry = lib.find(name); if (entry != 0) return entry; @@ -1805,13 +1811,13 @@ public abstract class ClassLoader { // is null then we are delegating assertion status queries to the VM, i.e., // none of this ClassLoader's assertion status modification methods have // been invoked. - private Map packageAssertionStatus = null; + private Map packageAssertionStatus = null; // Maps String fullyQualifiedClassName to Boolean assertionStatus If this // field is null then we are delegating assertion status queries to the VM, // i.e., none of this ClassLoader's assertion status modification methods // have been invoked. - Map classAssertionStatus = null; + Map classAssertionStatus = null; /** * Sets the default assertion status for this class loader. This setting @@ -1878,7 +1884,7 @@ public abstract class ClassLoader { if (packageAssertionStatus == null) initializeJavaAssertionMaps(); - packageAssertionStatus.put(packageName, Boolean.valueOf(enabled)); + packageAssertionStatus.put(packageName, enabled); } /** @@ -1909,7 +1915,7 @@ public abstract class ClassLoader { if (classAssertionStatus == null) initializeJavaAssertionMaps(); - classAssertionStatus.put(className, Boolean.valueOf(enabled)); + classAssertionStatus.put(className, enabled); } /** @@ -1927,8 +1933,8 @@ public abstract class ClassLoader { * Whether or not "Java assertion maps" are initialized, set * them to empty maps, effectively ignoring any present settings. */ - classAssertionStatus = new HashMap(); - packageAssertionStatus = new HashMap(); + classAssertionStatus = new HashMap(); + packageAssertionStatus = new HashMap(); defaultAssertionStatus = false; } @@ -1962,20 +1968,20 @@ public abstract class ClassLoader { // assert packageAssertionStatus != null; // Check for a class entry - result = (Boolean)classAssertionStatus.get(className); + result = classAssertionStatus.get(className); if (result != null) return result.booleanValue(); // Check for most specific package entry int dotIndex = className.lastIndexOf("."); if (dotIndex < 0) { // default package - result = (Boolean)packageAssertionStatus.get(null); + result = packageAssertionStatus.get(null); if (result != null) return result.booleanValue(); } while(dotIndex > 0) { className = className.substring(0, dotIndex); - result = (Boolean)packageAssertionStatus.get(className); + result = packageAssertionStatus.get(className); if (result != null) return result.booleanValue(); dotIndex = className.lastIndexOf(".", dotIndex-1); @@ -1989,17 +1995,17 @@ public abstract class ClassLoader { private void initializeJavaAssertionMaps() { // assert Thread.holdsLock(this); - classAssertionStatus = new HashMap(); - packageAssertionStatus = new HashMap(); + classAssertionStatus = new HashMap(); + packageAssertionStatus = new HashMap(); AssertionStatusDirectives directives = retrieveDirectives(); for(int i = 0; i < directives.classes.length; i++) classAssertionStatus.put(directives.classes[i], - Boolean.valueOf(directives.classEnabled[i])); + directives.classEnabled[i]); for(int i = 0; i < directives.packages.length; i++) packageAssertionStatus.put(directives.packages[i], - Boolean.valueOf(directives.packageEnabled[i])); + directives.packageEnabled[i]); defaultAssertionStatus = directives.deflt; } @@ -2009,28 +2015,24 @@ public abstract class ClassLoader { } -class SystemClassLoaderAction implements PrivilegedExceptionAction { +class SystemClassLoaderAction + implements PrivilegedExceptionAction { private ClassLoader parent; SystemClassLoaderAction(ClassLoader parent) { this.parent = parent; } - public Object run() throws Exception { - ClassLoader sys; - Constructor ctor; - Class c; - Class cp[] = { ClassLoader.class }; - Object params[] = { parent }; - + public ClassLoader run() throws Exception { String cls = System.getProperty("java.system.class.loader"); if (cls == null) { return parent; } - c = Class.forName(cls, true, parent); - ctor = c.getDeclaredConstructor(cp); - sys = (ClassLoader) ctor.newInstance(params); + Constructor ctor = Class.forName(cls, true, parent) + .getDeclaredConstructor(new Class[] { ClassLoader.class }); + ClassLoader sys = (ClassLoader) ctor.newInstance( + new Object[] { parent }); Thread.currentThread().setContextClassLoader(sys); return sys; } diff --git a/jdk/src/share/classes/java/lang/Compiler.java b/jdk/src/share/classes/java/lang/Compiler.java index 5c2ab73db28..85219174d7f 100644 --- a/jdk/src/share/classes/java/lang/Compiler.java +++ b/jdk/src/share/classes/java/lang/Compiler.java @@ -53,9 +53,9 @@ public final class Compiler { static { registerNatives(); - java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction() { - public Object run() { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { boolean loaded = false; String jit = System.getProperty("java.compiler"); if ((jit != null) && (!jit.equals("NONE")) && diff --git a/jdk/src/share/classes/java/lang/Long.java b/jdk/src/share/classes/java/lang/Long.java index 271fd1c02c8..2f0f172698e 100644 --- a/jdk/src/share/classes/java/lang/Long.java +++ b/jdk/src/share/classes/java/lang/Long.java @@ -650,7 +650,7 @@ public final class Long extends Number implements Comparable { try { result = Long.valueOf(nm.substring(index), radix); - result = negative ? new Long((long)-result.longValue()) : result; + result = negative ? new Long(-result.longValue()) : result; } catch (NumberFormatException e) { // If number is Long.MIN_VALUE, we'll end up here. The next line // handles this case, and causes any genuine format error to be diff --git a/jdk/src/share/classes/java/lang/Package.java b/jdk/src/share/classes/java/lang/Package.java index 80af5d9bc46..0d8779b6147 100644 --- a/jdk/src/share/classes/java/lang/Package.java +++ b/jdk/src/share/classes/java/lang/Package.java @@ -507,7 +507,7 @@ public class Package implements java.lang.reflect.AnnotatedElement { */ static Package getSystemPackage(String name) { synchronized (pkgs) { - Package pkg = (Package)pkgs.get(name); + Package pkg = pkgs.get(name); if (pkg == null) { name = name.replace('.', '/').concat("/"); String fn = getSystemPackage0(name); @@ -529,18 +529,18 @@ public class Package implements java.lang.reflect.AnnotatedElement { for (int i = 0; i < names.length; i++) { defineSystemPackage(names[i], getSystemPackage0(names[i])); } - return (Package[])pkgs.values().toArray(new Package[pkgs.size()]); + return pkgs.values().toArray(new Package[pkgs.size()]); } } private static Package defineSystemPackage(final String iname, final String fn) { - return (Package) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged(new PrivilegedAction() { + public Package run() { String name = iname; // Get the cached code source url for the file name - URL url = (URL)urls.get(fn); + URL url = urls.get(fn); if (url == null) { // URL not found, so create one File file = new File(fn); @@ -559,7 +559,7 @@ public class Package implements java.lang.reflect.AnnotatedElement { // Convert to "."-separated package name name = name.substring(0, name.length() - 1).replace('/', '.'); Package pkg; - Manifest man = (Manifest)mans.get(fn); + Manifest man = mans.get(fn); if (man != null) { pkg = new Package(name, man, url, null); } else { @@ -588,13 +588,16 @@ public class Package implements java.lang.reflect.AnnotatedElement { } // The map of loaded system packages - private static Map pkgs = new HashMap(31); + private static Map pkgs + = new HashMap(31); // Maps each directory or zip file name to its corresponding url - private static Map urls = new HashMap(10); + private static Map urls + = new HashMap(10); // Maps each code source url for a jar file to its manifest - private static Map mans = new HashMap(10); + private static Map mans + = new HashMap(10); private static native String getSystemPackage0(String name); private static native String[] getSystemPackages0(); diff --git a/jdk/src/share/classes/java/lang/ref/Finalizer.java b/jdk/src/share/classes/java/lang/ref/Finalizer.java index 76b5bd9454a..695d71d64a1 100644 --- a/jdk/src/share/classes/java/lang/ref/Finalizer.java +++ b/jdk/src/share/classes/java/lang/ref/Finalizer.java @@ -121,8 +121,9 @@ final class Finalizer extends FinalReference { /* Package-private; must be in invokers of these methods from a stalled or deadlocked finalizer thread. */ private static void forkSecondaryFinalizer(final Runnable proc) { - PrivilegedAction pa = new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Void run() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); for (ThreadGroup tgn = tg; tgn != null; @@ -135,8 +136,7 @@ final class Finalizer extends FinalReference { /* Package-private; must be in /* Ignore */ } return null; - }}; - AccessController.doPrivileged(pa); + }}); } /* Called by Runtime.runFinalization() */ diff --git a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java index 23f16927ae0..29889b08810 100644 --- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java +++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java @@ -165,9 +165,9 @@ public class AccessibleObject implements AnnotatedElement { // Reflection factory used by subclasses for creating field, // method, and constructor accessors. Note that this is called // very early in the bootstrapping process. - static final ReflectionFactory reflectionFactory = (ReflectionFactory) - AccessController.doPrivileged - (new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); + static final ReflectionFactory reflectionFactory = + AccessController.doPrivileged( + new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); /** * @throws NullPointerException {@inheritDoc} diff --git a/jdk/src/share/classes/java/lang/reflect/Modifier.java b/jdk/src/share/classes/java/lang/reflect/Modifier.java index e036927ef08..952fbe8011b 100644 --- a/jdk/src/share/classes/java/lang/reflect/Modifier.java +++ b/jdk/src/share/classes/java/lang/reflect/Modifier.java @@ -58,9 +58,8 @@ class Modifier { */ static { sun.reflect.ReflectionFactory factory = - (sun.reflect.ReflectionFactory) AccessController.doPrivileged( - new ReflectionFactory.GetReflectionFactoryAction() - ); + AccessController.doPrivileged( + new ReflectionFactory.GetReflectionFactoryAction()); factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess()); } diff --git a/jdk/src/share/classes/java/lang/reflect/Proxy.java b/jdk/src/share/classes/java/lang/reflect/Proxy.java index e9a1d40f95c..ffa6a6dcadd 100644 --- a/jdk/src/share/classes/java/lang/reflect/Proxy.java +++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.List; import java.util.WeakHashMap; import sun.misc.ProxyGenerator; @@ -230,7 +231,8 @@ public class Proxy implements java.io.Serializable { { InvocationHandler.class }; /** maps a class loader to the proxy class cache for that loader */ - private static Map loaderToCache = new WeakHashMap(); + private static Map, Object>> loaderToCache + = new WeakHashMap, Object>>(); /** marks that a particular proxy class is currently being generated */ private static Object pendingGenerationMarker = new Object(); @@ -240,8 +242,8 @@ public class Proxy implements java.io.Serializable { private static Object nextUniqueNumberLock = new Object(); /** set of all generated proxy classes, for isProxyClass implementation */ - private static Map proxyClasses = - Collections.synchronizedMap(new WeakHashMap()); + private static Map, Void> proxyClasses = + Collections.synchronizedMap(new WeakHashMap, Void>()); /** * the invocation handler for this proxy instance. @@ -353,7 +355,8 @@ public class Proxy implements java.io.Serializable { /* collect interface names to use as key for proxy class cache */ String[] interfaceNames = new String[interfaces.length]; - Set interfaceSet = new HashSet(); // for detecting duplicates + // for detecting duplicates + Set> interfaceSet = new HashSet>(); for (int i = 0; i < interfaces.length; i++) { /* @@ -401,16 +404,16 @@ public class Proxy implements java.io.Serializable { * representation of a class makes for an implicit weak * reference to the class. */ - Object key = Arrays.asList(interfaceNames); + List key = Arrays.asList(interfaceNames); /* * Find or create the proxy class cache for the class loader. */ - Map cache; + Map, Object> cache; synchronized (loaderToCache) { - cache = (Map) loaderToCache.get(loader); + cache = loaderToCache.get(loader); if (cache == null) { - cache = new HashMap(); + cache = new HashMap, Object>(); loaderToCache.put(loader, cache); } /* @@ -442,7 +445,7 @@ public class Proxy implements java.io.Serializable { do { Object value = cache.get(key); if (value instanceof Reference) { - proxyClass = (Class) ((Reference) value).get(); + proxyClass = (Class) ((Reference) value).get(); } if (proxyClass != null) { // proxy class already generated: return it @@ -544,7 +547,7 @@ public class Proxy implements java.io.Serializable { */ synchronized (cache) { if (proxyClass != null) { - cache.put(key, new WeakReference(proxyClass)); + cache.put(key, new WeakReference>(proxyClass)); } else { cache.remove(key); } @@ -595,14 +598,14 @@ public class Proxy implements java.io.Serializable { /* * Look up or generate the designated proxy class. */ - Class cl = getProxyClass(loader, interfaces); + Class cl = getProxyClass(loader, interfaces); /* * Invoke its constructor with the designated invocation handler. */ try { Constructor cons = cl.getConstructor(constructorParams); - return (Object) cons.newInstance(new Object[] { h }); + return cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { diff --git a/jdk/src/share/classes/java/net/DatagramSocket.java b/jdk/src/share/classes/java/net/DatagramSocket.java index 4a09fa3cc57..6082bcab9f2 100644 --- a/jdk/src/share/classes/java/net/DatagramSocket.java +++ b/jdk/src/share/classes/java/net/DatagramSocket.java @@ -287,8 +287,9 @@ class DatagramSocket implements java.io.Closeable { // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use // getDeclaredMethod, therefore we need permission to access the member try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws NoSuchMethodException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws NoSuchMethodException { Class[] cl = new Class[1]; cl[0] = DatagramPacket.class; impl.getClass().getDeclaredMethod("peekData", cl); diff --git a/jdk/src/share/classes/java/net/ServerSocket.java b/jdk/src/share/classes/java/net/ServerSocket.java index 8b632f665d6..2793b2f961e 100644 --- a/jdk/src/share/classes/java/net/ServerSocket.java +++ b/jdk/src/share/classes/java/net/ServerSocket.java @@ -247,8 +247,9 @@ class ServerSocket implements java.io.Closeable { // SocketImpl.connect() is a protected method, therefore we need to use // getDeclaredMethod, therefore we need permission to access the member try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws NoSuchMethodException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws NoSuchMethodException { Class[] cl = new Class[2]; cl[0] = SocketAddress.class; cl[1] = Integer.TYPE; diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index c02dd4e2855..48442541689 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -847,9 +847,9 @@ class Socket implements java.io.Closeable { final Socket s = this; InputStream is = null; try { - is = (InputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + is = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public InputStream run() throws IOException { return impl.getInputStream(); } }); @@ -887,9 +887,9 @@ class Socket implements java.io.Closeable { final Socket s = this; OutputStream os = null; try { - os = (OutputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + os = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public OutputStream run() throws IOException { return impl.getOutputStream(); } }); diff --git a/jdk/src/share/classes/java/net/SocksSocketImpl.java b/jdk/src/share/classes/java/net/SocksSocketImpl.java index df88e645be8..76e11e957f7 100644 --- a/jdk/src/share/classes/java/net/SocksSocketImpl.java +++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java @@ -78,8 +78,8 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { { try { AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { superConnectServer(host, port, timeout); cmdIn = getInputStream(); cmdOut = getOutputStream(); @@ -129,10 +129,10 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { String userName; String password = null; final InetAddress addr = InetAddress.getByName(server); - PasswordAuthentication pw = (PasswordAuthentication) + PasswordAuthentication pw = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public PasswordAuthentication run() { return Authenticator.requestPasswordAuthentication( server, addr, port, "SOCKS5", "SOCKS authentication", null); } @@ -339,10 +339,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector - ProxySelector sel = (ProxySelector) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + ProxySelector sel = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); @@ -652,10 +651,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector - ProxySelector sel = (ProxySelector) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + ProxySelector sel = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); @@ -701,8 +699,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { // Connects to the SOCKS server try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws Exception { cmdsock = new Socket(new PlainSocketImpl()); cmdsock.connect(new InetSocketAddress(server, port)); cmdIn = cmdsock.getInputStream(); @@ -731,8 +730,9 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts { } } else { try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws Exception { cmdsock = new Socket(new PlainSocketImpl()); cmdsock.connect(new InetSocketAddress(server, port)); cmdIn = cmdsock.getInputStream(); diff --git a/jdk/src/share/classes/java/net/URLClassLoader.java b/jdk/src/share/classes/java/net/URLClassLoader.java index 267a005d101..5a6cfefecb3 100644 --- a/jdk/src/share/classes/java/net/URLClassLoader.java +++ b/jdk/src/share/classes/java/net/URLClassLoader.java @@ -205,9 +205,9 @@ public class URLClassLoader extends SecureClassLoader { throws ClassNotFoundException { try { - return (Class) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws ClassNotFoundException { + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Class run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(".class"); Resource res = ucp.getResource(path, false); if (res != null) { @@ -376,9 +376,9 @@ public class URLClassLoader extends SecureClassLoader { /* * The same restriction to finding classes applies to resources */ - URL url = - (URL) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URL url = AccessController.doPrivileged( + new PrivilegedAction() { + public URL run() { return ucp.findResource(name, true); } }, acc); @@ -397,7 +397,7 @@ public class URLClassLoader extends SecureClassLoader { public Enumeration findResources(final String name) throws IOException { - final Enumeration e = ucp.findResources(name, true); + final Enumeration e = ucp.findResources(name, true); return new Enumeration() { private URL url = null; @@ -407,9 +407,9 @@ public class URLClassLoader extends SecureClassLoader { return true; } do { - URL u = (URL) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URL u = AccessController.doPrivileged( + new PrivilegedAction() { + public URL run() { if (!e.hasMoreElements()) return null; return e.nextElement(); @@ -515,8 +515,8 @@ public class URLClassLoader extends SecureClassLoader { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { final Permission fp = p; - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() throws SecurityException { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() throws SecurityException { sm.checkPermission(fp); return null; } @@ -544,9 +544,9 @@ public class URLClassLoader extends SecureClassLoader { // Save the caller's context AccessControlContext acc = AccessController.getContext(); // Need a privileged block to create the class loader - URLClassLoader ucl = - (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URLClassLoader ucl = AccessController.doPrivileged( + new PrivilegedAction() { + public URLClassLoader run() { return new FactoryURLClassLoader(urls, parent); } }); @@ -571,9 +571,9 @@ public class URLClassLoader extends SecureClassLoader { // Save the caller's context AccessControlContext acc = AccessController.getContext(); // Need a privileged block to create the class loader - URLClassLoader ucl = (URLClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + URLClassLoader ucl = AccessController.doPrivileged( + new PrivilegedAction() { + public URLClassLoader run() { return new FactoryURLClassLoader(urls); } }); diff --git a/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java b/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java index a227addacf2..196359bfd91 100644 --- a/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java +++ b/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java @@ -167,9 +167,9 @@ public abstract class SelectorProvider { synchronized (lock) { if (provider != null) return provider; - return (SelectorProvider)AccessController - .doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public SelectorProvider run() { if (loadProviderFromProperty()) return provider; if (loadProviderAsService()) diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationGroupDesc.java b/jdk/src/share/classes/java/rmi/activation/ActivationGroupDesc.java index a3627416851..41a25db97f2 100644 --- a/jdk/src/share/classes/java/rmi/activation/ActivationGroupDesc.java +++ b/jdk/src/share/classes/java/rmi/activation/ActivationGroupDesc.java @@ -263,7 +263,7 @@ public final class ActivationGroupDesc implements Serializable { * @since 1.2 */ public String[] getCommandOptions() { - return (String[]) options.clone(); + return options.clone(); } /** diff --git a/jdk/src/share/classes/java/rmi/dgc/VMID.java b/jdk/src/share/classes/java/rmi/dgc/VMID.java index bbfd169c011..9f7801aabd4 100644 --- a/jdk/src/share/classes/java/rmi/dgc/VMID.java +++ b/jdk/src/share/classes/java/rmi/dgc/VMID.java @@ -136,9 +136,9 @@ public final class VMID implements java.io.Serializable { /* * Get the local host's IP address. */ - byte[] addr = (byte[]) java.security.AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + byte[] addr = java.security.AccessController.doPrivileged( + new PrivilegedAction() { + public byte[] run() { try { return InetAddress.getLocalHost().getAddress(); } catch (Exception e) { diff --git a/jdk/src/share/classes/java/security/cert/TrustAnchor.java b/jdk/src/share/classes/java/security/cert/TrustAnchor.java index 9fdac7b2c98..cd4c3de7097 100644 --- a/jdk/src/share/classes/java/security/cert/TrustAnchor.java +++ b/jdk/src/share/classes/java/security/cert/TrustAnchor.java @@ -275,7 +275,7 @@ public class TrustAnchor { ncBytes = null; nc = null; } else { - ncBytes = (byte []) bytes.clone(); + ncBytes = bytes.clone(); // validate DER encoding try { nc = new NameConstraintsExtension(Boolean.FALSE, bytes); @@ -309,7 +309,7 @@ public class TrustAnchor { * or null if not set. */ public final byte [] getNameConstraints() { - return (ncBytes == null ? null : (byte []) ncBytes.clone()); + return ncBytes == null ? null : ncBytes.clone(); } /** diff --git a/jdk/src/share/classes/java/security/cert/X509CertSelector.java b/jdk/src/share/classes/java/security/cert/X509CertSelector.java index dbcdf017e76..6ec61c17d60 100644 --- a/jdk/src/share/classes/java/security/cert/X509CertSelector.java +++ b/jdk/src/share/classes/java/security/cert/X509CertSelector.java @@ -381,7 +381,7 @@ public class X509CertSelector implements CertSelector { if (subjectKeyID == null) { this.subjectKeyID = null; } else { - this.subjectKeyID = (byte[])subjectKeyID.clone(); + this.subjectKeyID = subjectKeyID.clone(); } } @@ -442,7 +442,7 @@ public class X509CertSelector implements CertSelector { if (authorityKeyID == null) { this.authorityKeyID = null; } else { - this.authorityKeyID = (byte[])authorityKeyID.clone(); + this.authorityKeyID = authorityKeyID.clone(); } } @@ -566,7 +566,7 @@ public class X509CertSelector implements CertSelector { subjectPublicKey = null; subjectPublicKeyBytes = null; } else { - subjectPublicKeyBytes = (byte[])key.clone(); + subjectPublicKeyBytes = key.clone(); subjectPublicKey = X509Key.parse(new DerValue(subjectPublicKeyBytes)); } } @@ -590,7 +590,7 @@ public class X509CertSelector implements CertSelector { if (keyUsage == null) { this.keyUsage = null; } else { - this.keyUsage = (boolean[])keyUsage.clone(); + this.keyUsage = keyUsage.clone(); } } @@ -1041,7 +1041,7 @@ public class X509CertSelector implements CertSelector { ncBytes = null; nc = null; } else { - ncBytes = (byte[])bytes.clone(); + ncBytes = bytes.clone(); nc = new NameConstraintsExtension(FALSE, bytes); } } @@ -1438,7 +1438,7 @@ public class X509CertSelector implements CertSelector { if (subjectKeyID == null) { return null; } - return (byte[])subjectKeyID.clone(); + return subjectKeyID.clone(); } /** @@ -1457,7 +1457,7 @@ public class X509CertSelector implements CertSelector { if (authorityKeyID == null) { return null; } - return (byte[])authorityKeyID.clone(); + return authorityKeyID.clone(); } /** @@ -1546,7 +1546,7 @@ public class X509CertSelector implements CertSelector { if (keyUsage == null) { return null; } - return (boolean[])keyUsage.clone(); + return keyUsage.clone(); } /** @@ -1736,7 +1736,7 @@ public class X509CertSelector implements CertSelector { if (ncBytes == null) { return null; } else { - return (byte[]) ncBytes.clone(); + return ncBytes.clone(); } } diff --git a/jdk/src/share/classes/java/util/ArrayList.java b/jdk/src/share/classes/java/util/ArrayList.java index 36c846e3b31..f769822ce81 100644 --- a/jdk/src/share/classes/java/util/ArrayList.java +++ b/jdk/src/share/classes/java/util/ArrayList.java @@ -892,7 +892,7 @@ public class ArrayList extends AbstractList private final AbstractList parent; private final int parentOffset; private final int offset; - private int size; + int size; SubList(AbstractList parent, int offset, int fromIndex, int toIndex) { @@ -971,6 +971,7 @@ public class ArrayList extends AbstractList public ListIterator listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); + final int offset = this.offset; return new ListIterator() { int cursor = index; diff --git a/jdk/src/share/classes/java/util/Arrays.java b/jdk/src/share/classes/java/util/Arrays.java index 3d103ad51b0..46744d2c6be 100644 --- a/jdk/src/share/classes/java/util/Arrays.java +++ b/jdk/src/share/classes/java/util/Arrays.java @@ -1088,7 +1088,7 @@ public class Arrays { * mutually comparable (for example, strings and integers). */ public static void sort(Object[] a) { - Object[] aux = (Object[])a.clone(); + Object[] aux = a.clone(); mergeSort(aux, a, 0, a.length, 0); } @@ -1216,7 +1216,7 @@ public class Arrays { * not mutually comparable using the specified comparator. */ public static void sort(T[] a, Comparator c) { - T[] aux = (T[])a.clone(); + T[] aux = a.clone(); if (c==null) mergeSort(aux, a, 0, a.length, 0); else @@ -1257,7 +1257,7 @@ public class Arrays { public static void sort(T[] a, int fromIndex, int toIndex, Comparator c) { rangeCheck(a.length, fromIndex, toIndex); - T[] aux = (T[])copyOfRange(a, fromIndex, toIndex); + T[] aux = copyOfRange(a, fromIndex, toIndex); if (c==null) mergeSort(aux, a, fromIndex, toIndex, -fromIndex); else @@ -4128,7 +4128,7 @@ public class Arrays { if (a.length != 0 && bufLen <= 0) bufLen = Integer.MAX_VALUE; StringBuilder buf = new StringBuilder(bufLen); - deepToString(a, buf, new HashSet()); + deepToString(a, buf, new HashSet()); return buf.toString(); } diff --git a/jdk/src/share/classes/java/util/EnumMap.java b/jdk/src/share/classes/java/util/EnumMap.java index 896e07d2833..867ccc7bc56 100644 --- a/jdk/src/share/classes/java/util/EnumMap.java +++ b/jdk/src/share/classes/java/util/EnumMap.java @@ -140,7 +140,7 @@ public class EnumMap, V> extends AbstractMap public EnumMap(EnumMap m) { keyType = m.keyType; keyUniverse = m.keyUniverse; - vals = (Object[]) m.vals.clone(); + vals = m.vals.clone(); size = m.size; } @@ -161,7 +161,7 @@ public class EnumMap, V> extends AbstractMap EnumMap em = (EnumMap) m; keyType = em.keyType; keyUniverse = em.keyUniverse; - vals = (Object[]) em.vals.clone(); + vals = em.vals.clone(); size = em.size; } else { if (m.isEmpty()) @@ -257,7 +257,7 @@ public class EnumMap, V> extends AbstractMap public V put(K key, V value) { typeCheck(key); - int index = ((Enum)key).ordinal(); + int index = key.ordinal(); Object oldValue = vals[index]; vals[index] = maskNull(value); if (oldValue == null) @@ -662,7 +662,7 @@ public class EnumMap, V> extends AbstractMap } catch(CloneNotSupportedException e) { throw new AssertionError(); } - result.vals = (Object[]) result.vals.clone(); + result.vals = result.vals.clone(); return result; } diff --git a/jdk/src/share/classes/java/util/IdentityHashMap.java b/jdk/src/share/classes/java/util/IdentityHashMap.java index 1898ccad515..8f0a0cd5c76 100644 --- a/jdk/src/share/classes/java/util/IdentityHashMap.java +++ b/jdk/src/share/classes/java/util/IdentityHashMap.java @@ -701,7 +701,7 @@ public class IdentityHashMap try { IdentityHashMap m = (IdentityHashMap) super.clone(); m.entrySet = null; - m.table = (Object[])table.clone(); + m.table = table.clone(); return m; } catch (CloneNotSupportedException e) { throw new InternalError(); @@ -975,7 +975,7 @@ public class IdentityHashMap */ public boolean removeAll(Collection c) { boolean modified = false; - for (Iterator i = iterator(); i.hasNext(); ) { + for (Iterator i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { i.remove(); modified = true; @@ -1033,7 +1033,7 @@ public class IdentityHashMap return containsValue(o); } public boolean remove(Object o) { - for (Iterator i = iterator(); i.hasNext(); ) { + for (Iterator i = iterator(); i.hasNext(); ) { if (i.next() == o) { i.remove(); return true; @@ -1121,7 +1121,7 @@ public class IdentityHashMap */ public boolean removeAll(Collection c) { boolean modified = false; - for (Iterator i = iterator(); i.hasNext(); ) { + for (Iterator> i = iterator(); i.hasNext(); ) { if (c.contains(i.next())) { i.remove(); modified = true; diff --git a/jdk/src/share/classes/java/util/JumboEnumSet.java b/jdk/src/share/classes/java/util/JumboEnumSet.java index 6512e2cd5c9..de72c5fc5f9 100644 --- a/jdk/src/share/classes/java/util/JumboEnumSet.java +++ b/jdk/src/share/classes/java/util/JumboEnumSet.java @@ -364,7 +364,7 @@ class JumboEnumSet> extends EnumSet { public EnumSet clone() { JumboEnumSet result = (JumboEnumSet) super.clone(); - result.elements = (long[]) result.elements.clone(); + result.elements = result.elements.clone(); return result; } } diff --git a/jdk/src/share/classes/java/util/Random.java b/jdk/src/share/classes/java/util/Random.java index b16b48532b2..f30feb934fe 100644 --- a/jdk/src/share/classes/java/util/Random.java +++ b/jdk/src/share/classes/java/util/Random.java @@ -504,7 +504,7 @@ class Random implements java.io.Serializable { // The seed is read in as {@code long} for // historical reasons, but it is converted to an AtomicLong. - long seedVal = (long) fields.get("seed", -1L); + long seedVal = fields.get("seed", -1L); if (seedVal < 0) throw new java.io.StreamCorruptedException( "Random: invalid seed"); diff --git a/jdk/src/share/classes/java/util/TreeSet.java b/jdk/src/share/classes/java/util/TreeSet.java index 81b02e3663a..c4d538e9593 100644 --- a/jdk/src/share/classes/java/util/TreeSet.java +++ b/jdk/src/share/classes/java/util/TreeSet.java @@ -195,7 +195,7 @@ public class TreeSet extends AbstractSet * @since 1.6 */ public NavigableSet descendingSet() { - return new TreeSet(m.descendingMap()); + return new TreeSet(m.descendingMap()); } /** @@ -505,8 +505,8 @@ public class TreeSet extends AbstractSet s.writeInt(m.size()); // Write out all elements in the proper order. - for (Iterator i=m.keySet().iterator(); i.hasNext(); ) - s.writeObject(i.next()); + for (E e : m.keySet()) + s.writeObject(e); } /** diff --git a/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java b/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java index 029133714ea..ebf975ccfd8 100644 --- a/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java +++ b/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java @@ -155,7 +155,8 @@ public abstract class AbstractPreferences extends Preferences { * All known unremoved children of this node. (This "cache" is consulted * prior to calling childSpi() or getChild(). */ - private Map kidCache = new HashMap(); + private Map kidCache + = new HashMap(); /** * This field is used to keep track of whether or not this node has @@ -712,11 +713,10 @@ public abstract class AbstractPreferences extends Preferences { if (removed) throw new IllegalStateException("Node has been removed."); - Set s = new TreeSet(kidCache.keySet()); - String[] kids = childrenNamesSpi(); - for(int i=0; i s = new TreeSet(kidCache.keySet()); + for (String kid : childrenNamesSpi()) + s.add(kid); + return s.toArray(EMPTY_STRING_ARRAY); } } @@ -728,8 +728,7 @@ public abstract class AbstractPreferences extends Preferences { * @return all known unremoved children of this node. */ protected final AbstractPreferences[] cachedChildren() { - return (AbstractPreferences[]) kidCache.values(). - toArray(EMPTY_ABSTRACT_PREFS_ARRAY); + return kidCache.values().toArray(EMPTY_ABSTRACT_PREFS_ARRAY); } private static final AbstractPreferences[] EMPTY_ABSTRACT_PREFS_ARRAY @@ -825,7 +824,7 @@ public abstract class AbstractPreferences extends Preferences { if (token.equals("/")) // Check for consecutive slashes throw new IllegalArgumentException("Consecutive slashes in path"); synchronized(lock) { - AbstractPreferences child=(AbstractPreferences)kidCache.get(token); + AbstractPreferences child = kidCache.get(token); if (child == null) { if (token.length() > MAX_NAME_LENGTH) throw new IllegalArgumentException( @@ -893,7 +892,7 @@ public abstract class AbstractPreferences extends Preferences { if (token.equals("/")) // Check for consecutive slashes throw new IllegalArgumentException("Consecutive slashes in path"); synchronized(lock) { - AbstractPreferences child=(AbstractPreferences)kidCache.get(token); + AbstractPreferences child = kidCache.get(token); if (child == null) child = getChild(token); if (child==null) @@ -964,9 +963,10 @@ public abstract class AbstractPreferences extends Preferences { kidCache.put(kidNames[i], childSpi(kidNames[i])); // Recursively remove all cached children - for (Iterator i = kidCache.values().iterator(); i.hasNext();) { + for (Iterator i = kidCache.values().iterator(); + i.hasNext();) { try { - ((AbstractPreferences)i.next()).removeNode2(); + i.next().removeNode2(); i.remove(); } catch (BackingStoreException x) { } } @@ -1020,13 +1020,12 @@ public abstract class AbstractPreferences extends Preferences { * preference tree. */ public boolean isUserNode() { - Boolean result = (Boolean) - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - return Boolean.valueOf(root == Preferences.userRoot()); + return AccessController.doPrivileged( + new PrivilegedAction() { + public Boolean run() { + return root == Preferences.userRoot(); } - }); - return result.booleanValue(); + }).booleanValue(); } public void addPreferenceChangeListener(PreferenceChangeListener pcl) { @@ -1443,7 +1442,8 @@ public abstract class AbstractPreferences extends Preferences { * event delivery from preference activity, greatly simplifying * locking and reducing opportunity for deadlock. */ - private static final List eventQueue = new LinkedList(); + private static final List eventQueue + = new LinkedList(); /** * These two classes are used to distinguish NodeChangeEvents on @@ -1476,7 +1476,7 @@ public abstract class AbstractPreferences extends Preferences { try { while (eventQueue.isEmpty()) eventQueue.wait(); - event = (EventObject) eventQueue.remove(0); + event = eventQueue.remove(0); } catch (InterruptedException e) { // XXX Log "Event dispatch thread interrupted. Exiting" return; diff --git a/jdk/src/share/classes/java/util/regex/Matcher.java b/jdk/src/share/classes/java/util/regex/Matcher.java index 5dc6caa19d2..60dabaa279a 100644 --- a/jdk/src/share/classes/java/util/regex/Matcher.java +++ b/jdk/src/share/classes/java/util/regex/Matcher.java @@ -249,7 +249,7 @@ public final class Matcher implements MatchResult { Matcher result = new Matcher(this.parentPattern, text.toString()); result.first = this.first; result.last = this.last; - result.groups = (int[])(this.groups.clone()); + result.groups = this.groups.clone(); return result; } diff --git a/jdk/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java b/jdk/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java index cf569ef5bde..9d266fac861 100644 --- a/jdk/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java +++ b/jdk/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java @@ -121,7 +121,7 @@ public class SslRMIClientSocketFactory sslSocketFactory.createSocket(host, port); // Set the SSLSocket Enabled Cipher Suites // - final String enabledCipherSuites = (String) + final String enabledCipherSuites = System.getProperty("javax.rmi.ssl.client.enabledCipherSuites"); if (enabledCipherSuites != null) { StringTokenizer st = new StringTokenizer(enabledCipherSuites, ","); @@ -139,7 +139,7 @@ public class SslRMIClientSocketFactory } // Set the SSLSocket Enabled Protocols // - final String enabledProtocols = (String) + final String enabledProtocols = System.getProperty("javax.rmi.ssl.client.enabledProtocols"); if (enabledProtocols != null) { StringTokenizer st = new StringTokenizer(enabledProtocols, ","); diff --git a/jdk/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java b/jdk/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java index 27e8b2f2af9..802e1668b86 100644 --- a/jdk/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java +++ b/jdk/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java @@ -165,9 +165,9 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { // Initialize the configuration parameters. // this.enabledCipherSuites = enabledCipherSuites == null ? - null : (String[]) enabledCipherSuites.clone(); + null : enabledCipherSuites.clone(); this.enabledProtocols = enabledProtocols == null ? - null : (String[]) enabledProtocols.clone(); + null : enabledProtocols.clone(); this.needClientAuth = needClientAuth; // Force the initialization of the default at construction time, @@ -196,13 +196,11 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { // if (this.enabledCipherSuites != null) { sslSocket.setEnabledCipherSuites(this.enabledCipherSuites); - enabledCipherSuitesList = - Arrays.asList((String[]) this.enabledCipherSuites); + enabledCipherSuitesList = Arrays.asList(this.enabledCipherSuites); } if (this.enabledProtocols != null) { sslSocket.setEnabledProtocols(this.enabledProtocols); - enabledProtocolsList = - Arrays.asList((String[]) this.enabledProtocols); + enabledProtocolsList = Arrays.asList(this.enabledProtocols); } } @@ -218,7 +216,7 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { */ public final String[] getEnabledCipherSuites() { return enabledCipherSuites == null ? - null : (String[]) enabledCipherSuites.clone(); + null : enabledCipherSuites.clone(); } /** @@ -234,7 +232,7 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { */ public final String[] getEnabledProtocols() { return enabledProtocols == null ? - null : (String[]) enabledProtocols.clone(); + null : enabledProtocols.clone(); } /** @@ -315,8 +313,8 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { (enabledCipherSuites != null && that.enabledCipherSuites == null)) return false; if (enabledCipherSuites != null && that.enabledCipherSuites != null) { - List thatEnabledCipherSuitesList = - Arrays.asList((String[]) that.enabledCipherSuites); + List thatEnabledCipherSuitesList = + Arrays.asList(that.enabledCipherSuites); if (!enabledCipherSuitesList.equals(thatEnabledCipherSuitesList)) return false; } @@ -327,8 +325,8 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { (enabledProtocols != null && that.enabledProtocols == null)) return false; if (enabledProtocols != null && that.enabledProtocols != null) { - List thatEnabledProtocolsList = - Arrays.asList((String[]) that.enabledProtocols); + List thatEnabledProtocolsList = + Arrays.asList(that.enabledProtocols); if (!enabledProtocolsList.equals(thatEnabledProtocolsList)) return false; } @@ -374,7 +372,7 @@ public class SslRMIServerSocketFactory implements RMIServerSocketFactory { private final String[] enabledCipherSuites; private final String[] enabledProtocols; private final boolean needClientAuth; - private List enabledCipherSuitesList; - private List enabledProtocolsList; + private List enabledCipherSuitesList; + private List enabledProtocolsList; private SSLContext context; } diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java index 1879e5c4bf2..39463424984 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java @@ -276,7 +276,7 @@ public class KerberosTicket implements Destroyable, Refreshable, if (flags != null) { if (flags.length >= NUM_FLAGS) - this.flags = (boolean[]) flags.clone(); + this.flags = flags.clone(); else { this.flags = new boolean[NUM_FLAGS]; // Fill in whatever we have @@ -304,7 +304,7 @@ public class KerberosTicket implements Destroyable, Refreshable, this.endTime = endTime; if (clientAddresses != null) - this.clientAddresses = (InetAddress[]) clientAddresses.clone(); + this.clientAddresses = clientAddresses.clone(); } /** @@ -430,7 +430,7 @@ public class KerberosTicket implements Destroyable, Refreshable, * @return the flags associated with this ticket. */ public final boolean[] getFlags() { - return (flags == null? null: (boolean[]) flags.clone()); + return (flags == null? null: flags.clone()); } /** @@ -479,8 +479,7 @@ public class KerberosTicket implements Destroyable, Refreshable, * provided. */ public final java.net.InetAddress[] getClientAddresses() { - return (clientAddresses == null? - null: (InetAddress[]) clientAddresses.clone()); + return (clientAddresses == null) ? null: clientAddresses.clone(); } /** @@ -491,7 +490,7 @@ public class KerberosTicket implements Destroyable, Refreshable, public final byte[] getEncoded() { if (destroyed) throw new IllegalStateException("This ticket is no longer valid"); - return (byte[]) asn1Encoding.clone(); + return asn1Encoding.clone(); } /** Determines if this ticket is still current. */ diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java index 5937fd53cac..6fcffbdeecc 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java @@ -66,7 +66,7 @@ class KeyImpl implements SecretKey, Destroyable, Serializable { */ public KeyImpl(byte[] keyBytes, int keyType) { - this.keyBytes = (byte[]) keyBytes.clone(); + this.keyBytes = keyBytes.clone(); this.keyType = keyType; } @@ -151,7 +151,7 @@ class KeyImpl implements SecretKey, Destroyable, Serializable { public final byte[] getEncoded() { if (destroyed) throw new IllegalStateException("This key is no longer valid"); - return (byte[])keyBytes.clone(); + return keyBytes.clone(); } public void destroy() throws DestroyFailedException { diff --git a/jdk/src/share/classes/sun/misc/ClassFileTransformer.java b/jdk/src/share/classes/sun/misc/ClassFileTransformer.java index a0d2c84ed6f..1d05f71cc8a 100644 --- a/jdk/src/share/classes/sun/misc/ClassFileTransformer.java +++ b/jdk/src/share/classes/sun/misc/ClassFileTransformer.java @@ -46,8 +46,10 @@ public abstract class ClassFileTransformer { // Singleton of ClassFileTransformer // - private static ArrayList transformerList = new ArrayList(); - private static Object[] transformers = new Object[0]; + private static ArrayList transformerList + = new ArrayList(); + private static ClassFileTransformer[] transformers + = new ClassFileTransformer[0]; /** * Add the class file transformer object. @@ -59,7 +61,7 @@ public abstract class ClassFileTransformer synchronized(transformerList) { transformerList.add(t); - transformers = transformerList.toArray(); + transformers = transformerList.toArray(new ClassFileTransformer[0]); } } @@ -68,7 +70,7 @@ public abstract class ClassFileTransformer * * @return ClassFileTransformer object array */ - public static Object[] getTransformers() + public static ClassFileTransformer[] getTransformers() { // transformers is not intended to be changed frequently, // so it is okay to not put synchronized block here diff --git a/jdk/src/share/classes/sun/misc/Cleaner.java b/jdk/src/share/classes/sun/misc/Cleaner.java index c6cd63697b4..036b6c94cd0 100644 --- a/jdk/src/share/classes/sun/misc/Cleaner.java +++ b/jdk/src/share/classes/sun/misc/Cleaner.java @@ -141,8 +141,8 @@ public class Cleaner try { thunk.run(); } catch (final Throwable x) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { if (System.err != null) new Error("Cleaner terminated abnormally", x) .printStackTrace(); diff --git a/jdk/src/share/classes/sun/misc/ExtensionDependency.java b/jdk/src/share/classes/sun/misc/ExtensionDependency.java index ce2df19f3ea..67012641e62 100644 --- a/jdk/src/share/classes/sun/misc/ExtensionDependency.java +++ b/jdk/src/share/classes/sun/misc/ExtensionDependency.java @@ -284,10 +284,9 @@ public class ExtensionDependency { // Load the jar file ... Manifest man; try { - man = (Manifest) AccessController.doPrivileged - ( - new PrivilegedExceptionAction() { - public Object run() + man = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Manifest run() throws IOException, FileNotFoundException { if (!file.exists()) throw new FileNotFoundException(file.getName()); @@ -391,9 +390,9 @@ public class ExtensionDependency { final String extName = extensionName; final String[] fileExt = {".jar", ".zip"}; - return (File) AccessController.doPrivileged - (new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public File run() { try { File fExtension; File[] dirs = getExtDirs(); @@ -460,7 +459,7 @@ public class ExtensionDependency { * @return the list of files installed in all the directories */ private static File[] getExtFiles(File[] dirs) throws IOException { - Vector urls = new Vector(); + Vector urls = new Vector(); for (int i = 0; i < dirs.length; i++) { String[] files = dirs[i].list(new JarFilter()); if (files != null) { @@ -484,16 +483,15 @@ public class ExtensionDependency { *

    */ private File[] getInstalledExtensions() throws IOException { - return (File[]) AccessController.doPrivileged - ( - new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public File[] run() { try { return getExtFiles(getExtDirs()); } catch(IOException e) { debug("Cannot get list of installed extensions"); debugException(e); - return new URL[0]; + return new File[0]; } } }); diff --git a/jdk/src/share/classes/sun/misc/GC.java b/jdk/src/share/classes/sun/misc/GC.java index b3fd3f97712..477b5ffad91 100644 --- a/jdk/src/share/classes/sun/misc/GC.java +++ b/jdk/src/share/classes/sun/misc/GC.java @@ -128,8 +128,8 @@ public class GC { /* Create a new daemon thread in the root thread group */ public static void create() { - PrivilegedAction pa = new PrivilegedAction() { - public Object run() { + PrivilegedAction pa = new PrivilegedAction() { + public Void run() { ThreadGroup tg = Thread.currentThread().getThreadGroup(); for (ThreadGroup tgn = tg; tgn != null; @@ -170,13 +170,14 @@ public class GC { * method. Given a request, the only interesting operation is that of * cancellation. */ - public static class LatencyRequest implements Comparable { + public static class LatencyRequest + implements Comparable { /* Instance counter, used to generate unique identifers */ private static long counter = 0; /* Sorted set of active latency requests */ - private static SortedSet requests = null; + private static SortedSet requests = null; /* Examine the request set and reset the latency target if necessary. * Must be invoked while holding the lock. @@ -187,7 +188,7 @@ public class GC { setLatencyTarget(NO_TARGET); } } else { - LatencyRequest r = (LatencyRequest)requests.first(); + LatencyRequest r = requests.first(); if (r.latency != latencyTarget) { setLatencyTarget(r.latency); } @@ -211,7 +212,7 @@ public class GC { synchronized (lock) { this.id = ++counter; if (requests == null) { - requests = new TreeSet(); + requests = new TreeSet(); } requests.add(this); adjustLatencyIfNeeded(); @@ -240,8 +241,7 @@ public class GC { } } - public int compareTo(Object o) { - LatencyRequest r = (LatencyRequest)o; + public int compareTo(LatencyRequest r) { long d = this.latency - r.latency; if (d == 0) d = this.id - r.id; return (d < 0) ? -1 : ((d > 0) ? +1 : 0); diff --git a/jdk/src/share/classes/sun/misc/Launcher.java b/jdk/src/share/classes/sun/misc/Launcher.java index fca66090433..26f84d62819 100644 --- a/jdk/src/share/classes/sun/misc/Launcher.java +++ b/jdk/src/share/classes/sun/misc/Launcher.java @@ -135,9 +135,9 @@ public class Launcher { // aa synthesized ACC via a call to the private method // ExtClassLoader.getContext(). - return (ExtClassLoader) AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public ExtClassLoader run() throws IOException { int len = dirs.length; for (int i = 0; i < len; i++) { MetaIndex.registerDirectory(dirs[i]); @@ -180,7 +180,7 @@ public class Launcher { } private static URL[] getExtURLs(File[] dirs) throws IOException { - Vector urls = new Vector(); + Vector urls = new Vector(); for (int i = 0; i < dirs.length; i++) { String[] files = dirs[i].list(); if (files != null) { @@ -261,9 +261,9 @@ public class Launcher { // when loading classes. Specifically it prevent // accessClassInPackage.sun.* grants from being honored. // - return (AppClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public AppClassLoader run() { URL[] urls = (s == null) ? new URL[0] : pathToURLs(path); return new AppClassLoader(urls, extcl); @@ -348,12 +348,12 @@ public class Launcher { URL[] urls; if (prop != null) { final String path = prop; - urls = (URL[])AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + urls = AccessController.doPrivileged( + new PrivilegedAction() { + public URL[] run() { File[] classPath = getClassPath(path); int len = classPath.length; - Set seenDirs = new HashSet(); + Set seenDirs = new HashSet(); for (int i = 0; i < len; i++) { File curEntry = classPath[i]; // Negative test used to properly handle @@ -509,8 +509,8 @@ class PathPermissions extends PermissionCollection { perms.add(new java.util.PropertyPermission("java.*", SecurityConstants.PROPERTY_READ_ACTION)); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { for (int i=0; i < path.length; i++) { File f = path[i]; String path; @@ -553,7 +553,7 @@ class PathPermissions extends PermissionCollection { return perms.implies(permission); } - public java.util.Enumeration elements() { + public java.util.Enumeration elements() { if (perms == null) init(); synchronized (perms) { diff --git a/jdk/src/share/classes/sun/misc/PerformanceLogger.java b/jdk/src/share/classes/sun/misc/PerformanceLogger.java index 5f121845388..e23a0f1abb4 100644 --- a/jdk/src/share/classes/sun/misc/PerformanceLogger.java +++ b/jdk/src/share/classes/sun/misc/PerformanceLogger.java @@ -78,7 +78,7 @@ public class PerformanceLogger { private static boolean perfLoggingOn = false; private static boolean useNanoTime = false; - private static Vector times; + private static Vector times; private static String logFileName = null; private static Writer logWriter = null; @@ -104,8 +104,8 @@ public class PerformanceLogger { if (logFileName != null) { if (logWriter == null) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { try { File logFile = new File(logFileName); logFile.createNewFile(); @@ -124,7 +124,7 @@ public class PerformanceLogger { logWriter = new OutputStreamWriter(System.out); } } - times = new Vector(10); + times = new Vector(10); // Reserve predefined slots for (int i = 0; i <= LAST_RESERVED; ++i) { times.add(new TimeData("Time " + i + " not set", 0)); @@ -207,7 +207,7 @@ public class PerformanceLogger { */ public static long getStartTime() { if (loggingEnabled()) { - return ((TimeData)times.get(START_INDEX)).getTime(); + return times.get(START_INDEX).getTime(); } else { return 0; } @@ -253,7 +253,7 @@ public class PerformanceLogger { */ public static long getTimeAtIndex(int index) { if (loggingEnabled()) { - return ((TimeData)times.get(index)).getTime(); + return times.get(index).getTime(); } else { return 0; } @@ -264,7 +264,7 @@ public class PerformanceLogger { */ public static String getMessageAtIndex(int index) { if (loggingEnabled()) { - return ((TimeData)times.get(index)).getMessage(); + return times.get(index).getMessage(); } else { return null; } @@ -278,7 +278,7 @@ public class PerformanceLogger { try { synchronized(times) { for (int i = 0; i < times.size(); ++i) { - TimeData td = (TimeData)times.get(i); + TimeData td = times.get(i); if (td != null) { writer.write(i + " " + td.getMessage() + ": " + td.getTime() + "\n"); diff --git a/jdk/src/share/classes/sun/misc/ProxyGenerator.java b/jdk/src/share/classes/sun/misc/ProxyGenerator.java index 42350461eca..d25a87c1b4a 100644 --- a/jdk/src/share/classes/sun/misc/ProxyGenerator.java +++ b/jdk/src/share/classes/sun/misc/ProxyGenerator.java @@ -324,8 +324,8 @@ public class ProxyGenerator { if (saveGeneratedFiles) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { try { FileOutputStream file = new FileOutputStream(dotToSlash(name) + ".class"); @@ -576,7 +576,7 @@ public class ProxyGenerator { * compatibly with the throws clauses of both * overridden methods. */ - List legalExceptions = new ArrayList(); + List> legalExceptions = new ArrayList>(); collectCompatibleTypes( exceptionTypes, pm.exceptionTypes, legalExceptions); collectCompatibleTypes( @@ -618,11 +618,11 @@ public class ProxyGenerator { * List of return types that are not yet known to be * assignable from ("covered" by) any of the others. */ - LinkedList uncoveredReturnTypes = new LinkedList(); + LinkedList> uncoveredReturnTypes = new LinkedList>(); nextNewReturnType: for (ProxyMethod pm : methods) { - Class newReturnType = pm.returnType; + Class newReturnType = pm.returnType; if (newReturnType.isPrimitive()) { throw new IllegalArgumentException( "methods with same signature " + @@ -637,9 +637,9 @@ public class ProxyGenerator { * Compare the new return type to the existing uncovered * return types. */ - ListIterator liter = uncoveredReturnTypes.listIterator(); + ListIterator> liter = uncoveredReturnTypes.listIterator(); while (liter.hasNext()) { - Class uncoveredReturnType = liter.next(); + Class uncoveredReturnType = liter.next(); /* * If an existing uncovered return type is assignable @@ -944,10 +944,10 @@ public class ProxyGenerator { tryEnd = pc = (short) minfo.code.size(); - List catchList = computeUniqueCatchList(exceptionTypes); + List> catchList = computeUniqueCatchList(exceptionTypes); if (catchList.size() > 0) { - for (Class ex : catchList) { + for (Class ex : catchList) { minfo.exceptionTable.add(new ExceptionTableEntry( tryBegin, tryEnd, pc, cp.getClass(dotToSlash(ex.getName())))); @@ -1521,8 +1521,9 @@ public class ProxyGenerator { * declared exceptions from duplicate methods inherited from * different interfaces. */ - private static void collectCompatibleTypes(Class[] from, Class[] with, - List list) + private static void collectCompatibleTypes(Class[] from, + Class[] with, + List> list) { for (int i = 0; i < from.length; i++) { if (!list.contains(from[i])) { @@ -1557,8 +1558,8 @@ public class ProxyGenerator { * given list of declared exceptions, indicating that no exceptions * need to be caught. */ - private static List computeUniqueCatchList(Class[] exceptions) { - List uniqueList = new ArrayList(); + private static List> computeUniqueCatchList(Class[] exceptions) { + List> uniqueList = new ArrayList>(); // unique exceptions to catch uniqueList.add(Error.class); // always catch/rethrow these @@ -1566,7 +1567,7 @@ public class ProxyGenerator { nextException: for (int i = 0; i < exceptions.length; i++) { - Class ex = exceptions[i]; + Class ex = exceptions[i]; if (ex.isAssignableFrom(Throwable.class)) { /* * If Throwable is declared to be thrown by the proxy method, @@ -1586,7 +1587,7 @@ public class ProxyGenerator { * exceptions that need to be caught: */ for (int j = 0; j < uniqueList.size();) { - Class ex2 = uniqueList.get(j); + Class ex2 = uniqueList.get(j); if (ex2.isAssignableFrom(ex)) { /* * if a superclass of this exception is already on diff --git a/jdk/src/share/classes/sun/misc/URLClassPath.java b/jdk/src/share/classes/sun/misc/URLClassPath.java index 3aefe401db8..b3bd6d38a9e 100644 --- a/jdk/src/share/classes/sun/misc/URLClassPath.java +++ b/jdk/src/share/classes/sun/misc/URLClassPath.java @@ -86,16 +86,16 @@ public class URLClassPath { } /* The original search path of URLs. */ - private ArrayList path = new ArrayList(); + private ArrayList path = new ArrayList(); /* The stack of unopened URLs */ - Stack urls = new Stack(); + Stack urls = new Stack(); /* The resulting search path of Loaders */ - ArrayList loaders = new ArrayList(); + ArrayList loaders = new ArrayList(); /* Map of each URL opened to its corresponding Loader */ - HashMap lmap = new HashMap(); + HashMap lmap = new HashMap(); /* The jar protocol handler to use when creating new URLs */ private URLStreamHandler jarHandler; @@ -146,7 +146,7 @@ public class URLClassPath { */ public URL[] getURLs() { synchronized (urls) { - return (URL[])path.toArray(new URL[path.size()]); + return path.toArray(new URL[path.size()]); } } @@ -200,9 +200,9 @@ public class URLClassPath { * @param name the resource name * @return an Enumeration of all the urls having the specified name */ - public Enumeration findResources(final String name, + public Enumeration findResources(final String name, final boolean check) { - return new Enumeration() { + return new Enumeration() { private int index = 0; private URL url = null; @@ -225,7 +225,7 @@ public class URLClassPath { return next(); } - public Object nextElement() { + public URL nextElement() { if (!next()) { throw new NoSuchElementException(); } @@ -247,9 +247,9 @@ public class URLClassPath { * @param name the resource name * @return an Enumeration of all the resources having the specified name */ - public Enumeration getResources(final String name, + public Enumeration getResources(final String name, final boolean check) { - return new Enumeration() { + return new Enumeration() { private int index = 0; private Resource res = null; @@ -272,7 +272,7 @@ public class URLClassPath { return next(); } - public Object nextElement() { + public Resource nextElement() { if (!next()) { throw new NoSuchElementException(); } @@ -283,7 +283,7 @@ public class URLClassPath { }; } - public Enumeration getResources(final String name) { + public Enumeration getResources(final String name) { return getResources(name, true); } @@ -302,7 +302,7 @@ public class URLClassPath { if (urls.empty()) { return null; } else { - url = (URL)urls.pop(); + url = urls.pop(); } } // Skip this URL if it already has a Loader. (Loader @@ -329,7 +329,7 @@ public class URLClassPath { loaders.add(loader); lmap.put(url, loader); } - return (Loader)loaders.get(index); + return loaders.get(index); } /* @@ -337,9 +337,9 @@ public class URLClassPath { */ private Loader getLoader(final URL url) throws IOException { try { - return (Loader)java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public Loader run() throws IOException { String file = url.getFile(); if (file != null && file.endsWith("/")) { if ("file".equals(url.getProtocol())) { @@ -561,13 +561,14 @@ public class URLClassPath { private JarIndex index; private MetaIndex metaIndex; private URLStreamHandler handler; - private HashMap lmap; + private HashMap lmap; /* * Creates a new JarLoader for the specified URL referring to * a JAR file. */ - JarLoader(URL url, URLStreamHandler jarHandler, HashMap loaderMap) + JarLoader(URL url, URLStreamHandler jarHandler, + HashMap loaderMap) throws IOException { super(new URL("jar", "", -1, url + "!/", jarHandler)); @@ -615,8 +616,8 @@ public class URLClassPath { if (jar == null) { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { if (DEBUG) { System.err.println("Opening " + csu); Thread.dumpStack(); @@ -732,9 +733,9 @@ public class URLClassPath { String entryName; ZipEntry entry; - Enumeration enum_ = jar.entries(); + Enumeration enum_ = jar.entries(); while (enum_.hasMoreElements()) { - entry = (ZipEntry)enum_.nextElement(); + entry = enum_.nextElement(); entryName = entry.getName(); if((pos = entryName.lastIndexOf("/")) != -1) entryName = entryName.substring(0, pos); @@ -778,7 +779,7 @@ public class URLClassPath { if (index == null) return null; - HashSet visited = new HashSet(); + HashSet visited = new HashSet(); return getResource(name, check, visited); } @@ -790,7 +791,7 @@ public class URLClassPath { * non-existent resource */ Resource getResource(final String name, boolean check, - Set visited) { + Set visited) { Resource res; Object[] jarFiles; @@ -819,10 +820,9 @@ public class URLClassPath { /* no loader has been set up for this jar file * before */ - newLoader = (JarLoader) - AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { + newLoader = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public JarLoader run() throws IOException { return new JarLoader(url, handler, lmap); } diff --git a/jdk/src/share/classes/sun/net/NetProperties.java b/jdk/src/share/classes/sun/net/NetProperties.java index c2c7eb54e2a..a94f20c2ae3 100644 --- a/jdk/src/share/classes/sun/net/NetProperties.java +++ b/jdk/src/share/classes/sun/net/NetProperties.java @@ -42,8 +42,8 @@ public class NetProperties { static private Properties props = new Properties(); static { AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + new PrivilegedAction() { + public Void run() { loadDefaultProperties(); return null; }}); diff --git a/jdk/src/share/classes/sun/net/NetworkClient.java b/jdk/src/share/classes/sun/net/NetworkClient.java index 6e49e4c30fd..321b71bf650 100644 --- a/jdk/src/share/classes/sun/net/NetworkClient.java +++ b/jdk/src/share/classes/sun/net/NetworkClient.java @@ -64,8 +64,8 @@ public class NetworkClient { final String encs[] = { null }; AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + new PrivilegedAction() { + public Void run() { vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue(); vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue(); encs[0] = System.getProperty("file.encoding", "ISO8859_1"); @@ -152,9 +152,9 @@ public class NetworkClient { Socket s; if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { - s = (Socket) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + s = AccessController.doPrivileged( + new PrivilegedAction() { + public Socket run() { return new Socket(proxy); }}); } else diff --git a/jdk/src/share/classes/sun/net/ftp/FtpClient.java b/jdk/src/share/classes/sun/net/ftp/FtpClient.java index 52458a68870..9a7c99d517d 100644 --- a/jdk/src/share/classes/sun/net/ftp/FtpClient.java +++ b/jdk/src/share/classes/sun/net/ftp/FtpClient.java @@ -117,8 +117,8 @@ public class FtpClient extends TransferProtocolClient { public static int getFtpProxyPort() { final int result[] = {80}; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { String tmp = System.getProperty("ftp.proxyPort"); if (tmp == null) { @@ -343,9 +343,9 @@ public class FtpClient extends TransferProtocolClient { Socket s; if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { - s = (Socket) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + s = AccessController.doPrivileged( + new PrivilegedAction() { + public Socket run() { return new Socket(proxy); }}); } else diff --git a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java index 425c884fef6..6d69c49bfb6 100644 --- a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java +++ b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java @@ -82,9 +82,9 @@ public class DefaultProxySelector extends ProxySelector { static { final String key = "java.net.useSystemProxies"; - Boolean b = (Boolean) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + Boolean b = AccessController.doPrivileged( + new PrivilegedAction() { + public Boolean run() { return NetProperties.getBoolean(key); }}); if (b != null && b.booleanValue()) { @@ -197,9 +197,9 @@ public class DefaultProxySelector extends ProxySelector { * System properties it does help having only 1 call to doPrivileged. * Be mindful what you do in here though! */ - Proxy p = (Proxy) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + Proxy p = AccessController.doPrivileged( + new PrivilegedAction() { + public Proxy run() { int i, j; String phost = null; int pport = 0; diff --git a/jdk/src/share/classes/sun/net/www/MessageHeader.java b/jdk/src/share/classes/sun/net/www/MessageHeader.java index 02fb42cd4b5..c02374d589e 100644 --- a/jdk/src/share/classes/sun/net/www/MessageHeader.java +++ b/jdk/src/share/classes/sun/net/www/MessageHeader.java @@ -138,7 +138,7 @@ class MessageHeader { return null; } - class HeaderIterator implements Iterator { + class HeaderIterator implements Iterator { int index = 0; int next = -1; String key; @@ -165,7 +165,7 @@ class MessageHeader { return false; } } - public Object next() { + public String next() { synchronized (lock) { if (haveNext) { haveNext = false; @@ -187,17 +187,17 @@ class MessageHeader { * return an Iterator that returns all values of a particular * key in sequence */ - public Iterator multiValueIterator (String k) { + public Iterator multiValueIterator (String k) { return new HeaderIterator (k, this); } - public synchronized Map getHeaders() { + public synchronized Map> getHeaders() { return getHeaders(null); } - public synchronized Map getHeaders(String[] excludeList) { + public synchronized Map> getHeaders(String[] excludeList) { boolean skipIt = false; - Map m = new HashMap(); + Map> m = new HashMap>(); for (int i = nkeys; --i >= 0;) { if (excludeList != null) { // check if the key is in the excludeList. @@ -211,9 +211,9 @@ class MessageHeader { } } if (!skipIt) { - List l = (List)m.get(keys[i]); + List l = m.get(keys[i]); if (l == null) { - l = new ArrayList(); + l = new ArrayList(); m.put(keys[i], l); } l.add(values[i]); @@ -223,11 +223,8 @@ class MessageHeader { } } - Set keySet = m.keySet(); - for (Iterator i = keySet.iterator(); i.hasNext();) { - Object key = i.next(); - List l = (List)m.get(key); - m.put(key, Collections.unmodifiableList(l)); + for (String key : m.keySet()) { + m.put(key, Collections.unmodifiableList(m.get(key))); } return Collections.unmodifiableMap(m); diff --git a/jdk/src/share/classes/sun/net/www/MimeTable.java b/jdk/src/share/classes/sun/net/www/MimeTable.java index 291cf0586eb..6018fbf4641 100644 --- a/jdk/src/share/classes/sun/net/www/MimeTable.java +++ b/jdk/src/share/classes/sun/net/www/MimeTable.java @@ -37,18 +37,20 @@ import java.util.StringTokenizer; public class MimeTable implements FileNameMap { /** Keyed by content type, returns MimeEntries */ - private Hashtable entries = new Hashtable(); + private Hashtable entries + = new Hashtable(); /** Keyed by file extension (with the .), returns MimeEntries */ - private Hashtable extensionMap = new Hashtable(); + private Hashtable extensionMap + = new Hashtable(); // Will be reset if in the platform-specific data file private static String tempFileTemplate; static { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { tempFileTemplate = System.getProperty("content.types.temp.file.template", "/tmp/%s"); @@ -60,7 +62,8 @@ public class MimeTable implements FileNameMap { "/usr/etc/mailcap", "/usr/local/etc/mailcap", System.getProperty("hotjava.home", - "/usr/local/hotjava") + "/lib/mailcap", + "/usr/local/hotjava") + + "/lib/mailcap", }; return null; } @@ -83,8 +86,8 @@ public class MimeTable implements FileNameMap { public static MimeTable getDefaultTable() { if (defaultInstance == null) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { defaultInstance = new MimeTable(); URLConnection.setFileNameMap(defaultInstance); return null; @@ -130,7 +133,7 @@ public class MimeTable implements FileNameMap { } public synchronized MimeEntry remove(String type) { - MimeEntry entry = (MimeEntry)entries.get(type); + MimeEntry entry = entries.get(type); return remove(entry); } @@ -142,16 +145,16 @@ public class MimeTable implements FileNameMap { } } - return (MimeEntry)entries.remove(entry.getType()); + return entries.remove(entry.getType()); } public synchronized MimeEntry find(String type) { - MimeEntry entry = (MimeEntry)entries.get(type); + MimeEntry entry = entries.get(type); if (entry == null) { // try a wildcard lookup - Enumeration e = entries.elements(); + Enumeration e = entries.elements(); while (e.hasMoreElements()) { - MimeEntry wild = (MimeEntry)e.nextElement(); + MimeEntry wild = e.nextElement(); if (wild.matches(type)) { return wild; } @@ -191,13 +194,13 @@ public class MimeTable implements FileNameMap { * with it. */ public synchronized MimeEntry findByExt(String fileExtension) { - return (MimeEntry)extensionMap.get(fileExtension); + return extensionMap.get(fileExtension); } public synchronized MimeEntry findByDescription(String description) { - Enumeration e = elements(); + Enumeration e = elements(); while (e.hasMoreElements()) { - MimeEntry entry = (MimeEntry)e.nextElement(); + MimeEntry entry = e.nextElement(); if (description.equals(entry.getDescription())) { return entry; } @@ -211,7 +214,7 @@ public class MimeTable implements FileNameMap { return tempFileTemplate; } - public synchronized Enumeration elements() { + public synchronized Enumeration elements() { return entries.elements(); } @@ -269,7 +272,7 @@ public class MimeTable implements FileNameMap { } // now, parse the mime-type spec's - Enumeration types = entries.propertyNames(); + Enumeration types = entries.propertyNames(); while (types.hasMoreElements()) { String type = (String)types.nextElement(); String attrs = entries.getProperty(type); @@ -392,9 +395,9 @@ public class MimeTable implements FileNameMap { public Properties getAsProperties() { Properties properties = new Properties(); - Enumeration e = elements(); + Enumeration e = elements(); while (e.hasMoreElements()) { - MimeEntry entry = (MimeEntry)e.nextElement(); + MimeEntry entry = e.nextElement(); properties.put(entry.getType(), entry.toProperty()); } diff --git a/jdk/src/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/share/classes/sun/net/www/http/HttpClient.java index 674a88336e4..7f0cf0d4273 100644 --- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java +++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java @@ -230,9 +230,9 @@ public class HttpClient extends NetworkClient { setConnectTimeout(to); // get the cookieHandler if there is any - cookieHandler = (CookieHandler)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + cookieHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public CookieHandler run() { return CookieHandler.getDefault(); } }); @@ -297,7 +297,7 @@ public class HttpClient extends NetworkClient { HttpClient ret = null; /* see if one's already around */ if (useCache) { - ret = (HttpClient) kac.get(url, null); + ret = kac.get(url, null); if (ret != null) { if ((ret.proxy != null && ret.proxy.equals(p)) || (ret.proxy == null && p == null)) { @@ -389,7 +389,7 @@ public class HttpClient extends NetworkClient { * cache). */ public void closeIdleConnection() { - HttpClient http = (HttpClient) kac.get(url, null); + HttpClient http = kac.get(url, null); if (http != null) { http.closeServer(); } @@ -447,8 +447,8 @@ public class HttpClient extends NetworkClient { { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { openServer(server.getHostString(), server.getPort()); return null; } @@ -477,9 +477,8 @@ public class HttpClient extends NetworkClient { { try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException - { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { superOpenServer(proxyHost, proxyPort); return null; } @@ -686,7 +685,7 @@ public class HttpClient extends NetworkClient { // So we do put the cast in as a workaround until // it is resolved. if (uri != null) - cookieHandler.put(uri, (Map>)responses.getHeaders()); + cookieHandler.put(uri, responses.getHeaders()); } /* decide if we're keeping alive: diff --git a/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java b/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java index 1226b251013..93882397a11 100644 --- a/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java +++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java @@ -38,7 +38,9 @@ import java.util.concurrent.ConcurrentHashMap; * @author Stephen R. Pietrowicz (NCSA) * @author Dave Brown */ -public class KeepAliveCache extends ConcurrentHashMap implements Runnable { +public class KeepAliveCache + extends ConcurrentHashMap + implements Runnable { private static final long serialVersionUID = -2937172892064557949L; /* maximum # keep-alive connections to maintain at once @@ -88,12 +90,12 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { * back from the server. If I'm connected through a Netscape proxy * to a server that sent me a keep-alive * time of 15 sec, the proxy unilaterally terminates my connection - * The robustness to to get around this is in HttpClient.parseHTTP() + * The robustness to get around this is in HttpClient.parseHTTP() */ final KeepAliveCache cache = this; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { // We want to create the Keep-Alive-Timer in the // system threadgroup ThreadGroup grp = Thread.currentThread().getThreadGroup(); @@ -112,7 +114,7 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } KeepAliveKey key = new KeepAliveKey(url, obj); - ClientVector v = (ClientVector)super.get(key); + ClientVector v = super.get(key); if (v == null) { int keepAliveTimeout = http.getKeepAliveTimeout(); @@ -125,10 +127,10 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } } - /* remove an obsolete HttpClient from it's VectorCache */ + /* remove an obsolete HttpClient from its VectorCache */ public synchronized void remove (HttpClient h, Object obj) { KeepAliveKey key = new KeepAliveKey(h.url, obj); - ClientVector v = (ClientVector)super.get(key); + ClientVector v = super.get(key); if (v != null) { v.remove(h); if (v.empty()) { @@ -137,7 +139,7 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } } - /* called by a clientVector thread when all it's connections have timed out + /* called by a clientVector thread when all its connections have timed out * and that vector of connections should be removed. */ synchronized void removeVector(KeepAliveKey k) { @@ -147,10 +149,10 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { /** * Check to see if this URL has a cached HttpClient */ - public synchronized Object get(URL url, Object obj) { + public synchronized HttpClient get(URL url, Object obj) { KeepAliveKey key = new KeepAliveKey(url, obj); - ClientVector v = (ClientVector)super.get(key); + ClientVector v = super.get(key); if (v == null) { // nothing in cache yet return null; } @@ -180,17 +182,16 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { long currentTime = System.currentTimeMillis(); - Iterator itr = keySet().iterator(); - ArrayList keysToRemove = new ArrayList(); + ArrayList keysToRemove + = new ArrayList(); - while (itr.hasNext()) { - KeepAliveKey key = (KeepAliveKey)itr.next(); - ClientVector v = (ClientVector)get(key); + for (KeepAliveKey key : keySet()) { + ClientVector v = get(key); synchronized (v) { int i; for (i = 0; i < v.size(); i++) { - KeepAliveEntry e = (KeepAliveEntry)v.elementAt(i); + KeepAliveEntry e = v.elementAt(i); if ((currentTime - e.idleStartTime) > v.nap) { HttpClient h = e.hc; h.closeServer(); @@ -205,9 +206,9 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { } } } - itr = keysToRemove.iterator(); - while (itr.hasNext()) { - removeVector((KeepAliveKey)itr.next()); + + for (KeepAliveKey key : keysToRemove) { + removeVector(key); } } } while (size() > 0); @@ -234,7 +235,7 @@ public class KeepAliveCache extends ConcurrentHashMap implements Runnable { */ -class ClientVector extends java.util.Stack { +class ClientVector extends java.util.Stack { private static final long serialVersionUID = -8680532108106489459L; // sleep time in milliseconds, before cache clear @@ -254,7 +255,7 @@ class ClientVector extends java.util.Stack { HttpClient hc = null; long currentTime = System.currentTimeMillis(); do { - KeepAliveEntry e = (KeepAliveEntry)pop(); + KeepAliveEntry e = pop(); if ((currentTime - e.idleStartTime) > nap) { e.hc.closeServer(); } else { diff --git a/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java b/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java index 779afb5ad7b..08fc3b03b17 100644 --- a/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java +++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java @@ -174,8 +174,8 @@ class KeepAliveStream extends MeteredStream implements Hurryable { if (startCleanupThread) { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { // We want to create the Keep-Alive-SocketCleaner in the // system threadgroup ThreadGroup grp = Thread.currentThread().getThreadGroup(); diff --git a/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java b/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java index 779e38ac9ea..3ae7cff0fdf 100644 --- a/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java +++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java @@ -59,19 +59,19 @@ public class KeepAliveStreamCleaner extends LinkedBlockingQueue() { + public Integer run() { + return NetProperties.getInteger(maxDataKey, MAX_DATA_REMAINING); + }}).intValue() * 1024; MAX_DATA_REMAINING = maxData; final String maxCapacityKey = "http.KeepAlive.queuedConnections"; - int maxCapacity = ((Integer) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return new Integer(NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY)); - }})).intValue(); + int maxCapacity = AccessController.doPrivileged( + new PrivilegedAction() { + public Integer run() { + return NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY); + }}).intValue(); MAX_CAPACITY = maxCapacity; } diff --git a/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java index 44473d421d8..3661090f806 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java @@ -215,12 +215,11 @@ public class FtpURLConnection extends URLConnection { Proxy p = null; if (instProxy == null) { // no per connection proxy specified /** - * Do we have to use a proxie? + * Do we have to use a proxy? */ - ProxySelector sel = (ProxySelector) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + ProxySelector sel = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index fb1f3b05ed1..af0bd046f4c 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -144,8 +144,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { static { maxRedirects = java.security.AccessController.doPrivileged( - new sun.security.action.GetIntegerAction("http.maxRedirects", - defaultmaxRedirects)).intValue(); + new sun.security.action.GetIntegerAction( + "http.maxRedirects", defaultmaxRedirects)).intValue(); version = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("java.version")); String agent = java.security.AccessController.doPrivileged( @@ -291,10 +291,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection { final String scheme, final URL url, final RequestorType authType) { - return (PasswordAuthentication) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public PasswordAuthentication run() { return Authenticator.requestPasswordAuthentication( host, addr, port, protocol, prompt, scheme, url, authType); @@ -559,15 +558,15 @@ public class HttpURLConnection extends java.net.HttpURLConnection { responses = new MessageHeader(); this.handler = handler; instProxy = p; - cookieHandler = (CookieHandler)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + cookieHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public CookieHandler run() { return CookieHandler.getDefault(); } }); - cacheHandler = (ResponseCache)java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + cacheHandler = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public ResponseCache run() { return ResponseCache.getDefault(); } }); @@ -650,8 +649,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { final boolean result[] = {false}; java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { try { InetAddress a1 = InetAddress.getByName(h1); InetAddress a2 = InetAddress.getByName(h2); @@ -729,10 +728,10 @@ public class HttpURLConnection extends java.net.HttpURLConnection { /** * Do we have to use a proxy? */ - ProxySelector sel = (ProxySelector) + ProxySelector sel = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public ProxySelector run() { return ProxySelector.getDefault(); } }); @@ -908,25 +907,23 @@ public class HttpURLConnection extends java.net.HttpURLConnection { URI uri = ParseUtil.toURI(url); if (uri != null) { - Map cookies = cookieHandler.get(uri, requests.getHeaders(EXCLUDE_HEADERS)); + Map> cookies + = cookieHandler.get( + uri, requests.getHeaders(EXCLUDE_HEADERS)); if (!cookies.isEmpty()) { - Set s = cookies.entrySet(); - Iterator k_itr = s.iterator(); - while (k_itr.hasNext()) { - Map.Entry entry = (Map.Entry)k_itr.next(); - String key = (String)entry.getKey(); + for (Map.Entry> entry : + cookies.entrySet()) { + String key = entry.getKey(); // ignore all entries that don't have "Cookie" // or "Cookie2" as keys if (!"Cookie".equalsIgnoreCase(key) && !"Cookie2".equalsIgnoreCase(key)) { continue; } - List l = (List)entry.getValue(); + List l = entry.getValue(); if (l != null && !l.isEmpty()) { - Iterator v_itr = l.iterator(); StringBuilder cookieValue = new StringBuilder(); - while (v_itr.hasNext()) { - String value = (String)v_itr.next(); + for (String value : l) { cookieValue.append(value).append(';'); } // strip off the ending ;-sign @@ -1363,23 +1360,20 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * original exception and with the same message. Right now, * there is no convenient APIs for doing so. */ - private IOException getChainedException(IOException rememberedException) { + private IOException getChainedException(final IOException rememberedException) { try { - final IOException originalException = rememberedException; - final Class[] cls = new Class[1]; - cls[0] = String.class; - final String[] args = new String[1]; - args[0] = originalException.getMessage(); - IOException chainedException = (IOException) - java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Object run() - throws Exception { - Constructor ctr = originalException.getClass().getConstructor(cls); - return (IOException)ctr.newInstance((Object[])args); + final Object[] args = { rememberedException.getMessage() }; + IOException chainedException = + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public IOException run() throws Exception { + return (IOException) + rememberedException.getClass() + .getConstructor(new Class[] { String.class }) + .newInstance(args); } }); - chainedException.initCause(originalException); + chainedException.initCause(rememberedException); return chainedException; } catch (Exception ignored) { return rememberedException; @@ -1629,10 +1623,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection { InetAddress addr = null; try { final String finalHost = host; - addr = (InetAddress) - java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Object run() + addr = java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public InetAddress run() throws java.net.UnknownHostException { return InetAddress.getByName(finalHost); } @@ -2174,7 +2167,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @return a Map of header fields * @since 1.4 */ - public Map getHeaderFields() { + public Map> getHeaderFields() { try { getInputStream(); } catch (IOException e) {} @@ -2286,7 +2279,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * @throws IllegalStateException if already connected * @since 1.4 */ - public Map getRequestProperties() { + public Map> getRequestProperties() { if (connected) throw new IllegalStateException("Already connected"); @@ -2367,20 +2360,15 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return method; } - private MessageHeader mapToMessageHeader(Map map) { + private MessageHeader mapToMessageHeader(Map> map) { MessageHeader headers = new MessageHeader(); if (map == null || map.isEmpty()) { return headers; } - Set entries = map.entrySet(); - Iterator itr1 = entries.iterator(); - while (itr1.hasNext()) { - Map.Entry entry = (Map.Entry)itr1.next(); - String key = (String)entry.getKey(); - List values = (List)entry.getValue(); - Iterator itr2 = values.iterator(); - while (itr2.hasNext()) { - String value = (String)itr2.next(); + for (Map.Entry> entry : map.entrySet()) { + String key = entry.getKey(); + List values = entry.getValue(); + for (String value : values) { if (key == null) { headers.prepend(key, value); } else { diff --git a/jdk/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java b/jdk/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java index 4388f79d891..80b9f0f763f 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java +++ b/jdk/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java @@ -55,7 +55,7 @@ public class URLJarFile extends JarFile { private Manifest superMan; private Attributes superAttr; - private Map superEntries; + private Map superEntries; static JarFile getJarFile(URL url) throws IOException { return getJarFile(url, null); @@ -146,12 +146,10 @@ public class URLJarFile extends JarFile { // now deep copy the manifest entries if (superEntries != null) { - Map entries = man.getEntries(); - Iterator it = superEntries.keySet().iterator(); - while (it.hasNext()) { - Object key = it.next(); - Attributes at = (Attributes)superEntries.get(key); - entries.put(key, at.clone()); + Map entries = man.getEntries(); + for (String key : superEntries.keySet()) { + Attributes at = superEntries.get(key); + entries.put(key, (Attributes) at.clone()); } } @@ -213,9 +211,9 @@ public class URLJarFile extends JarFile { final InputStream in = url.openConnection().getInputStream(); try { - result = (JarFile) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + result = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public JarFile run() throws IOException { OutputStream out = null; File tmpFile = null; try { @@ -273,9 +271,9 @@ public class URLJarFile extends JarFile { public Attributes getAttributes() throws IOException { if (URLJarFile.this.isSuperMan()) { - Map e = URLJarFile.this.superEntries; + Map e = URLJarFile.this.superEntries; if (e != null) { - Attributes a = (Attributes)e.get(getName()); + Attributes a = e.get(getName()); if (a != null) return (Attributes)a.clone(); } diff --git a/jdk/src/share/classes/sun/nio/ch/Reflect.java b/jdk/src/share/classes/sun/nio/ch/Reflect.java index b50c600e314..cd98bf8dfad 100644 --- a/jdk/src/share/classes/sun/nio/ch/Reflect.java +++ b/jdk/src/share/classes/sun/nio/ch/Reflect.java @@ -43,8 +43,8 @@ class Reflect { // package-private } private static void setAccessible(final AccessibleObject ao) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { ao.setAccessible(true); return null; }}); @@ -54,7 +54,7 @@ class Reflect { // package-private Class[] paramTypes) { try { - Class cl = Class.forName(className); + Class cl = Class.forName(className); Constructor c = cl.getDeclaredConstructor(paramTypes); setAccessible(c); return c; @@ -82,7 +82,7 @@ class Reflect { // package-private Class[] paramTypes) { try { - Class cl = Class.forName(className); + Class cl = Class.forName(className); Method m = cl.getDeclaredMethod(methodName, paramTypes); setAccessible(m); return m; diff --git a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java index e852204d803..d8c26a2d13b 100644 --- a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java @@ -242,9 +242,9 @@ public class SocketAdaptor throw new SocketException("Socket input is shutdown"); if (socketInputStream == null) { try { - socketInputStream = (InputStream)AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws IOException { + socketInputStream = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public InputStream run() throws IOException { return new SocketInputStream(); } }); @@ -264,9 +264,9 @@ public class SocketAdaptor throw new SocketException("Socket output is shutdown"); OutputStream os = null; try { - os = (OutputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws IOException { + os = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public OutputStream run() throws IOException { return Channels.newOutputStream(sc); } }); diff --git a/jdk/src/share/classes/sun/nio/ch/Util.java b/jdk/src/share/classes/sun/nio/ch/Util.java index bacaa59f85f..73b66e07296 100644 --- a/jdk/src/share/classes/sun/nio/ch/Util.java +++ b/jdk/src/share/classes/sun/nio/ch/Util.java @@ -49,20 +49,21 @@ class Util { private static final int TEMP_BUF_POOL_SIZE = 3; // Per-thread soft cache of the last temporary direct buffer - private static ThreadLocal[] bufferPool; + private static ThreadLocal>[] bufferPool; static { - bufferPool = new ThreadLocal[TEMP_BUF_POOL_SIZE]; + bufferPool = (ThreadLocal>[]) + new ThreadLocal[TEMP_BUF_POOL_SIZE]; for (int i=0; i>(); } static ByteBuffer getTemporaryDirectBuffer(int size) { ByteBuffer buf = null; // Grab a buffer if available for (int i=0; i ref = bufferPool[i].get(); + if ((ref != null) && ((buf = ref.get()) != null) && (buf.capacity() >= size)) { buf.rewind(); buf.limit(size); @@ -80,18 +81,18 @@ class Util { return; // Put it in an empty slot if such exists for (int i=0; i ref = bufferPool[i].get(); if ((ref == null) || (ref.get() == null)) { - bufferPool[i].set(new SoftReference(buf)); + bufferPool[i].set(new SoftReference(buf)); return; } } // Otherwise replace a smaller one in the cache if such exists for (int i=0; i ref = bufferPool[i].get(); + ByteBuffer inCacheBuf = ref.get(); if ((inCacheBuf == null) || (buf.capacity() > inCacheBuf.capacity())) { - bufferPool[i].set(new SoftReference(buf)); + bufferPool[i].set(new SoftReference(buf)); return; } } @@ -120,10 +121,12 @@ class Util { } // Per-thread cached selector - private static ThreadLocal localSelector = new ThreadLocal(); + private static ThreadLocal> localSelector + = new ThreadLocal>(); // Hold a reference to the selWrapper object to prevent it from // being cleaned when the temporary selector wrapped is on lease. - private static ThreadLocal localSelectorWrapper = new ThreadLocal(); + private static ThreadLocal localSelectorWrapper + = new ThreadLocal(); // When finished, invoker must ensure that selector is empty // by cancelling any related keys and explicitly releasing @@ -131,15 +134,16 @@ class Util { static Selector getTemporarySelector(SelectableChannel sc) throws IOException { - SoftReference ref = (SoftReference)localSelector.get(); + SoftReference ref = localSelector.get(); SelectorWrapper selWrapper = null; Selector sel = null; if (ref == null - || ((selWrapper = (SelectorWrapper) ref.get()) == null) + || ((selWrapper = ref.get()) == null) || ((sel = selWrapper.get()) == null) || (sel.provider() != sc.provider())) { sel = sc.provider().openSelector(); - localSelector.set(new SoftReference(new SelectorWrapper(sel))); + localSelector.set(new SoftReference( + new SelectorWrapper(sel))); } else { localSelectorWrapper.set(selWrapper); } @@ -235,10 +239,10 @@ class Util { private static volatile Constructor directByteBufferConstructor = null; private static void initDBBConstructor() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { try { - Class cl = Class.forName("java.nio.DirectByteBuffer"); + Class cl = Class.forName("java.nio.DirectByteBuffer"); Constructor ctor = cl.getDeclaredConstructor( new Class[] { int.class, long.class, @@ -282,10 +286,10 @@ class Util { private static volatile Constructor directByteBufferRConstructor = null; private static void initDBBRConstructor() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { try { - Class cl = Class.forName("java.nio.DirectByteBufferR"); + Class cl = Class.forName("java.nio.DirectByteBufferR"); Constructor ctor = cl.getDeclaredConstructor( new Class[] { int.class, long.class, diff --git a/jdk/src/share/classes/sun/reflect/ClassDefiner.java b/jdk/src/share/classes/sun/reflect/ClassDefiner.java index 63a4e2af44d..91efcfffedf 100644 --- a/jdk/src/share/classes/sun/reflect/ClassDefiner.java +++ b/jdk/src/share/classes/sun/reflect/ClassDefiner.java @@ -54,9 +54,9 @@ class ClassDefiner { static Class defineClass(String name, byte[] bytes, int off, int len, final ClassLoader parentClassLoader) { - ClassLoader newLoader = (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + ClassLoader newLoader = AccessController.doPrivileged( + new PrivilegedAction() { + public ClassLoader run() { return new DelegatingClassLoader(parentClassLoader); } }); diff --git a/jdk/src/share/classes/sun/reflect/MethodAccessorGenerator.java b/jdk/src/share/classes/sun/reflect/MethodAccessorGenerator.java index 3b62e2df819..fd72a6e1c87 100644 --- a/jdk/src/share/classes/sun/reflect/MethodAccessorGenerator.java +++ b/jdk/src/share/classes/sun/reflect/MethodAccessorGenerator.java @@ -392,11 +392,12 @@ class MethodAccessorGenerator extends AccessorGenerator { // same namespace as the target class. Since the generated code // is privileged anyway, the protection domain probably doesn't // matter. - return (MagicAccessorImpl) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public MagicAccessorImpl run() { try { - return ClassDefiner.defineClass + return (MagicAccessorImpl) + ClassDefiner.defineClass (generatedName, bytes, 0, diff --git a/jdk/src/share/classes/sun/reflect/ReflectionFactory.java b/jdk/src/share/classes/sun/reflect/ReflectionFactory.java index 30a1ac47c20..54dc717f62f 100644 --- a/jdk/src/share/classes/sun/reflect/ReflectionFactory.java +++ b/jdk/src/share/classes/sun/reflect/ReflectionFactory.java @@ -84,8 +84,8 @@ public class ReflectionFactory { * AccessController.doPrivileged. */ public static final class GetReflectionFactoryAction - implements PrivilegedAction { - public Object run() { + implements PrivilegedAction { + public ReflectionFactory run() { return getReflectionFactory(); } } @@ -164,7 +164,7 @@ public class ReflectionFactory { public ConstructorAccessor newConstructorAccessor(Constructor c) { checkInitted(); - Class declaringClass = c.getDeclaringClass(); + Class declaringClass = c.getDeclaringClass(); if (Modifier.isAbstract(declaringClass.getModifiers())) { return new InstantiationExceptionConstructorAccessorImpl(null); } @@ -204,9 +204,9 @@ public class ReflectionFactory { /** Creates a new java.lang.reflect.Field. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Field newField(Class declaringClass, + public Field newField(Class declaringClass, String name, - Class type, + Class type, int modifiers, int slot, String signature, @@ -223,11 +223,11 @@ public class ReflectionFactory { /** Creates a new java.lang.reflect.Method. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Method newMethod(Class declaringClass, + public Method newMethod(Class declaringClass, String name, - Class[] parameterTypes, - Class returnType, - Class[] checkedExceptions, + Class[] parameterTypes, + Class returnType, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -250,9 +250,9 @@ public class ReflectionFactory { /** Creates a new java.lang.reflect.Constructor. Access checks as per java.lang.reflect.AccessibleObject are not overridden. */ - public Constructor newConstructor(Class declaringClass, - Class[] parameterTypes, - Class[] checkedExceptions, + public Constructor newConstructor(Class declaringClass, + Class[] parameterTypes, + Class[] checkedExceptions, int modifiers, int slot, String signature, @@ -310,7 +310,7 @@ public class ReflectionFactory { /** Makes a copy of the passed constructor. The returned constructor is a "child" of the passed one; see the comments in Constructor.java for details. */ - public Constructor copyConstructor(Constructor arg) { + public Constructor copyConstructor(Constructor arg) { return langReflectAccess().copyConstructor(arg); } @@ -321,7 +321,7 @@ public class ReflectionFactory { // public Constructor newConstructorForSerialization - (Class classToInstantiate, Constructor constructorToCall) + (Class classToInstantiate, Constructor constructorToCall) { // Fast path if (constructorToCall.getDeclaringClass() == classToInstantiate) { @@ -366,8 +366,9 @@ public class ReflectionFactory { run, before the system properties are set up. */ private static void checkInitted() { if (initted) return; - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Void run() { // Tests to ensure the system properties table is fully // initialized. This is needed because reflection code is // called very early in the initialization process (before diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index 45147dc51cf..56f1bad4b04 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -273,8 +273,8 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { private Method[] getMemberMethods() { if (memberMethods == null) { final Method[] mm = type.getDeclaredMethods(); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { AccessibleObject.setAccessible(mm, true); return null; } diff --git a/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java index b36993337bb..9c1bfbea41f 100644 --- a/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java +++ b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java @@ -67,7 +67,7 @@ public final class MethodUtil extends SecureClassLoader { super(); } - public static Method getMethod(Class cls, String name, Class[] args) + public static Method getMethod(Class cls, String name, Class[] args) throws NoSuchMethodException { ReflectUtil.checkPackageAccess(cls); return cls.getMethod(name, args); @@ -89,7 +89,7 @@ public final class MethodUtil extends SecureClassLoader { if (System.getSecurityManager() == null) { return cls.getMethods(); } - Map sigs = new HashMap(); + Map sigs = new HashMap(); while (cls != null) { boolean done = getInternalPublicMethods(cls, sigs); if (done) { @@ -98,14 +98,14 @@ public final class MethodUtil extends SecureClassLoader { getInterfaceMethods(cls, sigs); cls = cls.getSuperclass(); } - Collection c = sigs.values(); - return (Method[]) c.toArray(new Method[c.size()]); + return sigs.values().toArray(new Method[sigs.size()]); } /* * Process the immediate interfaces of this class or interface. */ - private static void getInterfaceMethods(Class cls, Map sigs) { + private static void getInterfaceMethods(Class cls, + Map sigs) { Class[] intfs = cls.getInterfaces(); for (int i=0; i < intfs.length; i++) { Class intf = intfs[i]; @@ -120,7 +120,8 @@ public final class MethodUtil extends SecureClassLoader { * * Process the methods in this class or interface */ - private static boolean getInternalPublicMethods(Class cls, Map sigs) { + private static boolean getInternalPublicMethods(Class cls, + Map sigs) { Method[] methods = null; try { /* @@ -178,7 +179,7 @@ public final class MethodUtil extends SecureClassLoader { return done; } - private static void addMethod(Map sigs, Method method) { + private static void addMethod(Map sigs, Method method) { Signature signature = new Signature(method); if (!sigs.containsKey(signature)) { sigs.put(signature, method); @@ -186,7 +187,7 @@ public final class MethodUtil extends SecureClassLoader { /* * Superclasses beat interfaces. */ - Method old = (Method)sigs.get(signature); + Method old = sigs.get(signature); if (old.getDeclaringClass().isInterface()) { sigs.put(signature, method); } @@ -280,17 +281,15 @@ public final class MethodUtil extends SecureClassLoader { } private static Method getTrampoline() { - Method tramp = null; - try { - tramp = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { - Class[] types; - Class t = getTrampolineClass(); - Method b; - - types = new Class[] {Method.class, Object.class, Object[].class}; - b = t.getDeclaredMethod("invoke", types); + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Method run() throws Exception { + Class t = getTrampolineClass(); + Class[] types = { + Method.class, Object.class, Object[].class + }; + Method b = t.getDeclaredMethod("invoke", types); ((AccessibleObject)b).setAccessible(true); return b; } @@ -298,7 +297,6 @@ public final class MethodUtil extends SecureClassLoader { } catch (Exception e) { throw new InternalError("bouncer cannot be found"); } - return tramp; } diff --git a/jdk/src/share/classes/sun/rmi/log/ReliableLog.java b/jdk/src/share/classes/sun/rmi/log/ReliableLog.java index 7ac2858196a..542c6d27a15 100644 --- a/jdk/src/share/classes/sun/rmi/log/ReliableLog.java +++ b/jdk/src/share/classes/sun/rmi/log/ReliableLog.java @@ -140,8 +140,8 @@ public class ReliableLog { throws IOException { super(); - this.Debug = ((Boolean) AccessController.doPrivileged( - new GetBooleanAction("sun.rmi.log.debug"))).booleanValue(); + this.Debug = AccessController.doPrivileged( + new GetBooleanAction("sun.rmi.log.debug")).booleanValue(); dir = new File(dirPath); if (!(dir.exists() && dir.isDirectory())) { // create directory @@ -333,8 +333,8 @@ public class ReliableLog { private static Constructor getLogClassConstructor() { - String logClassName = ((String) AccessController.doPrivileged( - new GetPropertyAction("sun.rmi.log.class"))); + String logClassName = AccessController.doPrivileged( + new GetPropertyAction("sun.rmi.log.class")); if (logClassName != null) { try { ClassLoader loader = diff --git a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java index 2f29cd57033..7a99a014ee5 100644 --- a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java @@ -66,8 +66,10 @@ public class RegistryImpl extends java.rmi.server.RemoteServer /* indicate compatibility with JDK 1.1.x version of class */ private static final long serialVersionUID = 4666870661827494597L; - private Hashtable bindings = new Hashtable(101); - private static Hashtable allowedAccessCache = new Hashtable(3); + private Hashtable bindings + = new Hashtable(101); + private static Hashtable allowedAccessCache + = new Hashtable(3); private static RegistryImpl registry; private static ObjID id = new ObjID(ObjID.REGISTRY_ID); @@ -119,7 +121,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer throws RemoteException, NotBoundException { synchronized (bindings) { - Remote obj = (Remote)bindings.get(name); + Remote obj = bindings.get(name); if (obj == null) throw new NotBoundException(name); return obj; @@ -136,7 +138,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer { checkAccess("Registry.bind"); synchronized (bindings) { - Remote curr = (Remote)bindings.get(name); + Remote curr = bindings.get(name); if (curr != null) throw new AlreadyBoundException(name); bindings.put(name, obj); @@ -153,7 +155,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer { checkAccess("Registry.unbind"); synchronized (bindings) { - Remote obj = (Remote)bindings.get(name); + Remote obj = bindings.get(name); if (obj == null) throw new NotBoundException(name); bindings.remove(name); @@ -203,10 +205,9 @@ public class RegistryImpl extends java.rmi.server.RemoteServer InetAddress clientHost; try { - clientHost = (InetAddress) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() + clientHost = java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public InetAddress run() throws java.net.UnknownHostException { return InetAddress.getByName(clientHostName); @@ -228,8 +229,8 @@ public class RegistryImpl extends java.rmi.server.RemoteServer final InetAddress finalClientHost = clientHost; java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws java.io.IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws java.io.IOException { /* * if a ServerSocket can be bound to the client's * address then that address must be local diff --git a/jdk/src/share/classes/sun/rmi/rmic/RemoteClass.java b/jdk/src/share/classes/sun/rmi/rmic/RemoteClass.java index 0caa07fe067..7d41be36974 100644 --- a/jdk/src/share/classes/sun/rmi/rmic/RemoteClass.java +++ b/jdk/src/share/classes/sun/rmi/rmic/RemoteClass.java @@ -103,7 +103,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * in the array). */ public ClassDefinition[] getRemoteInterfaces() { - return (ClassDefinition[]) remoteInterfaces.clone(); + return remoteInterfaces.clone(); } /** @@ -118,7 +118,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * stub/skeleton protocol. */ public Method[] getRemoteMethods() { - return (Method[]) remoteMethods.clone(); + return remoteMethods.clone(); } /** @@ -204,8 +204,8 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * chain, add each directly-implemented interface that * somehow extends Remote to a list. */ - Vector remotesImplemented = // list of remote interfaces found - new Vector(); + Vector remotesImplemented = // list of remote interfaces found + new Vector(); for (ClassDefinition classDef = implClassDef; classDef != null;) { @@ -307,13 +307,13 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * Now we collect the methods from all of the remote interfaces * into a hashtable. */ - Hashtable methods = new Hashtable(); + Hashtable methods = new Hashtable(); boolean errors = false; - for (Enumeration enumeration = remotesImplemented.elements(); + for (Enumeration enumeration + = remotesImplemented.elements(); enumeration.hasMoreElements();) { - ClassDefinition interfaceDef = - (ClassDefinition) enumeration.nextElement(); + ClassDefinition interfaceDef = enumeration.nextElement(); if (!collectRemoteMethods(interfaceDef, methods)) errors = true; } @@ -336,10 +336,10 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { */ String[] orderedKeys = new String[methods.size()]; int count = 0; - for (Enumeration enumeration = methods.elements(); + for (Enumeration enumeration = methods.elements(); enumeration.hasMoreElements();) { - Method m = (Method) enumeration.nextElement(); + Method m = enumeration.nextElement(); String key = m.getNameAndDescriptor(); int i; for (i = count; i > 0; --i) { @@ -353,7 +353,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { } remoteMethods = new Method[methods.size()]; for (int i = 0; i < remoteMethods.length; i++) { - remoteMethods[i] = (Method) methods.get(orderedKeys[i]); + remoteMethods[i] = methods.get(orderedKeys[i]); /***** */ if (env.verbose()) { System.out.print("[found remote method <" + i + ">: " + @@ -388,7 +388,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * or false if an error occurred. */ private boolean collectRemoteMethods(ClassDefinition interfaceDef, - Hashtable table) + Hashtable table) { if (!interfaceDef.isInterface()) { throw new Error( @@ -529,7 +529,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * the new method (see bugid 4070653). */ String key = newMethod.getNameAndDescriptor(); - Method oldMethod = (Method) table.get(key); + Method oldMethod = table.get(key); if (oldMethod != null) { newMethod = newMethod.mergeWith(oldMethod); if (newMethod == null) { @@ -684,7 +684,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { * methods that can be legally thrown in each of them. */ public ClassDeclaration[] getExceptions() { - return (ClassDeclaration[]) exceptions.clone(); + return exceptions.clone(); } /** @@ -789,7 +789,8 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { getNameAndDescriptor()); } - Vector legalExceptions = new Vector(); + Vector legalExceptions + = new Vector(); try { collectCompatibleExceptions( other.exceptions, exceptions, legalExceptions); @@ -814,7 +815,7 @@ public class RemoteClass implements sun.rmi.rmic.RMIConstants { */ private void collectCompatibleExceptions(ClassDeclaration[] from, ClassDeclaration[] with, - Vector list) + Vector list) throws ClassNotFound { for (int i = 0; i < from.length; i++) { diff --git a/jdk/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java b/jdk/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java index f22a652dfdb..064d2d0cc7a 100644 --- a/jdk/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java +++ b/jdk/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java @@ -121,7 +121,7 @@ final class RemoteClass { * in the array). **/ ClassDoc[] remoteInterfaces() { - return (ClassDoc[]) remoteInterfaces.clone(); + return remoteInterfaces.clone(); } /** @@ -136,7 +136,7 @@ final class RemoteClass { * stub/skeleton protocol. **/ Method[] remoteMethods() { - return (Method[]) remoteMethods.clone(); + return remoteMethods.clone(); } /** @@ -559,7 +559,7 @@ final class RemoteClass { * methods that can be legally thrown by all of them. **/ ClassDoc[] exceptionTypes() { - return (ClassDoc[]) exceptionTypes.clone(); + return exceptionTypes.clone(); } /** diff --git a/jdk/src/share/classes/sun/rmi/runtime/Log.java b/jdk/src/share/classes/sun/rmi/runtime/Log.java index 3eb8ce9cf9f..8017ee0a10f 100644 --- a/jdk/src/share/classes/sun/rmi/runtime/Log.java +++ b/jdk/src/share/classes/sun/rmi/runtime/Log.java @@ -71,7 +71,7 @@ public abstract class Log { private static final LogFactory logFactory; static { boolean useOld = - Boolean.valueOf((String) java.security.AccessController. + Boolean.valueOf(java.security.AccessController. doPrivileged(new sun.security.action.GetPropertyAction( "sun.rmi.log.useOld"))).booleanValue(); @@ -179,17 +179,16 @@ public abstract class Log { private static class LoggerLog extends Log { /* alternate console handler for RMI loggers */ - private static final Handler alternateConsole = (Handler) + private static final Handler alternateConsole = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Handler run() { InternalStreamHandler alternate = new InternalStreamHandler(System.err); alternate.setLevel(Level.ALL); return alternate; } - } - ); + }); /** handler to which messages are copied */ private InternalStreamHandler copyHandler = null; @@ -206,8 +205,8 @@ public abstract class Log { if (level != null){ java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { if (!logger.isLoggable(level)) { logger.setLevel(level); } diff --git a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java index d4a9183e4a3..dcdecb0cc43 100644 --- a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java +++ b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java @@ -70,7 +70,7 @@ public final class LoaderHandler { /** RMI class loader log level */ static final int logLevel = LogStream.parseLevel( - (String) java.security.AccessController.doPrivileged( + java.security.AccessController.doPrivileged( new GetPropertyAction("sun.rmi.loader.logLevel"))); /* loader system log */ @@ -83,7 +83,7 @@ public final class LoaderHandler { */ private static String codebaseProperty = null; static { - String prop = (String) java.security.AccessController.doPrivileged( + String prop = java.security.AccessController.doPrivileged( new GetPropertyAction("java.rmi.server.codebase")); if (prop != null && prop.trim().length() > 0) { codebaseProperty = prop; @@ -94,8 +94,8 @@ public final class LoaderHandler { private static URL[] codebaseURLs = null; /** table of class loaders that use codebase property for annotation */ - private static final Map codebaseLoaders = - Collections.synchronizedMap(new IdentityHashMap(5)); + private static final Map codebaseLoaders = + Collections.synchronizedMap(new IdentityHashMap(5)); static { for (ClassLoader codebaseLoader = ClassLoader.getSystemClassLoader(); codebaseLoader != null; @@ -111,10 +111,12 @@ public final class LoaderHandler { * references, so this table does not prevent loaders from being * garbage collected. */ - private static final HashMap loaderTable = new HashMap(5); + private static final HashMap loaderTable + = new HashMap(5); /** reference queue for cleared class loader entries */ - private static final ReferenceQueue refQueue = new ReferenceQueue(); + private static final ReferenceQueue refQueue + = new ReferenceQueue(); /* * Disallow anyone from creating one of these. @@ -757,7 +759,7 @@ public final class LoaderHandler { throws MalformedURLException { synchronized (pathToURLsCache) { - Object[] v = (Object[]) pathToURLsCache.get(path); + Object[] v = pathToURLsCache.get(path); if (v != null) { return ((URL[])v[0]); } @@ -769,13 +771,14 @@ public final class LoaderHandler { } synchronized (pathToURLsCache) { pathToURLsCache.put(path, - new Object[] {urls, new SoftReference(path)}); + new Object[] {urls, new SoftReference(path)}); } return urls; } /** map from weak(key=string) to [URL[], soft(key)] */ - private static final Map pathToURLsCache = new WeakHashMap(5); + private static final Map pathToURLsCache + = new WeakHashMap(5); /** * Convert an array of URL objects into a corresponding string @@ -853,9 +856,9 @@ public final class LoaderHandler { * in the table of RMI class loaders. */ LoaderKey key = new LoaderKey(urls, parent); - entry = (LoaderEntry) loaderTable.get(key); + entry = loaderTable.get(key); - if (entry == null || (loader = (Loader) entry.get()) == null) { + if (entry == null || (loader = entry.get()) == null) { /* * If entry was in table but it's weak reference was cleared, * remove it from the table and mark it as explicitly cleared, @@ -876,9 +879,9 @@ public final class LoaderHandler { * necessary to load classes from its codebase URL path. */ AccessControlContext acc = getLoaderAccessControlContext(urls); - loader = (Loader) java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + loader = java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Loader run() { return new Loader(urls, parent); } }, acc); @@ -954,7 +957,7 @@ public final class LoaderHandler { * loader key for the loader so that the mapping can be removed from * the table efficiently when the weak reference is cleared. */ - private static class LoaderEntry extends WeakReference { + private static class LoaderEntry extends WeakReference { public LoaderKey key; @@ -983,10 +986,10 @@ public final class LoaderHandler { * getAccessControlContext() in the sun.applet.AppletPanel class. */ // begin with permissions granted to all code in current policy - PermissionCollection perms = (PermissionCollection) + PermissionCollection perms = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public PermissionCollection run() { CodeSource codesource = new CodeSource(null, (java.security.cert.Certificate[]) null); Policy p = java.security.Policy.getPolicy(); diff --git a/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java b/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java index a75b8051a5c..cf4e345d786 100644 --- a/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java +++ b/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java @@ -59,18 +59,20 @@ public class MarshalInputStream extends ObjectInputStream { * as cached at class initialization time. */ private static final boolean useCodebaseOnlyProperty = - ((Boolean) java.security.AccessController.doPrivileged( + java.security.AccessController.doPrivileged( new sun.security.action.GetBooleanAction( - "java.rmi.server.useCodebaseOnly"))).booleanValue(); + "java.rmi.server.useCodebaseOnly")).booleanValue(); /** table to hold sun classes to which access is explicitly permitted */ - protected static Map permittedSunClasses = new HashMap(3); + protected static Map> permittedSunClasses + = new HashMap>(3); /** if true, don't try superclass first in resolveClass() */ private boolean skipDefaultResolveClass = false; /** callbacks to make when done() called: maps Object to Runnable */ - private final Map doneCallbacks = new HashMap(3); + private final Map doneCallbacks + = new HashMap(3); /** * if true, load classes (if not available locally) only from the @@ -130,7 +132,7 @@ public class MarshalInputStream extends ObjectInputStream { * with that key. */ public Runnable getDoneCallback(Object key) { - return (Runnable) doneCallbacks.get(key); // not thread-safe + return doneCallbacks.get(key); // not thread-safe } /** @@ -153,9 +155,9 @@ public class MarshalInputStream extends ObjectInputStream { * the superclass's close method. */ public void done() { - Iterator iter = doneCallbacks.values().iterator(); + Iterator iter = doneCallbacks.values().iterator(); while (iter.hasNext()) { // not thread-safe - Runnable callback = (Runnable) iter.next(); + Runnable callback = iter.next(); callback.run(); } doneCallbacks.clear(); @@ -276,8 +278,7 @@ public class MarshalInputStream extends ObjectInputStream { name = perm.getName(); } - Class resolvedClass = - (Class) permittedSunClasses.get(className); + Class resolvedClass = permittedSunClasses.get(className); // if class not permitted, throw the SecurityException if ((name == null) || diff --git a/jdk/src/share/classes/sun/rmi/server/MarshalOutputStream.java b/jdk/src/share/classes/sun/rmi/server/MarshalOutputStream.java index 63aed2bee53..067a5f2ec70 100644 --- a/jdk/src/share/classes/sun/rmi/server/MarshalOutputStream.java +++ b/jdk/src/share/classes/sun/rmi/server/MarshalOutputStream.java @@ -64,8 +64,8 @@ public class MarshalOutputStream extends ObjectOutputStream super(out); this.useProtocolVersion(protocolVersion); java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { enableReplaceObject(true); return null; } diff --git a/jdk/src/share/classes/sun/rmi/server/Util.java b/jdk/src/share/classes/sun/rmi/server/Util.java index f103319ce89..f757874416b 100644 --- a/jdk/src/share/classes/sun/rmi/server/Util.java +++ b/jdk/src/share/classes/sun/rmi/server/Util.java @@ -67,7 +67,7 @@ public final class Util { /** "server" package log level */ static final int logLevel = LogStream.parseLevel( - (String) AccessController.doPrivileged( + AccessController.doPrivileged( new GetPropertyAction("sun.rmi.server.logLevel"))); /** server reference log */ @@ -76,13 +76,13 @@ public final class Util { /** cached value of property java.rmi.server.ignoreStubClasses */ private static final boolean ignoreStubClasses = - ((Boolean) AccessController.doPrivileged( - new GetBooleanAction("java.rmi.server.ignoreStubClasses"))). + AccessController.doPrivileged( + new GetBooleanAction("java.rmi.server.ignoreStubClasses")). booleanValue(); /** cache of impl classes that have no corresponding stub class */ - private static final Map withoutStubs = - Collections.synchronizedMap(new WeakHashMap(11)); + private static final Map, Void> withoutStubs = + Collections.synchronizedMap(new WeakHashMap, Void>(11)); /** parameter types for stub constructor */ private static final Class[] stubConsParamTypes = { RemoteRef.class }; @@ -207,9 +207,9 @@ public final class Util { * @throws NullPointerException if remoteClass is null */ private static Class[] getRemoteInterfaces(Class remoteClass) { - ArrayList list = new ArrayList(); + ArrayList> list = new ArrayList>(); getRemoteInterfaces(list, remoteClass); - return (Class []) list.toArray(new Class[list.size()]); + return list.toArray(new Class[list.size()]); } /** @@ -220,7 +220,7 @@ public final class Util { * any illegal remote interfaces * @throws NullPointerException if the specified class or list is null */ - private static void getRemoteInterfaces(ArrayList list, Class cl) { + private static void getRemoteInterfaces(ArrayList> list, Class cl) { Class superclass = cl.getSuperclass(); if (superclass != null) { getRemoteInterfaces(list, superclass); @@ -254,7 +254,7 @@ public final class Util { * @throws IllegalArgumentException if m is an illegal remote method */ private static void checkMethod(Method m) { - Class[] ex = m.getExceptionTypes(); + Class[] ex = m.getExceptionTypes(); for (int i = 0; i < ex.length; i++) { if (ex[i].isAssignableFrom(RemoteException.class)) return; @@ -283,7 +283,7 @@ public final class Util { * pickle methods */ try { - Class stubcl = + Class stubcl = Class.forName(stubname, false, remoteClass.getClassLoader()); Constructor cons = stubcl.getConstructor(stubConsParamTypes); return (RemoteStub) cons.newInstance(new Object[] { ref }); diff --git a/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java b/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java index e822c26551b..331930c3680 100644 --- a/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java +++ b/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java @@ -69,7 +69,7 @@ public abstract class WeakClassHashMap { synchronized (valueCell) { V value = null; if (valueCell.ref != null) { - value = (V) valueCell.ref.get(); + value = valueCell.ref.get(); } if (value == null) { value = computeValue(remoteClass); diff --git a/jdk/src/share/classes/sun/rmi/transport/DGCClient.java b/jdk/src/share/classes/sun/rmi/transport/DGCClient.java index 31784b3574a..585901bbce7 100644 --- a/jdk/src/share/classes/sun/rmi/transport/DGCClient.java +++ b/jdk/src/share/classes/sun/rmi/transport/DGCClient.java @@ -85,21 +85,21 @@ final class DGCClient { /** lease duration to request (usually ignored by server) */ private static final long leaseValue = // default 10 minutes - ((Long) AccessController.doPrivileged( + AccessController.doPrivileged( new GetLongAction("java.rmi.dgc.leaseValue", - 600000))).longValue(); + 600000)).longValue(); /** maximum interval between retries of failed clean calls */ private static final long cleanInterval = // default 3 minutes - ((Long) AccessController.doPrivileged( + AccessController.doPrivileged( new GetLongAction("sun.rmi.dgc.cleanInterval", - 180000))).longValue(); + 180000)).longValue(); /** maximum interval between complete garbage collections of local heap */ private static final long gcInterval = // default 1 hour - ((Long) AccessController.doPrivileged( + AccessController.doPrivileged( new GetLongAction("sun.rmi.dgc.client.gcInterval", - 3600000))).longValue(); + 3600000)).longValue(); /** minimum retry count for dirty calls that fail */ private static final int dirtyFailureRetries = 5; @@ -243,7 +243,7 @@ final class DGCClient { } catch (RemoteException e) { throw new Error("internal error creating DGC stub"); } - renewCleanThread = (Thread) AccessController.doPrivileged( + renewCleanThread = AccessController.doPrivileged( new NewThreadAction(new RenewCleanThread(), "RenewClean-" + endpoint, true)); renewCleanThread.start(); @@ -473,8 +473,9 @@ final class DGCClient { if (newRenewTime < renewTime) { renewTime = newRenewTime; if (interruptible) { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Void run() { renewCleanThread.interrupt(); return null; } diff --git a/jdk/src/share/classes/sun/rmi/transport/Target.java b/jdk/src/share/classes/sun/rmi/transport/Target.java index 01df4380093..6abf092d725 100644 --- a/jdk/src/share/classes/sun/rmi/transport/Target.java +++ b/jdk/src/share/classes/sun/rmi/transport/Target.java @@ -321,7 +321,7 @@ public final class Target { Remote obj = getImpl(); if (obj instanceof Unreferenced) { final Unreferenced unrefObj = (Unreferenced) obj; - final Thread t = (Thread) + final Thread t = java.security.AccessController.doPrivileged( new NewThreadAction(new Runnable() { public void run() { @@ -334,8 +334,8 @@ public final class Target { * for threads that may invoke user code (see bugid 4171278). */ java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { t.setContextClassLoader(ccl); return null; } diff --git a/jdk/src/share/classes/sun/rmi/transport/Transport.java b/jdk/src/share/classes/sun/rmi/transport/Transport.java index 572a55b2bea..67e6058d95a 100644 --- a/jdk/src/share/classes/sun/rmi/transport/Transport.java +++ b/jdk/src/share/classes/sun/rmi/transport/Transport.java @@ -53,7 +53,7 @@ public abstract class Transport { static final int logLevel = LogStream.parseLevel(getLogLevel()); private static String getLogLevel() { - return (String) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.rmi.transport.logLevel")); } @@ -171,8 +171,8 @@ public abstract class Transport { currentTransport.set(this); try { java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() throws IOException { + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { checkAcceptPermission(acc); disp.dispatch(impl, call); return null; diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java index 3d91ab0d179..cb4a88e562c 100644 --- a/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java +++ b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java @@ -89,8 +89,8 @@ public final class CGIHandler { static { java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public Void run() { ContentLength = Integer.getInteger("CONTENT_LENGTH", 0).intValue(); QueryString = System.getProperty("QUERY_STRING", ""); diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java index 7498c9bfd8b..2c972d8760f 100644 --- a/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java +++ b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java @@ -78,7 +78,7 @@ class HttpSendSocket extends Socket implements RMISocketInfo { * property at the moment that the socket was created. */ private String lineSeparator = - (String) java.security.AccessController.doPrivileged( + java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("line.separator")); /** diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java b/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java index 16735959e2f..92d0dd77cb3 100644 --- a/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java +++ b/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java @@ -50,7 +50,7 @@ public class RMIMasterSocketFactory extends RMISocketFactory { static int logLevel = LogStream.parseLevel(getLogLevel()); private static String getLogLevel() { - return (String) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.rmi.transport.proxy.logLevel")); } @@ -63,15 +63,15 @@ public class RMIMasterSocketFactory extends RMISocketFactory { private static long connectTimeout = getConnectTimeout(); private static long getConnectTimeout() { - return ((Long) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new GetLongAction("sun.rmi.transport.proxy.connectTimeout", - 15000))).longValue(); // default: 15 seconds + 15000)).longValue(); // default: 15 seconds } /** whether to fallback to HTTP on general connect failures */ - private static final boolean eagerHttpFallback = ((Boolean) + private static final boolean eagerHttpFallback = java.security.AccessController.doPrivileged(new GetBooleanAction( - "sun.rmi.transport.proxy.eagerHttpFallback"))).booleanValue(); + "sun.rmi.transport.proxy.eagerHttpFallback")).booleanValue(); /** table of hosts successfully connected to and the factory used */ private Hashtable successTable = new Hashtable(); @@ -100,14 +100,14 @@ public class RMIMasterSocketFactory extends RMISocketFactory { try { String proxyHost; - proxyHost = (String) java.security.AccessController.doPrivileged( + proxyHost = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("http.proxyHost")); if (proxyHost == null) - proxyHost=(String)java.security.AccessController.doPrivileged( + proxyHost = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("proxyHost")); - Boolean tmp = (Boolean)java.security.AccessController.doPrivileged( + Boolean tmp = java.security.AccessController.doPrivileged( new sun.security.action.GetBooleanAction("java.rmi.server.disableHttp")); if (!tmp.booleanValue() && @@ -178,10 +178,8 @@ public class RMIMasterSocketFactory extends RMISocketFactory { try { synchronized (connector) { - Thread t = (Thread) - java.security.AccessController.doPrivileged( - new NewThreadAction(connector, "AsyncConnector", - true)); + Thread t = java.security.AccessController.doPrivileged( + new NewThreadAction(connector, "AsyncConnector", true)); t.start(); try { diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java b/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java index f756cd34f74..ac26ac6d832 100644 --- a/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java +++ b/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java @@ -49,7 +49,7 @@ final class ConnectionMultiplexer { static int logLevel = LogStream.parseLevel(getLogLevel()); private static String getLogLevel() { - return (String) java.security.AccessController.doPrivileged( + return java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.rmi.transport.tcp.multiplex.logLevel")); } diff --git a/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java index 7bf0f9be230..7aa401b0380 100644 --- a/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java +++ b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java @@ -83,7 +83,7 @@ public class GSSManagerImpl extends GSSManager { public Oid[] getNamesForMech(Oid mech) throws GSSException { MechanismFactory factory = list.getMechFactory(mech); - return (Oid[])factory.getNameTypes().clone(); + return factory.getNameTypes().clone(); } public Oid[] getMechsForName(Oid nameType){ diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java index 0fcbe12ff25..838f6f8df1e 100644 --- a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java +++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java @@ -103,8 +103,7 @@ class InitSecContextToken extends InitialToken { apReq = new KrbApReq(apReqBytes, keys, addr); //debug("\nReceived AP-REQ and authenticated it.\n"); - EncryptionKey sessionKey - = (EncryptionKey) apReq.getCreds().getSessionKey(); + EncryptionKey sessionKey = apReq.getCreds().getSessionKey(); /* System.out.println("\n\nSession key from service ticket is: " + diff --git a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java index 794f7179f20..81a3696f7af 100644 --- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java +++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java @@ -191,7 +191,7 @@ final class CipherSuite implements Comparable { if (s == null) { throw new IllegalArgumentException("Name must not be null"); } - CipherSuite c = (CipherSuite)nameMap.get(s); + CipherSuite c = nameMap.get(s); if ((c == null) || (c.allowed == false)) { throw new IllegalArgumentException("Unsupported ciphersuite " + s); } @@ -395,7 +395,7 @@ final class CipherSuite implements Comparable { } private static synchronized boolean isAvailable(BulkCipher cipher) { - Boolean b = (Boolean)availableCache.get(cipher); + Boolean b = availableCache.get(cipher); if (b == null) { try { SecretKey key = new SecretKeySpec diff --git a/jdk/src/share/classes/sun/security/ssl/DHCrypt.java b/jdk/src/share/classes/sun/security/ssl/DHCrypt.java index baf784cde2b..5c9dc14aac2 100644 --- a/jdk/src/share/classes/sun/security/ssl/DHCrypt.java +++ b/jdk/src/share/classes/sun/security/ssl/DHCrypt.java @@ -132,8 +132,7 @@ final class DHCrypt { } try { KeyFactory factory = JsseJce.getKeyFactory("DH"); - return (DHPublicKeySpec)factory.getKeySpec - (key, DHPublicKeySpec.class); + return factory.getKeySpec(key, DHPublicKeySpec.class); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/jdk/src/share/classes/sun/security/ssl/JsseJce.java b/jdk/src/share/classes/sun/security/ssl/JsseJce.java index 5fb6972874f..d9a40fb2b84 100644 --- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java +++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java @@ -343,8 +343,7 @@ final class JsseJce { } try { KeyFactory factory = JsseJce.getKeyFactory("RSA"); - return (RSAPublicKeySpec)factory.getKeySpec - (key, RSAPublicKeySpec.class); + return factory.getKeySpec(key, RSAPublicKeySpec.class); } catch (Exception e) { throw (RuntimeException)new RuntimeException().initCause(e); } diff --git a/jdk/src/share/classes/sun/security/ssl/ProtocolList.java b/jdk/src/share/classes/sun/security/ssl/ProtocolList.java index 9898d244a20..197cfa4adbb 100644 --- a/jdk/src/share/classes/sun/security/ssl/ProtocolList.java +++ b/jdk/src/share/classes/sun/security/ssl/ProtocolList.java @@ -98,7 +98,7 @@ final class ProtocolList { protocolNames[i++] = version.name; } } - return (String[])protocolNames.clone(); + return protocolNames.clone(); } public String toString() { diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java index 38d666ac337..a37954ea22e 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java @@ -458,7 +458,7 @@ final class SSLSessionImpl implements SSLSession { + " for Kerberos cipher suites"); } if (peerCerts != null) { - return (X509Certificate [])peerCerts.clone(); + return peerCerts.clone(); } else { throw new SSLPeerUnverifiedException("peer not authenticated"); } @@ -489,7 +489,7 @@ final class SSLSessionImpl implements SSLSession { if (peerCerts == null) { throw new SSLPeerUnverifiedException("peer not authenticated"); } - return ((X500Principal)peerCerts[0].getSubjectX500Principal()); + return peerCerts[0].getSubjectX500Principal(); } /** @@ -508,7 +508,7 @@ final class SSLSessionImpl implements SSLSession { (KerberosPrincipal)localPrincipal); } return (localCerts == null ? null : - (X500Principal)localCerts[0].getSubjectX500Principal()); + localCerts[0].getSubjectX500Principal()); } /** diff --git a/jdk/src/share/classes/sun/security/ssl/SessionId.java b/jdk/src/share/classes/sun/security/ssl/SessionId.java index 557fbff30c8..c9b900f743a 100644 --- a/jdk/src/share/classes/sun/security/ssl/SessionId.java +++ b/jdk/src/share/classes/sun/security/ssl/SessionId.java @@ -64,7 +64,7 @@ class SessionId /** Returns the bytes in the ID. May be an empty array. */ byte [] getId () { - return (byte []) sessionId.clone (); + return sessionId.clone (); } /** Returns the ID as a string */ diff --git a/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java b/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java index a111f79b427..2cd825def26 100644 --- a/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java @@ -172,7 +172,7 @@ final class SunX509KeyManagerImpl extends X509ExtendedKeyManager { if (cred == null) { return null; } else { - return (X509Certificate[])cred.certificates.clone(); + return cred.certificates.clone(); } } @@ -255,7 +255,7 @@ final class SunX509KeyManagerImpl extends X509ExtendedKeyManager { String[] aliases; if (issuers == null || issuers.length == 0) { - aliases = (String[])serverAliasCache.get(keyType); + aliases = serverAliasCache.get(keyType); if (aliases == null) { aliases = getServerAliases(keyType, issuers); // Cache the result (positive and negative lookups) @@ -388,7 +388,7 @@ final class SunX509KeyManagerImpl extends X509ExtendedKeyManager { } } - String[] aliasStrings = (String[])aliases.toArray(STRING0); + String[] aliasStrings = aliases.toArray(STRING0); return ((aliasStrings.length == 0) ? null : aliasStrings); } diff --git a/jdk/src/share/classes/sun/security/x509/CertificatePolicySet.java b/jdk/src/share/classes/sun/security/x509/CertificatePolicySet.java index 32e5121c76a..514a3576cc4 100644 --- a/jdk/src/share/classes/sun/security/x509/CertificatePolicySet.java +++ b/jdk/src/share/classes/sun/security/x509/CertificatePolicySet.java @@ -87,7 +87,7 @@ public class CertificatePolicySet { DerOutputStream tmp = new DerOutputStream(); for (int i = 0; i < ids.size(); i++) { - ((CertificatePolicyId)ids.elementAt(i)).encode(tmp); + ids.elementAt(i).encode(tmp); } out.write(DerValue.tag_Sequence,tmp); } diff --git a/jdk/src/share/classes/sun/security/x509/X509Cert.java b/jdk/src/share/classes/sun/security/x509/X509Cert.java index 6777d4b4a2f..af685111294 100644 --- a/jdk/src/share/classes/sun/security/x509/X509Cert.java +++ b/jdk/src/share/classes/sun/security/x509/X509Cert.java @@ -516,7 +516,7 @@ public class X509Cert implements Certificate, Serializable { * Null is returned in the case of a partially constructed cert. */ public byte [] getSignedCert () - { return (byte[])signedCert.clone(); } + { return signedCert.clone(); } /** diff --git a/jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java b/jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java index 5485bfaded9..c39b35eaa17 100644 --- a/jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java +++ b/jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java @@ -32,7 +32,6 @@ import java.util.jar.*; import java.security.cert.Certificate; import java.security.AccessController; import java.security.cert.X509Certificate; -import java.security.Identity; import java.security.PublicKey; import java.security.Principal; import sun.security.provider.SystemIdentity; @@ -49,7 +48,8 @@ import sun.security.provider.SystemIdentity; public class JarVerifierStream extends ZipInputStream { private JarEntry current; - private Hashtable verified = new Hashtable(); + private Hashtable> verified + = new Hashtable>(); private JarInputStream jis; private sun.tools.jar.Manifest man = null; @@ -120,7 +120,7 @@ public class JarVerifierStream extends ZipInputStream { if (current != null) { Certificate[] certs = current.getCertificates(); if (certs != null) { - Vector ids = getIds(certs); + Vector ids = getIds(certs); if (ids != null) { verified.put(current.getName(), ids); } @@ -189,7 +189,7 @@ public class JarVerifierStream extends ZipInputStream { static class CertCache { Certificate [] certs; - Vector ids; + Vector ids; boolean equals(Certificate[] certs) { if (this.certs == null) { @@ -229,21 +229,21 @@ public class JarVerifierStream extends ZipInputStream { } } - private ArrayList certCache = null; + private ArrayList certCache = null; /** * Returns the Identity vector for the given array of Certificates */ - protected Vector getIds(Certificate[] certs) { + protected Vector getIds(Certificate[] certs) { if (certs == null) return null; if (certCache == null) - certCache = new ArrayList(); + certCache = new ArrayList(); CertCache cc; for (int i = 0; i < certCache.size(); i++) { - cc = (CertCache) certCache.get(i); + cc = certCache.get(i); if (cc.equals(certs)) { return cc.ids; } @@ -265,8 +265,8 @@ public class JarVerifierStream extends ZipInputStream { new sun.security.x509.X509Cert(encoded); try { AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction() { - public Object run() + new java.security.PrivilegedExceptionAction() { + public Void run() throws java.security.KeyManagementException { id.addCertificate(oldC); @@ -278,7 +278,7 @@ public class JarVerifierStream extends ZipInputStream { pae.getException(); } if (cc.ids == null) - cc.ids = new Vector(); + cc.ids = new Vector(); cc.ids.addElement(id); } catch (java.security.KeyManagementException kme) { // ignore if we can't create Identity diff --git a/jdk/src/share/classes/sun/tools/native2ascii/N2AFilter.java b/jdk/src/share/classes/sun/tools/native2ascii/N2AFilter.java index 0a5706e061c..82c807d2e1b 100644 --- a/jdk/src/share/classes/sun/tools/native2ascii/N2AFilter.java +++ b/jdk/src/share/classes/sun/tools/native2ascii/N2AFilter.java @@ -42,7 +42,7 @@ class N2AFilter extends FilterWriter { public void write(char b) throws IOException { char[] buf = new char[1]; - buf[0] = (char)b; + buf[0] = b; write(buf, 0, 1); } diff --git a/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java b/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java index 4b5b6d20d42..a48dc65fbbb 100644 --- a/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java +++ b/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java @@ -52,14 +52,10 @@ class FileSystemPreferences extends AbstractPreferences { * Sync interval in seconds. */ private static final int SYNC_INTERVAL = Math.max(1, - Integer.parseInt((String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty("java.util.prefs.syncInterval", - "30"); - } - }))); - + Integer.parseInt( + AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "java.util.prefs.syncInterval", "30")))); /** * Returns logger for error messages. Backing store exceptions are logged at @@ -103,8 +99,8 @@ class FileSystemPreferences extends AbstractPreferences { } private static void setupUserRoot() { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { userRootDir = new File(System.getProperty("java.util.prefs.userRoot", System.getProperty("user.home")), ".java/.userPrefs"); @@ -164,9 +160,9 @@ class FileSystemPreferences extends AbstractPreferences { } private static void setupSystemRoot() { - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - String systemPrefsDirName = (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + String systemPrefsDirName = System.getProperty("java.util.prefs.systemRoot","/etc/.java"); systemRootDir = new File(systemPrefsDirName, ".systemPrefs"); @@ -322,7 +318,7 @@ class FileSystemPreferences extends AbstractPreferences { * corresponding disk file (prefsFile) by the sync operation. The initial * value is read *without* acquiring the file-lock. */ - private Map prefsCache = null; + private Map prefsCache = null; /** * The last modification time of the file backing this node at the time @@ -358,7 +354,7 @@ class FileSystemPreferences extends AbstractPreferences { * log against that map. The resulting map is then written back * to the disk. */ - final List changeLog = new ArrayList(); + final List changeLog = new ArrayList(); /** * Represents a change to a preference. @@ -424,7 +420,7 @@ class FileSystemPreferences extends AbstractPreferences { */ private void replayChanges() { for (int i = 0, n = changeLog.size(); i() { + public Void run() { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { syncTimer.cancel(); @@ -503,15 +499,15 @@ class FileSystemPreferences extends AbstractPreferences { dir = new File(parent.dir, dirName(name)); prefsFile = new File(dir, "prefs.xml"); tmpFile = new File(dir, "prefs.tmp"); - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { newNode = !dir.exists(); return null; } }); if (newNode) { // These 2 things guarantee node will get wrtten at next flush/sync - prefsCache = new TreeMap(); + prefsCache = new TreeMap(); nodeCreate = new NodeCreate(); changeLog.add(nodeCreate); } @@ -529,7 +525,7 @@ class FileSystemPreferences extends AbstractPreferences { protected String getSpi(String key) { initCacheIfNecessary(); - return (String) prefsCache.get(key); + return prefsCache.get(key); } protected void removeSpi(String key) { @@ -554,7 +550,7 @@ class FileSystemPreferences extends AbstractPreferences { loadCache(); } catch(Exception e) { // assert lastSyncTime == 0; - prefsCache = new TreeMap(); + prefsCache = new TreeMap(); } } @@ -568,9 +564,10 @@ class FileSystemPreferences extends AbstractPreferences { */ private void loadCache() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { - Map m = new TreeMap(); + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { + Map m = new TreeMap(); long newLastSyncTime = 0; try { newLastSyncTime = prefsFile.lastModified(); @@ -584,7 +581,7 @@ class FileSystemPreferences extends AbstractPreferences { prefsFile.renameTo( new File( prefsFile.getParentFile(), "IncorrectFormatPrefs.xml")); - m = new TreeMap(); + m = new TreeMap(); } else if (e instanceof FileNotFoundException) { getLogger().warning("Prefs file removed in background " + prefsFile.getPath()); @@ -614,8 +611,9 @@ class FileSystemPreferences extends AbstractPreferences { */ private void writeBackCache() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { try { if (!dir.exists() && !dir.mkdirs()) throw new BackingStoreException(dir + @@ -641,15 +639,14 @@ class FileSystemPreferences extends AbstractPreferences { protected String[] keysSpi() { initCacheIfNecessary(); - return (String[]) - prefsCache.keySet().toArray(new String[prefsCache.size()]); + return prefsCache.keySet().toArray(new String[prefsCache.size()]); } protected String[] childrenNamesSpi() { - return (String[]) - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { - List result = new ArrayList(); + return AccessController.doPrivileged( + new PrivilegedAction() { + public String[] run() { + List result = new ArrayList(); File[] dirContents = dir.listFiles(); if (dirContents != null) { for (int i = 0; i < dirContents.length; i++) @@ -685,8 +682,9 @@ class FileSystemPreferences extends AbstractPreferences { */ protected void removeNodeSpi() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { if (changeLog.contains(nodeCreate)) { changeLog.remove(nodeCreate); nodeCreate = null; @@ -731,8 +729,9 @@ class FileSystemPreferences extends AbstractPreferences { if (!lockFile(shared)) throw(new BackingStoreException("Couldn't get file lock.")); final Long newModTime = - (Long) AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged( + new PrivilegedAction() { + public Long run() { long nmt; if (isUserNode()) { nmt = userRootModFile.lastModified(); @@ -746,8 +745,8 @@ class FileSystemPreferences extends AbstractPreferences { }); try { super.sync(); - AccessController.doPrivileged( new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { if (isUserNode()) { userRootModTime = newModTime.longValue() + 1000; userRootModFile.setLastModified(userRootModTime); @@ -766,8 +765,9 @@ class FileSystemPreferences extends AbstractPreferences { protected void syncSpi() throws BackingStoreException { try { - AccessController.doPrivileged( new PrivilegedExceptionAction() { - public Object run() throws BackingStoreException { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws BackingStoreException { syncSpiPrivileged(); return null; } @@ -794,7 +794,7 @@ class FileSystemPreferences extends AbstractPreferences { } else if (lastSyncTime != 0 && !dir.exists()) { // This node was removed in the background. Playback any changes // against a virgin (empty) Map. - prefsCache = new TreeMap(); + prefsCache = new TreeMap(); replayChanges(); } if (!changeLog.isEmpty()) { diff --git a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java index 2514a2fffc0..f56a159294e 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java @@ -217,8 +217,7 @@ class DevPollArrayWrapper { Updator u = null; while ((u = updateList.poll()) != null) { // First add pollfd struct to clear out this fd - putPollFD(updatePollArray, index, u.fd, - (short)POLLREMOVE); + putPollFD(updatePollArray, index, u.fd, POLLREMOVE); index++; // Now add pollfd to update this fd, if necessary if (u.mask != POLLREMOVE) { diff --git a/jdk/src/solaris/classes/sun/security/provider/NativePRNG.java b/jdk/src/solaris/classes/sun/security/provider/NativePRNG.java index 8e25f256068..cfa19f8f478 100644 --- a/jdk/src/solaris/classes/sun/security/provider/NativePRNG.java +++ b/jdk/src/solaris/classes/sun/security/provider/NativePRNG.java @@ -71,8 +71,9 @@ public final class NativePRNG extends SecureRandomSpi { private static final RandomIO INSTANCE = initIO(); private static RandomIO initIO() { - Object o = AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public RandomIO run() { File randomFile = new File(NAME_RANDOM); if (randomFile.exists() == false) { return null; @@ -88,7 +89,6 @@ public final class NativePRNG extends SecureRandomSpi { } } }); - return (RandomIO)o; } // return whether the NativePRNG is available diff --git a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java index b867a76e5d9..99a5165a90d 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java +++ b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java @@ -48,8 +48,8 @@ public final class SunMSCAPI extends Provider { private static final String INFO = "Sun's Microsoft Crypto API provider"; static { - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { System.loadLibrary("sunmscapi"); return null; } From f8103008516cccbcc6c9e48f14d0cd620aeb8189 Mon Sep 17 00:00:00 2001 From: Luis Miguel Alventosa Date: Mon, 10 Mar 2008 23:13:31 +0100 Subject: [PATCH 112/274] 4981215: Publishing a port number for management console to access Reviewed-by: emcmanus, dfuchs --- .../sun/management/ConnectorAddressLink.java | 121 ++++++++++-- .../jmxremote/ConnectorBootstrap.java | 162 ++++++++++------ .../bootstrap/JvmstatCountersTest.java | 183 ++++++++++++++++++ 3 files changed, 386 insertions(+), 80 deletions(-) create mode 100644 jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java diff --git a/jdk/src/share/classes/sun/management/ConnectorAddressLink.java b/jdk/src/share/classes/sun/management/ConnectorAddressLink.java index 58b1b3f5a70..093746c3164 100644 --- a/jdk/src/share/classes/sun/management/ConnectorAddressLink.java +++ b/jdk/src/share/classes/sun/management/ConnectorAddressLink.java @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems, Inc. 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,12 +25,13 @@ package sun.management; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.Iterator; -import java.util.Set; import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import sun.misc.Perf; import sun.management.counter.Units; @@ -46,36 +47,67 @@ import sun.management.counter.perf.PerfInstrumentation; public class ConnectorAddressLink { private static final String CONNECTOR_ADDRESS_COUNTER = - "sun.management.JMXConnectorServer.address"; + "sun.management.JMXConnectorServer.address"; + + /* + * The format of the jvmstat counters representing the properties of + * a given out-of-the-box JMX remote connector will be as follows: + * + * sun.management.JMXConnectorServer..= + * + * where: + * + * counter = index computed by this class which uniquely identifies + * an out-of-the-box JMX remote connector running in this + * Java virtual machine. + * key/value = a given key/value pair in the map supplied to the + * exportRemote() method. + * + * For example, + * + * sun.management.JMXConnectorServer.0.remoteAddress=service:jmx:rmi:///jndi/rmi://myhost:5000/jmxrmi + * sun.management.JMXConnectorServer.0.authenticate=false + * sun.management.JMXConnectorServer.0.ssl=false + * sun.management.JMXConnectorServer.0.sslRegistry=false + * sun.management.JMXConnectorServer.0.sslNeedClientAuth=false + */ + private static final String REMOTE_CONNECTOR_COUNTER_PREFIX = + "sun.management.JMXConnectorServer."; + + /* + * JMX remote connector counter (it will be incremented every + * time a new out-of-the-box JMX remote connector is created). + */ + private static AtomicInteger counter = new AtomicInteger(); /** * Exports the specified connector address to the instrumentation buffer * so that it can be read by this or other Java virtual machines running * on the same system. * - * @param address The connector address. + * @param address The connector address. */ public static void export(String address) { if (address == null || address.length() == 0) { throw new IllegalArgumentException("address not specified"); } Perf perf = Perf.getPerf(); - perf.createString(CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address); + perf.createString( + CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address); } /** * Imports the connector address from the instrument buffer * of the specified Java virtual machine. * - * @param vmid an identifier that uniquely identifies a local - * Java virtual machine, or 0 to indicate - * the current Java virtual machine. + * @param vmid an identifier that uniquely identifies a local Java virtual + * machine, or 0 to indicate the current Java virtual machine. * - * @return the value of the connector address, or null - * if the target VM has not exported a connector address. + * @return the value of the connector address, or null if the + * target VM has not exported a connector address. * - * @throws IOException An I/O error occurred while trying to acquire - * the instrumentation buffer. + * @throws IOException An I/O error occurred while trying to acquire the + * instrumentation buffer. */ public static String importFrom(int vmid) throws IOException { Perf perf = Perf.getPerf(); @@ -85,14 +117,65 @@ public class ConnectorAddressLink { } catch (IllegalArgumentException iae) { throw new IOException(iae.getMessage()); } - List counters = (new PerfInstrumentation(bb)).findByPattern(CONNECTOR_ADDRESS_COUNTER); + List counters = + new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER); Iterator i = counters.iterator(); if (i.hasNext()) { - Counter c = (Counter)i.next(); - return (String)c.getValue(); + Counter c = (Counter) i.next(); + return (String) c.getValue(); } else { return null; } } + /** + * Exports the specified remote connector address and associated + * configuration properties to the instrumentation buffer so that + * it can be read by this or other Java virtual machines running + * on the same system. + * + * @param properties The remote connector address properties. + */ + public static void exportRemote(Map properties) { + final int index = counter.getAndIncrement(); + Perf perf = Perf.getPerf(); + for (Map.Entry entry : properties.entrySet()) { + perf.createString(REMOTE_CONNECTOR_COUNTER_PREFIX + index + "." + + entry.getKey(), 1, Units.STRING.intValue(), entry.getValue()); + } + } + + /** + * Imports the remote connector address and associated + * configuration properties from the instrument buffer + * of the specified Java virtual machine. + * + * @param vmid an identifier that uniquely identifies a local Java virtual + * machine, or 0 to indicate the current Java virtual machine. + * + * @return a map containing the remote connector's properties, or an empty + * map if the target VM has not exported the remote connector's properties. + * + * @throws IOException An I/O error occurred while trying to acquire the + * instrumentation buffer. + */ + public static Map importRemoteFrom(int vmid) throws IOException { + Perf perf = Perf.getPerf(); + ByteBuffer bb; + try { + bb = perf.attach(vmid, "r"); + } catch (IllegalArgumentException iae) { + throw new IOException(iae.getMessage()); + } + List counters = new PerfInstrumentation(bb).getAllCounters(); + Map properties = new HashMap(); + for (Object c : counters) { + String name = ((Counter) c).getName(); + if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) && + !name.equals(CONNECTOR_ADDRESS_COUNTER)) { + properties.put(name, ((Counter) c).getValue().toString()); + } + } + return properties; + } } diff --git a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java index 0463db83f89..43cae9144e9 100644 --- a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java +++ b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -39,6 +39,7 @@ import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.Registry; +import java.rmi.server.RemoteObject; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.UnicastRemoteObject; @@ -70,12 +71,14 @@ import javax.rmi.ssl.SslRMIServerSocketFactory; import javax.security.auth.Subject; +import sun.rmi.server.UnicastRef; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; import sun.management.Agent; import sun.management.AgentConfigurationError; import static sun.management.AgentConfigurationError.*; +import sun.management.ConnectorAddressLink; import sun.management.FileSystem; import sun.management.snmp.util.MibLogger; @@ -92,20 +95,22 @@ public final class ConnectorBootstrap { * Default values for JMX configuration properties. **/ public static interface DefaultValues { - public static final String PORT="0"; - public static final String CONFIG_FILE_NAME="management.properties"; - public static final String USE_SSL="true"; - public static final String USE_REGISTRY_SSL="false"; - public static final String USE_AUTHENTICATION="true"; - public static final String PASSWORD_FILE_NAME="jmxremote.password"; - public static final String ACCESS_FILE_NAME="jmxremote.access"; - public static final String SSL_NEED_CLIENT_AUTH="false"; + + public static final String PORT = "0"; + public static final String CONFIG_FILE_NAME = "management.properties"; + public static final String USE_SSL = "true"; + public static final String USE_REGISTRY_SSL = "false"; + public static final String USE_AUTHENTICATION = "true"; + public static final String PASSWORD_FILE_NAME = "jmxremote.password"; + public static final String ACCESS_FILE_NAME = "jmxremote.access"; + public static final String SSL_NEED_CLIENT_AUTH = "false"; } /** * Names of JMX configuration properties. **/ public static interface PropertyNames { + public static final String PORT = "com.sun.management.jmxremote.port"; public static final String CONFIG_FILE_NAME = @@ -132,6 +137,21 @@ public final class ConnectorBootstrap { "com.sun.management.jmxremote.ssl.config.file"; } + /** + * JMXConnectorServer associated data. + */ + private static class JMXConnectorServerData { + + public JMXConnectorServerData( + JMXConnectorServer jmxConnectorServer, + JMXServiceURL jmxRemoteURL) { + this.jmxConnectorServer = jmxConnectorServer; + this.jmxRemoteURL = jmxRemoteURL; + } + JMXConnectorServer jmxConnectorServer; + JMXServiceURL jmxRemoteURL; + } + /** *

    Prevents our RMI server objects from keeping the JVM alive.

    * @@ -151,6 +171,7 @@ public final class ConnectorBootstrap { * works). Hence the somewhat misleading name of this class.

    */ private static class PermanentExporter implements RMIExporter { + public Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, @@ -158,24 +179,25 @@ public final class ConnectorBootstrap { throws RemoteException { synchronized (this) { - if (firstExported == null) + if (firstExported == null) { firstExported = obj; + } } final UnicastServerRef ref; - if (csf == null && ssf == null) + if (csf == null && ssf == null) { ref = new UnicastServerRef(port); - else + } else { ref = new UnicastServerRef2(port, csf, ssf); + } return ref.exportObject(obj, null, true); } // Nothing special to be done for this case public boolean unexportObject(Remote obj, boolean force) - throws NoSuchObjectException { + throws NoSuchObjectException { return UnicastRemoteObject.unexportObject(obj, force); } - Remote firstExported; } @@ -202,19 +224,21 @@ public final class ConnectorBootstrap { } private void checkAccessFileEntries(Subject subject) { - if (subject == null) + if (subject == null) { throw new SecurityException( "Access denied! No matching entries found in " + "the access file [" + accessFile + "] as the " + "authenticated Subject is null"); + } final Set principals = subject.getPrincipals(); - for (Iterator i = principals.iterator(); i.hasNext(); ) { + for (Iterator i = principals.iterator(); i.hasNext();) { final Principal p = (Principal) i.next(); - if (properties.containsKey(p.getName())) + if (properties.containsKey(p.getName())) { return; + } } final Set principalsStr = new HashSet(); - for (Iterator i = principals.iterator(); i.hasNext(); ) { + for (Iterator i = principals.iterator(); i.hasNext();) { final Principal p = (Principal) i.next(); principalsStr.add(p.getName()); } @@ -225,16 +249,16 @@ public final class ConnectorBootstrap { } private static Properties propertiesFromFile(String fname) - throws IOException { + throws IOException { Properties p = new Properties(); - if (fname == null) + if (fname == null) { return p; + } FileInputStream fin = new FileInputStream(fname); p.load(fin); fin.close(); return p; } - private final Map environment; private final Properties properties; private final String accessFile; @@ -251,22 +275,23 @@ public final class ConnectorBootstrap { // Load a new management properties final Properties props = Agent.loadManagementProperties(); - if (props == null) return null; + if (props == null) { + return null; + } final String portStr = props.getProperty(PropertyNames.PORT); // System.out.println("initializing: {port=" + portStr + ", // properties="+props+"}"); - return initialize(portStr,props); + return initialize(portStr, props); } /** * Initializes and starts a JMX Connector Server for remote * monitoring and management. **/ - public static synchronized - JMXConnectorServer initialize(String portStr, Properties props) { + public static synchronized JMXConnectorServer initialize(String portStr, Properties props) { // Get port number final int port; @@ -280,21 +305,21 @@ public final class ConnectorBootstrap { } // Do we use authentication? - final String useAuthenticationStr = + final String useAuthenticationStr = props.getProperty(PropertyNames.USE_AUTHENTICATION, DefaultValues.USE_AUTHENTICATION); final boolean useAuthentication = Boolean.valueOf(useAuthenticationStr).booleanValue(); // Do we use SSL? - final String useSslStr = + final String useSslStr = props.getProperty(PropertyNames.USE_SSL, DefaultValues.USE_SSL); final boolean useSsl = Boolean.valueOf(useSslStr).booleanValue(); // Do we use RMI Registry SSL? - final String useRegistrySslStr = + final String useRegistrySslStr = props.getProperty(PropertyNames.USE_REGISTRY_SSL, DefaultValues.USE_REGISTRY_SSL); final boolean useRegistrySsl = @@ -307,7 +332,7 @@ public final class ConnectorBootstrap { StringTokenizer st = new StringTokenizer(enabledCipherSuites, ","); int tokens = st.countTokens(); enabledCipherSuitesList = new String[tokens]; - for (int i = 0 ; i < tokens; i++) { + for (int i = 0; i < tokens; i++) { enabledCipherSuitesList[i] = st.nextToken(); } } @@ -319,12 +344,12 @@ public final class ConnectorBootstrap { StringTokenizer st = new StringTokenizer(enabledProtocols, ","); int tokens = st.countTokens(); enabledProtocolsList = new String[tokens]; - for (int i = 0 ; i < tokens; i++) { + for (int i = 0; i < tokens; i++) { enabledProtocolsList[i] = st.nextToken(); } } - final String sslNeedClientAuthStr = + final String sslNeedClientAuthStr = props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH, DefaultValues.SSL_NEED_CLIENT_AUTH); final boolean sslNeedClientAuth = @@ -374,39 +399,49 @@ public final class ConnectorBootstrap { sslNeedClientAuth + "\n\t" + PropertyNames.USE_AUTHENTICATION + "=" + useAuthentication + - (useAuthentication ? - (loginConfigName == null ? - ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" + - passwordFileName) : - ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" + + (useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" + + passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" + loginConfigName)) : "\n\t" + Agent.getText("jmxremote.ConnectorBootstrap.initialize.noAuthentication")) + - (useAuthentication ? - ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" + + (useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" + accessFileName) : "") + ""); } final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); JMXConnectorServer cs = null; + JMXServiceURL url = null; try { - cs = exportMBeanServer(mbs, port, useSsl, useRegistrySsl, + final JMXConnectorServerData data = exportMBeanServer( + mbs, port, useSsl, useRegistrySsl, sslConfigFileName, enabledCipherSuitesList, enabledProtocolsList, sslNeedClientAuth, useAuthentication, loginConfigName, passwordFileName, accessFileName); - - final JMXServiceURL url = cs.getAddress(); + cs = data.jmxConnectorServer; + url = data.jmxRemoteURL; log.config("initialize", Agent.getText("jmxremote.ConnectorBootstrap.initialize.ready", - new JMXServiceURL(url.getProtocol(), - url.getHost(), - url.getPort(), - "/jndi/rmi://"+url.getHost()+":"+port+"/"+ - "jmxrmi").toString())); + url.toString())); } catch (Exception e) { throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString()); } + try { + // Export remote connector address and associated configuration + // properties to the instrumentation buffer. + Map properties = new HashMap(); + properties.put("remoteAddress", url.toString()); + properties.put("authenticate", useAuthenticationStr); + properties.put("ssl", useSslStr); + properties.put("sslRegistry", useRegistrySslStr); + properties.put("sslNeedClientAuth", sslNeedClientAuthStr); + ConnectorAddressLink.exportRemote(properties); + } catch (Exception e) { + // Remote connector server started but unable to export remote + // connector address and associated configuration properties to + // the instrumentation buffer - non-fatal error. + log.debug("initialize", e); + } return cs; } @@ -452,7 +487,7 @@ public final class ConnectorBootstrap { } private static void checkPasswordFile(String passwordFileName) { - if (passwordFileName == null || passwordFileName.length()==0) { + if (passwordFileName == null || passwordFileName.length() == 0) { throw new AgentConfigurationError(PASSWORD_FILE_NOT_SET); } File file = new File(passwordFileName); @@ -468,9 +503,9 @@ public final class ConnectorBootstrap { try { if (fs.supportsFileSecurity(file)) { if (!fs.isAccessUserOnly(file)) { - final String msg=Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly", + final String msg = Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly", passwordFileName); - log.config("initialize",msg); + log.config("initialize", msg); throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED, passwordFileName); } @@ -482,7 +517,7 @@ public final class ConnectorBootstrap { } private static void checkAccessFile(String accessFileName) { - if (accessFileName == null || accessFileName.length()==0) { + if (accessFileName == null || accessFileName.length() == 0) { throw new AgentConfigurationError(ACCESS_FILE_NOT_SET); } File file = new File(accessFileName); @@ -619,7 +654,7 @@ public final class ConnectorBootstrap { } } - private static JMXConnectorServer exportMBeanServer( + private static JMXConnectorServerData exportMBeanServer( MBeanServer mbs, int port, boolean useSsl, @@ -697,24 +732,30 @@ public final class ConnectorBootstrap { } final Registry registry; - if (useRegistrySsl) + if (useRegistrySsl) { registry = new SingleEntryRegistry(port, csf, ssf, "jmxrmi", exporter.firstExported); - else + } else { registry = new SingleEntryRegistry(port, "jmxrmi", exporter.firstExported); + } + + JMXServiceURL remoteURL = new JMXServiceURL( + "service:jmx:rmi:///jndi/rmi://" + url.getHost() + ":" + + ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort() + + "/jmxrmi"); /* Our exporter remembers the first object it was asked to - export, which will be an RMIServerImpl appropriate for - publication in our special registry. We could - alternatively have constructed the RMIServerImpl explicitly - and then constructed an RMIConnectorServer passing it as a - parameter, but that's quite a bit more verbose and pulls in - lots of knowledge of the RMI connector. */ + export, which will be an RMIServerImpl appropriate for + publication in our special registry. We could + alternatively have constructed the RMIServerImpl explicitly + and then constructed an RMIConnectorServer passing it as a + parameter, but that's quite a bit more verbose and pulls in + lots of knowledge of the RMI connector. */ - return connServer; + return new JMXConnectorServerData(connServer, remoteURL); } /** @@ -726,5 +767,4 @@ public final class ConnectorBootstrap { // XXX Revisit: should probably clone this MibLogger.... private static final MibLogger log = new MibLogger(ConnectorBootstrap.class); - } diff --git a/jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java b/jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java new file mode 100644 index 00000000000..3f23b0bf7bf --- /dev/null +++ b/jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java @@ -0,0 +1,183 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 4981215 + * @summary Tests that the jvmstat counters published by the out-of-the-box + * management agent for the JMX connection details are correct. + * @author Luis-Miguel Alventosa + * @run clean JvmstatCountersTest + * @run build JvmstatCountersTest + * @run main/othervm JvmstatCountersTest 1 + * @run main/othervm -Dcom.sun.management.jmxremote JvmstatCountersTest 2 + * @run main/othervm -Dcom.sun.management.jmxremote.port=0 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false JvmstatCountersTest 3 + * @run main/othervm JvmstatCountersTest 4 + */ + +import java.io.*; +import java.lang.management.*; +import java.util.*; +import javax.management.*; +import javax.management.remote.*; +import com.sun.tools.attach.*; +import sun.management.ConnectorAddressLink; + +public class JvmstatCountersTest { + + public static void checkAddress(String address) throws IOException { + System.out.println("Address = " + address); + JMXServiceURL url = new JMXServiceURL(address); + JMXConnector jmxc = JMXConnectorFactory.connect(url); + MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); + System.out.println("MBean Count = " + mbsc.getMBeanCount()); + } + + public static void checkKey(Map data, int index, + String key, String expectedValue) throws Exception { + String counter = "sun.management.JMXConnectorServer." + index + "." + key; + if (!data.containsKey(counter)) { + System.out.println("Test FAILED! Missing counter " + counter); + throw new IllegalArgumentException("Test case failed"); + } + String value = data.get(counter); + if (key.equals("remoteAddress")) { + checkAddress(value); + } else if (!expectedValue.equals(value)) { + System.out.println("Test FAILED! Invalid counter " + + counter + "=" + value); + throw new IllegalArgumentException("Test case failed"); + } + System.out.println("OK: " + counter + "=" + value); + } + + public static void main(String args[]) throws Exception { + String localAddress = ConnectorAddressLink.importFrom(0); + Map remoteData = ConnectorAddressLink.importRemoteFrom(0); + final int testCase = Integer.parseInt(args[0]); + switch (testCase) { + case 1: + if (localAddress == null && remoteData.isEmpty()) { + System.out.println("Test PASSED! The OOTB management " + + "agent didn't publish any jvmstat counter."); + } else { + System.out.println("Test FAILED! The OOTB management " + + "agent unexpectedly published jvmstat counters."); + throw new IllegalArgumentException("Test case 1 failed"); + } + break; + case 2: + if (localAddress == null) { + System.out.println("Test FAILED! The OOTB management " + + "agent didn't publish the local connector."); + throw new IllegalArgumentException("Test case 2 failed"); + } + checkAddress(localAddress); + if (!remoteData.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent shouldn't publish the remote connector."); + throw new IllegalArgumentException("Test case 2 failed"); + } + System.out.println("Test PASSED! The OOTB management " + + "agent only publishes the local connector through " + + "a jvmstat counter."); + break; + case 3: + if (localAddress == null) { + System.out.println("Test FAILED! The OOTB management " + + "agent didn't publish the local connector."); + throw new IllegalArgumentException("Test case 3 failed"); + } + checkAddress(localAddress); + if (remoteData.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent didnn't publish the remote connector."); + throw new IllegalArgumentException("Test case 3 failed"); + } + for (String key : remoteData.keySet()) { + if (!key.startsWith("sun.management.JMXConnectorServer.0.")) { + System.out.println("Test FAILED! The OOTB management " + + "agent shouldn't publish anything which isn't " + + "related to the remote connector."); + throw new IllegalArgumentException("Test case 3 failed"); + } + } + checkKey(remoteData, 0, "remoteAddress", null); + checkKey(remoteData, 0, "authenticate", "false"); + checkKey(remoteData, 0, "ssl", "false"); + checkKey(remoteData, 0, "sslRegistry", "false"); + checkKey(remoteData, 0, "sslNeedClientAuth", "false"); + System.out.println("Test PASSED! The OOTB management " + + "agent publishes both the local and remote " + + "connector info through jvmstat counters."); + break; + case 4: + if (localAddress != null || !remoteData.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent unexpectedly published jvmstat counters."); + throw new IllegalArgumentException("Test case 4 failed"); + } + RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean(); + String name = rt.getName(); + System.out.println("name = " + name); + String vmid = name.substring(0, name.indexOf("@")); + System.out.println("vmid = " + vmid); + VirtualMachine vm = VirtualMachine.attach(vmid); + String agent = vm.getSystemProperties().getProperty("java.home") + + File.separator + "lib" + File.separator + "management-agent.jar"; + vm.loadAgent(agent, "com.sun.management.jmxremote.port=0,com.sun.management.jmxremote.authenticate=false,com.sun.management.jmxremote.ssl=false"); + vm.detach(); + String localAddress2 = ConnectorAddressLink.importFrom(0); + if (localAddress2 == null) { + System.out.println("Test FAILED! The OOTB management " + + "agent didn't publish the local connector."); + throw new IllegalArgumentException("Test case 4 failed"); + } + checkAddress(localAddress2); + Map remoteData2 = ConnectorAddressLink.importRemoteFrom(0); + if (remoteData2.isEmpty()) { + System.out.println("Test FAILED! The OOTB management " + + "agent didnn't publish the remote connector."); + throw new IllegalArgumentException("Test case 4 failed"); + } + for (String key : remoteData2.keySet()) { + if (!key.startsWith("sun.management.JMXConnectorServer.0.")) { + System.out.println("Test FAILED! The OOTB management " + + "agent shouldn't publish anything which isn't " + + "related to the remote connector."); + throw new IllegalArgumentException("Test case 4 failed"); + } + } + checkKey(remoteData2, 0, "remoteAddress", null); + checkKey(remoteData2, 0, "authenticate", "false"); + checkKey(remoteData2, 0, "ssl", "false"); + checkKey(remoteData2, 0, "sslRegistry", "false"); + checkKey(remoteData2, 0, "sslNeedClientAuth", "false"); + System.out.println("Test PASSED! The OOTB management agent " + + "publishes both the local and remote connector " + + "info through jvmstat counters when the agent is " + + "loaded through the Attach API."); + } + System.out.println("Bye! Bye!"); + } +} From c0165a4ae8edbf1c53d2ca58dfbcd3615ef5d2be Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Mon, 10 Mar 2008 16:51:23 -0700 Subject: [PATCH 113/274] 6649672: Adjustments to OUTPUTDIR default and mkdirs to avoid empty directory clutter OUTPUTDIR changes to make sure absolute path is correct. Reviewed-by: xdono --- jdk/make/common/Defs.gmk | 8 ---- jdk/make/common/shared/Defs-control.gmk | 5 ++- jdk/make/common/shared/Defs.gmk | 59 +++++++++++++++++++------ 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 92da33487ce..6fe53ebeced 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -178,14 +178,6 @@ ifdef OPENJDK endif endif # OPENJDK -# Default output directory -ifdef OPENJDK -_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX) -else -_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH) -endif - - # # Get platform definitions # diff --git a/jdk/make/common/shared/Defs-control.gmk b/jdk/make/common/shared/Defs-control.gmk index ec94a2ed7ae..172166aed91 100644 --- a/jdk/make/common/shared/Defs-control.gmk +++ b/jdk/make/common/shared/Defs-control.gmk @@ -36,7 +36,7 @@ ifndef JDK_MAKE_SHARED_DIR endif ifndef CONTROL_TOPDIR - CONTROL_TOPDIR=$(TOPDIR)/control + CONTROL_TOPDIR=$(TOPDIR) endif ifndef HOTSPOT_TOPDIR HOTSPOT_TOPDIR=$(TOPDIR)/hotspot @@ -70,7 +70,8 @@ endif include $(JDK_MAKE_SHARED_DIR)/Platform.gmk # Default output directory -_OUTPUTDIR=$(CONTROL_TOPDIR)/build/$(PLATFORM)-$(ARCH) +BUILD_PARENT_DIRECTORY=$(TOPDIR) +_OUTPUTDIR=$(TOPDIR)/build/$(PLATFORM)-$(ARCH) # Get platform specific settings include $(JDK_MAKE_SHARED_DIR)/Defs.gmk diff --git a/jdk/make/common/shared/Defs.gmk b/jdk/make/common/shared/Defs.gmk index c2a8278bddf..0eb8c729a96 100644 --- a/jdk/make/common/shared/Defs.gmk +++ b/jdk/make/common/shared/Defs.gmk @@ -55,7 +55,10 @@ include $(JDK_MAKE_SHARED_DIR)/Defs-utils.gmk # Simple pwd path define PwdPath -$(shell cd $1 2> $(DEV_NULL) && pwd) +$(shell $(CD) $1 2> $(DEV_NULL) && $(PWD)) +endef +define AbsPwdPathCheck +$(shell $(CD) .. 2> $(DEV_NULL) && $(CD) $1 2> $(DEV_NULL) && $(PWD)) endef # Checks an ALT value for spaces (should be one word), @@ -422,23 +425,54 @@ CACERTS_FILE:=$(call AltCheckSpaces,CACERTS_FILE) CACERTS_FILE:=$(call AltCheckValue,CACERTS_FILE) # OUTPUTDIR: Location of all output for the build -_BACKUP_OUTPUTDIR = $(TEMP_DISK)/$(USER)/jdk-outputdir ifdef ALT_OUTPUTDIR - _POSSIBLE_OUTPUTDIR =$(subst \,/,$(ALT_OUTPUTDIR)) + OUTPUTDIR:=$(subst \,/,$(ALT_OUTPUTDIR)) + # Assumes this is absolute (checks later) + ABS_OUTPUTDIR:=$(OUTPUTDIR) else ifndef _OUTPUTDIR - _OUTPUTDIR = $(_BACKUP_OUTPUTDIR) + # Default: Get "build" parent directory, which should always exist + ifndef BUILD_PARENT_DIRECTORY + BUILD_PARENT_DIRECTORY=$(BUILDDIR)/.. + endif + ABS_BUILD_PARENT_DIRECTORY:=$(call FullPath,$(BUILD_PARENT_DIRECTORY)) + ifdef OPENJDK + _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX) + else + _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH) + endif + _OUTPUTDIR=$(BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME) + ABS_OUTPUTDIR:=$(ABS_BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME) endif - _POSSIBLE_OUTPUTDIR =$(_OUTPUTDIR) -endif -_create_outputdir1:=$(shell mkdir -p $(_POSSIBLE_OUTPUTDIR) > $(DEV_NULL) 2>&1) -OUTPUTDIR:=$(call WriteDirExists,$(_POSSIBLE_OUTPUTDIR),$(_BACKUP_OUTPUTDIR)) -_create_outputdir2:=$(shell mkdir -p $(OUTPUTDIR) > $(DEV_NULL) 2>&1) -ifeq "$(OUTPUTDIR)" "$(_BACKUP_OUTPUTDIR)" - _outputdir_warning:=$(warning "WARNING: OUTPUTDIR '$(_POSSIBLE_OUTPUTDIR)' not writable, will use '$(_BACKUP_OUTPUTDIR)'") + OUTPUTDIR:=$(_OUTPUTDIR) endif +# Check for spaces and null value OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR) OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR) +# Create the output directory and make sure it exists and is writable +_create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1) +ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null) + _outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable") +endif +# Define absolute path if needed and check for spaces and null value +ifndef ABS_OUTPUTDIR + ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) +endif +ABS_OUTPUTDIR:=$(call AltCheckSpaces,ABS_OUTPUTDIR) +ABS_OUTPUTDIR:=$(call AltCheckValue,ABS_OUTPUTDIR) +# Make doubly sure this is a full path +ifeq ($(call AbsPwdPathCheck,$(ABS_OUTPUTDIR)), ) + ifdef ALT_OUTPUTDIR + _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)', was ALT_OUTPUTDIR '$(ALT_OUTPUTDIR)' an absolute path?") + else + _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)'") + endif +endif +_dir1:=$(call FullPath,$(ABS_OUTPUTDIR)) +_dir2:=$(call FullPath,$(OUTPUTDIR)) +ifneq ($(_dir1),$(_dir2)) + _outputdir_error:=$(error "ERROR: ABS_OUTPUTDIR '$(ABS_OUTPUTDIR)' is not the same directory as OUTPUTDIR '$(OUTPUTDIR)', '$(_dir1)'!='$(_dir2)'") +endif # Bin directory # NOTE: ISA_DIR is usually empty, on Solaris it might be /sparcv9 or /amd64 @@ -475,9 +509,6 @@ else COPYRIGHT_YEAR = $(shell $(DATE) '+%Y') endif -# Absolute path to output directory -ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) - # Get shared compiler settings include $(JDK_MAKE_SHARED_DIR)/Compiler.gmk From 134f15a93f80e39ac7da5fd1b7b70923a590d318 Mon Sep 17 00:00:00 2001 From: Luis Miguel Alventosa Date: Tue, 11 Mar 2008 01:20:55 +0100 Subject: [PATCH 114/274] 6655515: MBeans tab: operation return values of type Component displayed as String 6439590: MBeans tab: jconsole mbean tree not correctly refreshed 6446434: MBeans tab: Not possible to view MBean content before all MBeans have been initially loaded 6520144: Hard to find MBean Attributes, Operations, and Notifications in Java 6 jconsole 6522091: VMPanel.java contains non-ASCII character 6608334: JConsole fails to display MBean operation with return type 6611445: MBeans tab: MBean tree algorithm wrongly removes intermediate nodes Reviewed-by: dfuchs, jfdenise --- .../classes/sun/tools/jconsole/MBeansTab.java | 188 ++-- .../sun/tools/jconsole/MemoryPoolStat.java | 1 + .../classes/sun/tools/jconsole/VMPanel.java | 184 ++-- .../jconsole/inspector/OperationEntry.java | 2 +- .../tools/jconsole/inspector/TableSorter.java | 1 + .../jconsole/inspector/ThreadDialog.java | 1 + .../sun/tools/jconsole/inspector/Utils.java | 86 +- .../tools/jconsole/inspector/XDataViewer.java | 2 + .../sun/tools/jconsole/inspector/XMBean.java | 118 +-- .../tools/jconsole/inspector/XMBeanInfo.java | 117 +-- .../inspector/XMBeanNotifications.java | 487 +++++----- .../jconsole/inspector/XMBeanOperations.java | 1 + .../sun/tools/jconsole/inspector/XObject.java | 1 + .../tools/jconsole/inspector/XOperations.java | 184 ++-- .../tools/jconsole/inspector/XPlotter.java | 2 + .../jconsole/inspector/XPlottingViewer.java | 1 + .../sun/tools/jconsole/inspector/XSheet.java | 587 +++++++------ .../sun/tools/jconsole/inspector/XTable.java | 1 + .../tools/jconsole/inspector/XTextField.java | 1 + .../jconsole/inspector/XTextFieldEditor.java | 1 + .../sun/tools/jconsole/inspector/XTree.java | 831 ++++++++++-------- 21 files changed, 1485 insertions(+), 1312 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java b/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java index c2055d0916c..53260144e63 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java +++ b/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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.tools.jconsole; import java.awt.BorderLayout; +import java.awt.EventQueue; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; @@ -42,7 +43,8 @@ import com.sun.tools.jconsole.JConsoleContext; @SuppressWarnings("serial") public class MBeansTab extends Tab implements - NotificationListener, PropertyChangeListener, TreeSelectionListener { + NotificationListener, PropertyChangeListener, + TreeSelectionListener, TreeWillExpandListener { private XTree tree; private XSheet sheet; @@ -70,6 +72,7 @@ public class MBeansTab extends Tab implements return sheet; } + @Override public void dispose() { super.dispose(); sheet.dispose(); @@ -79,61 +82,79 @@ public class MBeansTab extends Tab implements return vmPanel.getUpdateInterval(); } - void synchroniseMBeanServerView() { - // Register listener for MBean registration/unregistration - // - try { - getMBeanServerConnection().addNotificationListener( - MBeanServerDelegate.DELEGATE_NAME, - this, - null, - null); - } catch (InstanceNotFoundException e) { - // Should never happen because the MBeanServerDelegate - // is always present in any standard MBeanServer - // - if (JConsole.isDebug()) { - e.printStackTrace(); + private void buildMBeanServerView() { + new SwingWorker, Void>() { + @Override + public Set doInBackground() { + // Register listener for MBean registration/unregistration + // + try { + getMBeanServerConnection().addNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, + MBeansTab.this, + null, + null); + } catch (InstanceNotFoundException e) { + // Should never happen because the MBeanServerDelegate + // is always present in any standard MBeanServer + // + if (JConsole.isDebug()) { + e.printStackTrace(); + } + } catch (IOException e) { + if (JConsole.isDebug()) { + e.printStackTrace(); + } + vmPanel.getProxyClient().markAsDead(); + return null; + } + // Retrieve MBeans from MBeanServer + // + Set mbeans = null; + try { + mbeans = getMBeanServerConnection().queryNames(null, null); + } catch (IOException e) { + if (JConsole.isDebug()) { + e.printStackTrace(); + } + vmPanel.getProxyClient().markAsDead(); + return null; + } + return mbeans; } - } catch (IOException e) { - if (JConsole.isDebug()) { - e.printStackTrace(); + @Override + protected void done() { + try { + // Wait for mbsc.queryNames() result + Set mbeans = get(); + // Do not display anything until the new tree has been built + // + tree.setVisible(false); + // Cleanup current tree + // + tree.removeAll(); + // Add MBeans to tree + // + tree.addMBeansToView(mbeans); + // Display the new tree + // + tree.setVisible(true); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem at MBean tree construction"); + t.printStackTrace(); + } + } } - vmPanel.getProxyClient().markAsDead(); - return; - } - // Retrieve MBeans from MBeanServer - // - Set newSet = null; - try { - newSet = getMBeanServerConnection().queryNames(null,null); - } catch (IOException e) { - if (JConsole.isDebug()) { - e.printStackTrace(); - } - vmPanel.getProxyClient().markAsDead(); - return; - } - // Cleanup current tree - // - tree.removeAll(); - // Do not display anything until the new tree has been built - // - tree.setVisible(false); - // Add MBeans to tree - // - for (ObjectName mbean : newSet) { - tree.addMBeanToView(mbean); - } - // Display the new tree - // - tree.setVisible(true); + }.execute(); } public MBeanServerConnection getMBeanServerConnection() { return vmPanel.getProxyClient().getMBeanServerConnection(); } + @Override public void update() { // Ping the connection to see if it is still alive. At // some point the ProxyClient class should centralize @@ -160,6 +181,7 @@ public class MBeansTab extends Tab implements tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(this); + tree.addTreeWillExpandListener(this); tree.addMouseListener(ml); JScrollPane theScrollPane = new JScrollPane( tree, @@ -177,55 +199,55 @@ public class MBeansTab extends Tab implements add(mainSplit); } - /* notification listener */ - public void handleNotification(Notification notification, Object handback) { - if (notification instanceof MBeanServerNotification) { - ObjectName mbean = - ((MBeanServerNotification) notification).getMBeanName(); - if (notification.getType().equals( - MBeanServerNotification.REGISTRATION_NOTIFICATION)) { - tree.addMBeanToView(mbean); - } else if (notification.getType().equals( - MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { - tree.delMBeanFromView(mbean); + /* notification listener: handleNotification */ + public void handleNotification( + final Notification notification, Object handback) { + EventQueue.invokeLater(new Runnable() { + public void run() { + if (notification instanceof MBeanServerNotification) { + ObjectName mbean = + ((MBeanServerNotification) notification).getMBeanName(); + if (notification.getType().equals( + MBeanServerNotification.REGISTRATION_NOTIFICATION)) { + tree.addMBeanToView(mbean); + } else if (notification.getType().equals( + MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { + tree.removeMBeanFromView(mbean); + } + } } - } + }); } - /* property change listener */ + /* property change listener: propertyChange */ public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName() == JConsoleContext.CONNECTION_STATE_PROPERTY) { + if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) { boolean connected = (Boolean) evt.getNewValue(); if (connected) { - workerAdd(new Runnable() { - public void run() { - synchroniseMBeanServerView(); - } - }); + buildMBeanServerView(); } else { sheet.dispose(); } } - } - /* tree selection listener */ + /* tree selection listener: valueChanged */ public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); sheet.displayNode(node); } - - /* tree mouse listener */ + /* tree mouse listener: mousePressed */ private MouseListener ml = new MouseAdapter() { + @Override public void mousePressed(MouseEvent e) { if (e.getClickCount() == 1) { int selRow = tree.getRowForLocation(e.getX(), e.getY()); if (selRow != -1) { TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); - DefaultMutableTreeNode node = (DefaultMutableTreeNode) - selPath.getLastPathComponent(); + DefaultMutableTreeNode node = + (DefaultMutableTreeNode) selPath.getLastPathComponent(); if (sheet.isMBeanNode(node)) { tree.expandPath(selPath); } @@ -233,4 +255,22 @@ public class MBeansTab extends Tab implements } } }; + + /* tree will expand listener: treeWillExpand */ + public void treeWillExpand(TreeExpansionEvent e) + throws ExpandVetoException { + TreePath path = e.getPath(); + if (!tree.hasBeenExpanded(path)) { + DefaultMutableTreeNode node = + (DefaultMutableTreeNode) path.getLastPathComponent(); + if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) { + tree.addMetadataNodes(node); + } + } + } + + /* tree will expand listener: treeWillCollapse */ + public void treeWillCollapse(TreeExpansionEvent e) + throws ExpandVetoException { + } } diff --git a/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java b/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java index f1d75147b62..c8c27e91ac4 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java +++ b/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole; import java.lang.management.MemoryUsage; diff --git a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java index e57c91a5e35..8215a7a8ed5 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java +++ b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java @@ -45,6 +45,7 @@ import static sun.tools.jconsole.ProxyClient.*; @SuppressWarnings("serial") public class VMPanel extends JTabbedPane implements PropertyChangeListener { + private ProxyClient proxyClient; private Timer timer; private int updateInterval; @@ -55,12 +56,9 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { private String password; private String url; private VMInternalFrame vmIF = null; - private static final String windowsLaF = - "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; - + "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; private static ArrayList tabInfos = new ArrayList(); - private boolean wasConnected = false; // The everConnected flag keeps track of whether the window can be @@ -76,7 +74,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // Each VMPanel has its own instance of the JConsolePlugin // A map of JConsolePlugin to the previous SwingWorker - private Map> plugins = null; + private Map> plugins = null; private boolean pluginTabsAdded = false; // Update these only on the EDT @@ -86,11 +84,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { static { tabInfos.add(new TabInfo(OverviewTab.class, OverviewTab.getTabName(), true)); - tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true)); - tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true)); - tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true)); + tabInfos.add(new TabInfo(MemoryTab.class, MemoryTab.getTabName(), true)); + tabInfos.add(new TabInfo(ThreadTab.class, ThreadTab.getTabName(), true)); + tabInfos.add(new TabInfo(ClassTab.class, ClassTab.getTabName(), true)); tabInfos.add(new TabInfo(SummaryTab.class, SummaryTab.getTabName(), true)); - tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true)); + tabInfos.add(new TabInfo(MBeansTab.class, MBeansTab.getTabName(), true)); } public static TabInfo[] getTabInfos() { @@ -101,8 +99,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { this.proxyClient = proxyClient; this.updateInterval = updateInterval; this.hostName = proxyClient.getHostName(); - this.port = proxyClient.getPort(); - this.vmid = proxyClient.getVmid(); + this.port = proxyClient.getPort(); + this.vmid = proxyClient.getVmid(); this.userName = proxyClient.getUserName(); this.password = proxyClient.getPassword(); this.url = proxyClient.getUrl(); @@ -113,7 +111,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } } - plugins = new LinkedHashMap>(); + plugins = new LinkedHashMap>(); for (JConsolePlugin p : JConsole.getPlugins()) { p.setContext(proxyClient); plugins.put(p, null); @@ -128,10 +126,9 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { proxyClient.addPropertyChangeListener(this); addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { - if (connectedIconBounds != null - && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 - && connectedIconBounds.contains(e.getPoint())) { + if (connectedIconBounds != null && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && connectedIconBounds.contains(e.getPoint())) { if (isConnected()) { disconnect(); @@ -145,23 +142,21 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { }); } - private static Icon connectedIcon16 = - new ImageIcon(VMPanel.class.getResource("resources/connected16.png")); + new ImageIcon(VMPanel.class.getResource("resources/connected16.png")); private static Icon connectedIcon24 = - new ImageIcon(VMPanel.class.getResource("resources/connected24.png")); + new ImageIcon(VMPanel.class.getResource("resources/connected24.png")); private static Icon disconnectedIcon16 = - new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png")); + new ImageIcon(VMPanel.class.getResource("resources/disconnected16.png")); private static Icon disconnectedIcon24 = - new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png")); - + new ImageIcon(VMPanel.class.getResource("resources/disconnected24.png")); private Rectangle connectedIconBounds; // Override to increase right inset for tab area, // in order to reserve space for the connect toggle. public void setUI(TabbedPaneUI ui) { - Insets insets = (Insets)UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets"); - insets = (Insets)insets.clone(); + Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets"); + insets = (Insets) insets.clone(); insets.right += connectedIcon24.getIconWidth() + 8; UIManager.put("TabbedPane.tabAreaInsets", insets); super.setUI(ui); @@ -225,7 +220,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { private Tab instantiate(TabInfo tabInfo) { try { Constructor con = tabInfo.tabClass.getConstructor(VMPanel.class); - return (Tab)con.newInstance(this); + return (Tab) con.newInstance(this); } catch (Exception ex) { System.err.println(ex); return null; @@ -247,10 +242,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { * IT IS USED TO MAKE SOME LOCAL MANIPULATIONS. */ ProxyClient getProxyClient(boolean assertThread) { - if(assertThread) + if (assertThread) { return getProxyClient(); - else + } else { return proxyClient; + } } public ProxyClient getProxyClient() { @@ -294,6 +290,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { startUpdateTimer(); } else { new Thread("VMPanel.connect") { + public void run() { proxyClient.connect(); } @@ -301,68 +298,63 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } } - // Call on EDT public void disconnect() { proxyClient.disconnect(); updateFrameTitle(); } - - // Called on EDT public void propertyChange(PropertyChangeEvent ev) { String prop = ev.getPropertyName(); if (prop == CONNECTION_STATE_PROPERTY) { - ConnectionState oldState = (ConnectionState)ev.getOldValue(); - ConnectionState newState = (ConnectionState)ev.getNewValue(); + ConnectionState oldState = (ConnectionState) ev.getOldValue(); + ConnectionState newState = (ConnectionState) ev.getNewValue(); switch (newState) { - case CONNECTING: - onConnecting(); - break; + case CONNECTING: + onConnecting(); + break; - case CONNECTED: - if (progressBar != null) { - progressBar.setIndeterminate(false); - progressBar.setValue(100); - } - closeOptionPane(); - updateFrameTitle(); - // create tabs if not done - createPluginTabs(); - repaint(); - // Notify tabs - fireConnectedChange(true); - // Enable/disable tabs on initial update - initialUpdate = true; - // Start/Restart update timer on connect/reconnect - startUpdateTimer(); - break; - - case DISCONNECTED: - if (progressBar != null) { - progressBar.setIndeterminate(false); - progressBar.setValue(0); + case CONNECTED: + if (progressBar != null) { + progressBar.setIndeterminate(false); + progressBar.setValue(100); + } closeOptionPane(); - } - vmPanelDied(); - if (oldState == ConnectionState.CONNECTED) { + updateFrameTitle(); + // create tabs if not done + createPluginTabs(); + repaint(); // Notify tabs - fireConnectedChange(false); - } - break; + fireConnectedChange(true); + // Enable/disable tabs on initial update + initialUpdate = true; + // Start/Restart update timer on connect/reconnect + startUpdateTimer(); + break; + + case DISCONNECTED: + if (progressBar != null) { + progressBar.setIndeterminate(false); + progressBar.setValue(0); + closeOptionPane(); + } + vmPanelDied(); + if (oldState == ConnectionState.CONNECTED) { + // Notify tabs + fireConnectedChange(false); + } + break; } } } - - // Called on EDT private void onConnecting() { time0 = System.currentTimeMillis(); - final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this); + final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this); String connectionName = getConnectionName(); progressBar = new JProgressBar(); @@ -373,17 +365,16 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { Object[] message = { "

    " + getText("connectingTo1", connectionName) + "

    ", progressPanel, - "" + getText("connectingTo2", connectionName) + "" + "" + getText("connectingTo2", connectionName) + "" }; - optionPane = - SheetDialog.showOptionDialog(this, - message, - JOptionPane.DEFAULT_OPTION, - JOptionPane.INFORMATION_MESSAGE, null, - new String[] { getText("Cancel") }, - 0); + SheetDialog.showOptionDialog(this, + message, + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, null, + new String[]{getText("Cancel")}, + 0); } @@ -398,10 +389,11 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { try { sleep(2000 - elapsed); } catch (InterruptedException ex) { - // Ignore + // Ignore } } SwingUtilities.invokeLater(new Runnable() { + public void run() { optionPane.setVisible(false); progressBar = null; @@ -425,8 +417,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { private VMInternalFrame getFrame() { if (vmIF == null) { - vmIF = (VMInternalFrame)SwingUtilities.getAncestorOfClass(VMInternalFrame.class, - this); + vmIF = (VMInternalFrame) SwingUtilities.getAncestorOfClass(VMInternalFrame.class, + this); } return vmIF; } @@ -452,27 +444,27 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { timer.cancel(); } TimerTask timerTask = new TimerTask() { + public void run() { update(); } }; - String timerName = "Timer-"+getConnectionName(); + String timerName = "Timer-" + getConnectionName(); timer = new Timer(timerName, true); timer.schedule(timerTask, 0, updateInterval); } - // Call on EDT private void vmPanelDied() { disconnect(); - final JConsole jc = (JConsole)SwingUtilities.getWindowAncestor(this); + final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this); JOptionPane optionPane; - final String connectStr = getText("Connect"); + final String connectStr = getText("Connect"); final String reconnectStr = getText("Reconnect"); - final String cancelStr = getText("Cancel"); + final String cancelStr = getText("Cancel"); String msgTitle, msgExplanation, buttonStr; @@ -488,15 +480,16 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } optionPane = - SheetDialog.showOptionDialog(this, - "

    " + msgTitle + "

    " + - "" + msgExplanation + "", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE, null, - new String[] { buttonStr, cancelStr }, - 0); + SheetDialog.showOptionDialog(this, + "

    " + msgTitle + "

    " + + "" + msgExplanation + "", + JOptionPane.DEFAULT_OPTION, + JOptionPane.WARNING_MESSAGE, null, + new String[]{buttonStr, cancelStr}, + 0); optionPane.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) { Object value = event.getNewValue(); @@ -507,7 +500,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { try { getFrame().setClosed(true); } catch (PropertyVetoException ex) { - // Should not happen, but can be ignored. + // Should not happen, but can be ignored. } } } @@ -518,11 +511,13 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // Note: This method is called on a TimerTask thread. Any GUI manipulation // must be performed with invokeLater() or invokeAndWait(). private Object lockObject = new Object(); + private void update() { - synchronized(lockObject) { + synchronized (lockObject) { if (!isConnected()) { if (wasConnected) { EventQueue.invokeLater(new Runnable() { + public void run() { vmPanelDied(); } @@ -548,6 +543,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // if (initialUpdate) { EventQueue.invokeLater(new Runnable() { + public void run() { setEnabledAt(index, true); } @@ -569,8 +565,8 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { // plugin GUI update for (JConsolePlugin p : plugins.keySet()) { - SwingWorker sw = p.newSwingWorker(); - SwingWorker prevSW = plugins.get(p); + SwingWorker sw = p.newSwingWorker(); + SwingWorker prevSW = plugins.get(p); // schedule SwingWorker to run only if the previous // SwingWorker has finished its task and it hasn't started. if (prevSW == null || prevSW.isDone()) { @@ -583,7 +579,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } } - // Set the first enabled tab in the tab´s list + // Set the first enabled tab in the tab's list // as the selected tab on initial update // if (initialUpdate) { @@ -622,7 +618,6 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { return url; } - public String getPassword() { return password; } @@ -636,6 +631,7 @@ public class VMPanel extends JTabbedPane implements PropertyChangeListener { } static class TabInfo { + Class tabClass; String name; boolean tabVisible; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java index 0eb3876838a..c6a805ab391 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java @@ -22,8 +22,8 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ -package sun.tools.jconsole.inspector; +package sun.tools.jconsole.inspector; // java import import java.awt.*; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java index 886b11c57f0..14ac7bc2ebb 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.util.*; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java index ea07d1393c1..a548fadd60f 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; // java import diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java index 7ae531eff3a..eee13d67094 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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 @@ -29,55 +29,51 @@ import java.awt.event.*; import java.lang.reflect.*; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.*; +import java.util.concurrent.ExecutionException; import javax.management.*; import javax.management.openmbean.*; import javax.swing.*; import javax.swing.text.*; -import java.util.*; public class Utils { private Utils() { } - private static Set tableNavigationKeys = - new HashSet(Arrays.asList(new Integer[] { + new HashSet(Arrays.asList(new Integer[]{ KeyEvent.VK_TAB, KeyEvent.VK_ENTER, KeyEvent.VK_HOME, KeyEvent.VK_END, KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, KeyEvent.VK_UP, KeyEvent.VK_DOWN, - KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN})); - + KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN + })); private static final Set> primitiveWrappers = - new HashSet>(Arrays.asList(new Class[] { + new HashSet>(Arrays.asList(new Class[]{ Byte.class, Short.class, Integer.class, Long.class, - Float.class, Double.class, Character.class, Boolean.class})); - + Float.class, Double.class, Character.class, Boolean.class + })); private static final Set> primitives = new HashSet>(); - private static final Map> primitiveMap = new HashMap>(); - private static final Map> primitiveToWrapper = new HashMap>(); - private static final Set editableTypes = new HashSet(); - private static final Set> extraEditableClasses = - new HashSet>(Arrays.asList(new Class[] { + new HashSet>(Arrays.asList(new Class[]{ BigDecimal.class, BigInteger.class, Number.class, - String.class, ObjectName.class})); - + String.class, ObjectName.class + })); private static final Set numericalTypes = new HashSet(); - private static final Set extraNumericalTypes = - new HashSet(Arrays.asList(new String[] { + new HashSet(Arrays.asList(new String[]{ BigDecimal.class.getName(), BigInteger.class.getName(), - Number.class.getName()})); - + Number.class.getName() + })); private static final Set booleanTypes = - new HashSet(Arrays.asList(new String[] { - Boolean.TYPE.getName(), Boolean.class.getName()})); + new HashSet(Arrays.asList(new String[]{ + Boolean.TYPE.getName(), Boolean.class.getName() + })); static { // compute primitives/primitiveMap/primitiveToWrapper @@ -122,10 +118,11 @@ public class Utils { * It's used to cater for the primitive types. */ public static Class getClass(String className) - throws ClassNotFoundException { + throws ClassNotFoundException { Class c; - if ((c = primitiveMap.get(className)) != null) + if ((c = primitiveMap.get(className)) != null) { return c; + } return Class.forName(className); } @@ -155,7 +152,9 @@ public class Utils { * structure, i.e. a data structure jconsole can render as an array. */ public static boolean canBeRenderedAsArray(Object elem) { - if (isSupportedArray(elem)) return true; + if (isSupportedArray(elem)) { + return true; + } if (elem instanceof Collection) { Collection c = (Collection) elem; if (c.isEmpty()) { @@ -168,7 +167,7 @@ public class Utils { // - Collections of other Java types are handled as arrays // return !isUniformCollection(c, CompositeData.class) && - !isUniformCollection(c, TabularData.class); + !isUniformCollection(c, TabularData.class); } } if (elem instanceof Map) { @@ -239,7 +238,9 @@ public class Utils { */ public static String getReadableClassName(String name) { String className = getArrayClassName(name); - if (className == null) return name; + if (className == null) { + return name; + } int index = name.lastIndexOf("["); StringBuilder brackets = new StringBuilder(className); for (int i = 0; i <= index; i++) { @@ -282,7 +283,7 @@ public class Utils { * Try to create a Java object using a one-string-param constructor. */ public static Object newStringConstructor(String type, String param) - throws Exception { + throws Exception { Constructor c = Utils.getClass(type).getConstructor(String.class); try { return c.newInstance(param); @@ -300,7 +301,7 @@ public class Utils { * Try to convert a string value into a numerical value. */ private static Number createNumberFromStringValue(String value) - throws NumberFormatException { + throws NumberFormatException { final String suffix = value.substring(value.length() - 1); if ("L".equalsIgnoreCase(suffix)) { return Long.valueOf(value.substring(0, value.length() - 1)); @@ -314,17 +315,17 @@ public class Utils { try { return Integer.valueOf(value); } catch (NumberFormatException e) { - // OK: Ignore exception... + // OK: Ignore exception... } try { return Long.valueOf(value); } catch (NumberFormatException e1) { - // OK: Ignore exception... + // OK: Ignore exception... } try { return Double.valueOf(value); } catch (NumberFormatException e2) { - // OK: Ignore exception... + // OK: Ignore exception... } throw new NumberFormatException("Cannot convert string value '" + value + "' into a numerical value"); @@ -337,7 +338,7 @@ public class Utils { * will return an Integer object initialized to 10. */ public static Object createObjectFromString(String type, String value) - throws Exception { + throws Exception { Object result; if (primitiveToWrapper.containsKey(type)) { if (type.equals(Character.TYPE.getName())) { @@ -367,7 +368,7 @@ public class Utils { * into a useful object array for passing into a parameter array. */ public static Object[] getParameters(XTextField[] inputs, String[] params) - throws Exception { + throws Exception { Object result[] = new Object[inputs.length]; Object userInput; for (int i = 0; i < inputs.length; i++) { @@ -388,12 +389,17 @@ public class Utils { * If the exception is wrapped, unwrap it. */ public static Throwable getActualException(Throwable e) { + if (e instanceof ExecutionException) { + e = e.getCause(); + } if (e instanceof MBeanException || e instanceof RuntimeMBeanException || e instanceof RuntimeOperationsException || e instanceof ReflectionException) { Throwable t = e.getCause(); - if (t != null) return t; + if (t != null) { + return t; + } } return e; } @@ -401,6 +407,7 @@ public class Utils { @SuppressWarnings("serial") public static class ReadOnlyTableCellEditor extends DefaultCellEditor { + public ReadOnlyTableCellEditor(JTextField tf) { super(tf); tf.addFocusListener(new Utils.EditFocusAdapter(this)); @@ -409,20 +416,25 @@ public class Utils { } public static class EditFocusAdapter extends FocusAdapter { + private CellEditor editor; + public EditFocusAdapter(CellEditor editor) { this.editor = editor; } + + @Override public void focusLost(FocusEvent e) { editor.stopCellEditing(); } - }; + } public static class CopyKeyAdapter extends KeyAdapter { private static final String defaultEditorKitCopyActionName = DefaultEditorKit.copyAction; private static final String transferHandlerCopyActionName = (String) TransferHandler.getCopyAction().getValue(Action.NAME); + @Override public void keyPressed(KeyEvent e) { // Accept "copy" key strokes KeyStroke ks = KeyStroke.getKeyStroke( @@ -441,6 +453,8 @@ public class Utils { e.consume(); } } + + @Override public void keyTyped(KeyEvent e) { e.consume(); } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java index 21b3f44189e..8a339f2ac49 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import javax.swing.JTable; @@ -108,6 +109,7 @@ public class XDataViewer { public Component createOperationViewer(Object value, XMBean mbean) { if(value instanceof Number) return null; + if(value instanceof Component) return (Component) value; return createAttributeViewer(value, mbean, null, null); } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBean.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBean.java index eed56044e09..9999d7dbda1 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBean.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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,47 +28,56 @@ package sun.tools.jconsole.inspector; import java.io.IOException; import javax.management.*; import javax.swing.Icon; +import sun.tools.jconsole.JConsole; import sun.tools.jconsole.MBeansTab; -public class XMBean extends Object { - private ObjectName objectName; +public class XMBean { + + private final MBeansTab mbeansTab; + private final ObjectName objectName; private Icon icon; private String text; - private boolean broadcaster; + private Boolean broadcaster; + private final Object broadcasterLock = new Object(); private MBeanInfo mbeanInfo; - private MBeansTab mbeansTab; + private final Object mbeanInfoLock = new Object(); - public XMBean(ObjectName objectName, MBeansTab mbeansTab) - throws InstanceNotFoundException, IntrospectionException, - ReflectionException, IOException { + public XMBean(ObjectName objectName, MBeansTab mbeansTab) { this.mbeansTab = mbeansTab; - setObjectName(objectName); + this.objectName = objectName; + text = objectName.getKeyProperty("name"); + if (text == null) { + text = objectName.getDomain(); + } if (MBeanServerDelegate.DELEGATE_NAME.equals(objectName)) { icon = IconManager.MBEANSERVERDELEGATE; } else { icon = IconManager.MBEAN; } - this.broadcaster = isBroadcaster(objectName); - this.mbeanInfo = getMBeanInfo(objectName); } MBeanServerConnection getMBeanServerConnection() { return mbeansTab.getMBeanServerConnection(); } - public boolean isBroadcaster() { - return broadcaster; - } - - private boolean isBroadcaster(ObjectName name) { - try { - return getMBeanServerConnection().isInstanceOf( - name, "javax.management.NotificationBroadcaster"); - } catch (Exception e) { - System.out.println("Error calling isBroadcaster: " + - e.getMessage()); + public Boolean isBroadcaster() { + synchronized (broadcasterLock) { + if (broadcaster == null) { + try { + broadcaster = getMBeanServerConnection().isInstanceOf( + getObjectName(), + "javax.management.NotificationBroadcaster"); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Couldn't check if MBean [" + + objectName + "] is a notification broadcaster"); + e.printStackTrace(); + } + return false; + } + } + return broadcaster; } - return false; } public Object invoke(String operationName) throws Exception { @@ -78,35 +87,35 @@ public class XMBean extends Object { } public Object invoke(String operationName, Object params[], String sig[]) - throws Exception { + throws Exception { Object result = getMBeanServerConnection().invoke( getObjectName(), operationName, params, sig); return result; } public void setAttribute(Attribute attribute) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException, IOException { getMBeanServerConnection().setAttribute(getObjectName(), attribute); } public Object getAttribute(String attributeName) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { return getMBeanServerConnection().getAttribute( getObjectName(), attributeName); } public AttributeList getAttributes(String attributeNames[]) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { return getMBeanServerConnection().getAttributes( getObjectName(), attributeNames); } public AttributeList getAttributes(MBeanAttributeInfo attributeNames[]) - throws AttributeNotFoundException, InstanceNotFoundException, + throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { String attributeString[] = new String[attributeNames.length]; for (int i = 0; i < attributeNames.length; i++) { @@ -119,32 +128,34 @@ public class XMBean extends Object { return objectName; } - private void setObjectName(ObjectName objectName) { - this.objectName = objectName; - // generate a readable name now - String name = getObjectName().getKeyProperty("name"); - if (name == null) - setText(getObjectName().getDomain()); - else - setText(name); - } - - public MBeanInfo getMBeanInfo() { - return mbeanInfo; - } - - private MBeanInfo getMBeanInfo(ObjectName name) - throws InstanceNotFoundException, IntrospectionException, - ReflectionException, IOException { - return getMBeanServerConnection().getMBeanInfo(name); - } - - public boolean equals(Object o) { - if (o instanceof XMBean) { - XMBean mbean = (XMBean) o; - return getObjectName().equals((mbean).getObjectName()); + public MBeanInfo getMBeanInfo() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + synchronized (mbeanInfoLock) { + if (mbeanInfo == null) { + mbeanInfo = getMBeanServerConnection().getMBeanInfo(objectName); + } + return mbeanInfo; } - return false; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (!(obj instanceof XMBean)) { + return false; + } + XMBean that = (XMBean) obj; + return getObjectName().equals(that.getObjectName()); + } + + @Override + public int hashCode() { + return (objectName == null ? 0 : objectName.hashCode()); } public String getText() { @@ -163,6 +174,7 @@ public class XMBean extends Object { this.icon = icon; } + @Override public String toString() { return getText(); } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java index 5a87772f87c..bb195cd990e 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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,10 +35,7 @@ import javax.swing.*; import javax.swing.border.TitledBorder; import javax.swing.event.*; import javax.swing.table.*; -import javax.swing.tree.*; -import sun.tools.jconsole.JConsole; import sun.tools.jconsole.Resources; -import sun.tools.jconsole.inspector.XNodeInfo.Type; import static sun.tools.jconsole.Utilities.*; @@ -46,21 +43,20 @@ import static sun.tools.jconsole.Utilities.*; public class XMBeanInfo extends JPanel { private static final Color lightYellow = new Color(255, 255, 128); - private final int NAME_COLUMN = 0; private final int VALUE_COLUMN = 1; - private final String[] columnNames = { Resources.getText("Name"), Resources.getText("Value") }; - private JTable infoTable = new JTable(); private JTable descTable = new JTable(); private JPanel infoBorderPanel = new JPanel(new BorderLayout()); private JPanel descBorderPanel = new JPanel(new BorderLayout()); private static class ReadOnlyDefaultTableModel extends DefaultTableModel { + + @Override public void setValueAt(Object value, int row, int col) { } } @@ -73,17 +69,18 @@ public class XMBeanInfo extends JPanel { this.tableRowDividerText = tableRowDividerText; } + @Override public String toString() { return tableRowDividerText; } } - private static MBeanInfoTableCellRenderer renderer = new MBeanInfoTableCellRenderer(); private static class MBeanInfoTableCellRenderer extends DefaultTableCellRenderer { + @Override public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { @@ -92,22 +89,24 @@ public class XMBeanInfo extends JPanel { if (value instanceof TableRowDivider) { JLabel label = new JLabel(value.toString()); label.setBackground(ensureContrast(lightYellow, - label.getForeground())); + label.getForeground())); label.setOpaque(true); return label; } return comp; } } - private static TableCellEditor editor = new MBeanInfoTableCellEditor(new JTextField()); private static class MBeanInfoTableCellEditor extends Utils.ReadOnlyTableCellEditor { + public MBeanInfoTableCellEditor(JTextField tf) { super(tf); } + + @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column) { @@ -116,7 +115,7 @@ public class XMBeanInfo extends JPanel { if (value instanceof TableRowDivider) { JLabel label = new JLabel(value.toString()); label.setBackground(ensureContrast(lightYellow, - label.getForeground())); + label.getForeground())); label.setOpaque(true); return label; } @@ -172,6 +171,7 @@ public class XMBeanInfo extends JPanel { add(descBorderPanel); } + // Call on EDT public void emptyInfoTable() { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); while (tableModel.getRowCount() > 0) { @@ -179,6 +179,7 @@ public class XMBeanInfo extends JPanel { } } + // Call on EDT public void emptyDescTable() { DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel(); while (tableModel.getRowCount() > 0) { @@ -186,6 +187,7 @@ public class XMBeanInfo extends JPanel { } } + // Call on EDT private void addDescriptor(Descriptor desc, String text) { if (desc != null && desc.getFieldNames().length > 0) { DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel(); @@ -223,6 +225,7 @@ public class XMBeanInfo extends JPanel { } } + // Call on EDT public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) { emptyInfoTable(); emptyDescTable(); @@ -263,6 +266,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) { emptyInfoTable(); emptyDescTable(); @@ -296,6 +300,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT public void addMBeanOperationInfo(MBeanOperationInfo mboi) { emptyInfoTable(); emptyDescTable(); @@ -343,6 +348,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) { emptyInfoTable(); emptyDescTable(); @@ -367,6 +373,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; @@ -383,6 +390,7 @@ public class XMBeanInfo extends JPanel { tableModel.newDataAvailable(new TableModelEvent(tableModel)); } + // Call on EDT private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) { DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel(); Object rowData[] = new Object[2]; @@ -401,91 +409,4 @@ public class XMBeanInfo extends JPanel { addDescriptor(mbpi.getDescriptor(), text); tableModel.newDataAvailable(new TableModelEvent(tableModel)); } - - public static void loadInfo(DefaultMutableTreeNode root) { - // Retrieve XMBean from XNodeInfo - // - XMBean mbean = (XMBean) ((XNodeInfo) root.getUserObject()).getData(); - // Initialize MBean*Info - // - final MBeanInfo mbeanInfo; - try { - mbeanInfo = mbean.getMBeanInfo(); - } catch (Exception e) { - if (JConsole.isDebug()) { - e.printStackTrace(); - } - return; - } - MBeanAttributeInfo[] ai = mbeanInfo.getAttributes(); - MBeanOperationInfo[] oi = mbeanInfo.getOperations(); - MBeanNotificationInfo[] ni = mbeanInfo.getNotifications(); - // MBeanAttributeInfo node - // - if (ai != null && ai.length > 0) { - DefaultMutableTreeNode attributes = new DefaultMutableTreeNode(); - XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean, - Resources.getText("Attributes"), null); - attributes.setUserObject(attributesUO); - root.add(attributes); - for (MBeanAttributeInfo mbai : ai) { - DefaultMutableTreeNode attribute = new DefaultMutableTreeNode(); - XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE, - new Object[] {mbean, mbai}, mbai.getName(), null); - attribute.setUserObject(attributeUO); - attributes.add(attribute); - } - } - // MBeanOperationInfo node - // - if (oi != null && oi.length > 0) { - DefaultMutableTreeNode operations = new DefaultMutableTreeNode(); - XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean, - Resources.getText("Operations"), null); - operations.setUserObject(operationsUO); - root.add(operations); - for (MBeanOperationInfo mboi : oi) { - // Compute the operation's tool tip text: - // "operationname(param1type,param2type,...)" - // - StringBuilder sb = new StringBuilder(); - for (MBeanParameterInfo mbpi : mboi.getSignature()) { - sb.append(mbpi.getType() + ","); - } - String signature = sb.toString(); - if (signature.length() > 0) { - // Remove the trailing ',' - // - signature = signature.substring(0, signature.length() - 1); - } - String toolTipText = mboi.getName() + "(" + signature + ")"; - // Create operation node - // - DefaultMutableTreeNode operation = new DefaultMutableTreeNode(); - XNodeInfo operationUO = new XNodeInfo(Type.OPERATION, - new Object[] {mbean, mboi}, mboi.getName(), toolTipText); - operation.setUserObject(operationUO); - operations.add(operation); - } - } - // MBeanNotificationInfo node - // - if (mbean.isBroadcaster()) { - DefaultMutableTreeNode notifications = new DefaultMutableTreeNode(); - XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean, - Resources.getText("Notifications"), null); - notifications.setUserObject(notificationsUO); - root.add(notifications); - if (ni != null && ni.length > 0) { - for (MBeanNotificationInfo mbni : ni) { - DefaultMutableTreeNode notification = - new DefaultMutableTreeNode(); - XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION, - mbni, mbni.getName(), null); - notification.setUserObject(notificationUO); - notifications.add(notification); - } - } - } - } } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java index c3e059a4bac..20c31b001d6 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java @@ -29,17 +29,13 @@ import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import javax.swing.tree.*; -import java.awt.BorderLayout; -import java.awt.GridLayout; import java.awt.Font; import java.text.SimpleDateFormat; -import java.awt.FlowLayout; import java.awt.Component; import java.awt.EventQueue; import java.awt.event.*; -import java.awt.Insets; import java.awt.Dimension; import java.util.*; import java.io.*; @@ -49,45 +45,44 @@ import javax.management.*; import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularData; +import sun.tools.jconsole.JConsole; import sun.tools.jconsole.Resources; @SuppressWarnings("serial") public class XMBeanNotifications extends JTable implements NotificationListener { - private final static String[] columnNames = { + private final static String[] columnNames = { Resources.getText("TimeStamp"), Resources.getText("Type"), Resources.getText("UserData"), Resources.getText("SeqNum"), Resources.getText("Message"), Resources.getText("Event"), - Resources.getText("Source")}; - + Resources.getText("Source") + }; private HashMap listeners = - new HashMap(); - private boolean subscribed; + new HashMap(); + private volatile boolean subscribed; private XMBeanNotificationsListener currentListener; public final static String NOTIFICATION_RECEIVED_EVENT = - "jconsole.xnotification.received"; - + "jconsole.xnotification.received"; private List notificationListenersList; - private boolean enabled; - private Font normalFont, boldFont; + private volatile boolean enabled; + private Font normalFont, boldFont; private int rowMinHeight = -1; private TableCellEditor userDataEditor = new UserDataCellEditor(); private NotifMouseListener mouseListener = new NotifMouseListener(); private SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss:SSS"); - private static TableCellEditor editor = new Utils.ReadOnlyTableCellEditor(new JTextField()); public XMBeanNotifications() { - super(new TableSorter(columnNames,0)); + super(new TableSorter(columnNames, 0)); setColumnSelectionAllowed(false); setRowSelectionAllowed(false); getTableHeader().setReorderingAllowed(false); ArrayList l = - new ArrayList(1); + new ArrayList(1); notificationListenersList = Collections.synchronizedList(l); addMouseListener(mouseListener); @@ -103,20 +98,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener addKeyListener(new Utils.CopyKeyAdapter()); } + // Call on EDT public void cancelCellEditing() { - TableCellEditor editor = getCellEditor(); - if (editor != null) { - editor.cancelCellEditing(); + TableCellEditor tce = getCellEditor(); + if (tce != null) { + tce.cancelCellEditing(); } } + // Call on EDT public void stopCellEditing() { - TableCellEditor editor = getCellEditor(); - if (editor != null) { - editor.stopCellEditing(); + TableCellEditor tce = getCellEditor(); + if (tce != null) { + tce.stopCellEditing(); } } + // Call on EDT + @Override public boolean isCellEditable(int row, int col) { UserDataCell cell = getUserDataCell(row, col); if (cell != null) { @@ -125,16 +124,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener return true; } + // Call on EDT + @Override public void setValueAt(Object value, int row, int column) { } - public synchronized Component prepareRenderer(TableCellRenderer renderer, - int row, int column) { + // Call on EDT + @Override + public synchronized Component prepareRenderer( + TableCellRenderer renderer, int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate - if(row >= getRowCount()) + if (row >= getRowCount()) { return null; + } Component comp = super.prepareRenderer(renderer, row, column); @@ -146,9 +150,10 @@ public class XMBeanNotifications extends JTable implements NotificationListener if (column == 2 && cell != null) { comp.setFont(boldFont); int size = cell.getHeight(); - if(size > 0) { - if(getRowHeight(row) != size) + if (size > 0) { + if (getRowHeight(row) != size) { setRowHeight(row, size); + } } } else { comp.setFont(normalFont); @@ -157,34 +162,35 @@ public class XMBeanNotifications extends JTable implements NotificationListener return comp; } - public synchronized TableCellRenderer getCellRenderer(int row, - int column) { + // Call on EDT + @Override + public synchronized TableCellRenderer getCellRenderer(int row, int column) { //In case we have a repaint thread that is in the process of //repainting an obsolete table, just ignore the call. //It can happen when MBean selection is switched at a very quick rate - if(row >= getRowCount()) + if (row >= getRowCount()) { return null; + } DefaultTableCellRenderer renderer; String toolTip = null; UserDataCell cell = getUserDataCell(row, column); - if(cell != null && cell.isInited()) { + if (cell != null && cell.isInited()) { renderer = (DefaultTableCellRenderer) cell.getRenderer(); - } - else { - renderer = (DefaultTableCellRenderer) - super.getCellRenderer(row, - column); + } else { + renderer = + (DefaultTableCellRenderer) super.getCellRenderer(row, column); } - if(cell != null) - toolTip = Resources.getText("Double click to expand/collapse")+". " - + cell.toString(); - else { + if (cell != null) { + toolTip = Resources.getText("Double click to expand/collapse") + + ". " + cell.toString(); + } else { Object val = - ((DefaultTableModel) getModel()).getValueAt(row,column); - if(val != null) + ((DefaultTableModel) getModel()).getValueAt(row, column); + if (val != null) { toolTip = val.toString(); + } } renderer.setToolTipText(toolTip); @@ -192,9 +198,12 @@ public class XMBeanNotifications extends JTable implements NotificationListener return renderer; } + // Call on EDT private UserDataCell getUserDataCell(int row, int column) { - Object obj = ((DefaultTableModel) getModel()).getValueAt(row,column); - if(obj instanceof UserDataCell) return (UserDataCell) obj; + Object obj = ((DefaultTableModel) getModel()).getValueAt(row, column); + if (obj instanceof UserDataCell) { + return (UserDataCell) obj; + } return null; } @@ -204,19 +213,22 @@ public class XMBeanNotifications extends JTable implements NotificationListener public long getReceivedNotifications(XMBean mbean) { XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); - if(listener == null) return 0; - else + listeners.get(mbean.getObjectName()); + if (listener == null) { + return 0; + } else { return listener.getReceivedNotifications(); + } } public synchronized boolean clearCurrentNotifications() { emptyTable(); - if(currentListener != null) { + if (currentListener != null) { currentListener.clear(); return true; - } else + } else { return false; + } } public synchronized boolean unregisterListener(DefaultMutableTreeNode node) { @@ -225,29 +237,25 @@ public class XMBeanNotifications extends JTable implements NotificationListener } public synchronized void registerListener(DefaultMutableTreeNode node) - throws InstanceNotFoundException, IOException { + throws InstanceNotFoundException, IOException { XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData(); - if(!subscribed) { + if (!subscribed) { try { - mbean.getMBeanServerConnection(). - addNotificationListener(new ObjectName("JMImplementation:type=MBeanServerDelegate"), - this, - null, - null); + mbean.getMBeanServerConnection().addNotificationListener( + MBeanServerDelegate.DELEGATE_NAME, this, null, null); subscribed = true; - }catch(Exception e) { - System.out.println("Error adding listener for delegate :"+ - e.getMessage()); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error adding listener for delegate:"); + e.printStackTrace(); + } } } - XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); + listeners.get(mbean.getObjectName()); if (listener == null) { - listener = new XMBeanNotificationsListener(this, - mbean, - node, - columnNames); + listener = new XMBeanNotificationsListener( + this, mbean, node, columnNames); listeners.put(mbean.getObjectName(), listener); } else { if (!listener.isRegistered()) { @@ -259,19 +267,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener currentListener = listener; } - public synchronized void handleNotification(Notification notif, - Object handback) { + public synchronized void handleNotification( + Notification notif, Object handback) { try { if (notif instanceof MBeanServerNotification) { ObjectName mbean = - ((MBeanServerNotification)notif).getMBeanName(); - if (notif.getType().indexOf("JMX.mbean.unregistered")>=0){ + ((MBeanServerNotification) notif).getMBeanName(); + if (notif.getType().indexOf("JMX.mbean.unregistered") >= 0) { unregister(mbean); } } - } catch(Exception e) { - System.out.println("Error unregistering notification:"+ - e.getMessage()); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error unregistering notification:"); + e.printStackTrace(); + } } } @@ -283,75 +293,77 @@ public class XMBeanNotifications extends JTable implements NotificationListener private synchronized boolean unregister(ObjectName mbean) { XMBeanNotificationsListener listener = listeners.get(mbean); - if(listener != null && listener.isRegistered()) { + if (listener != null && listener.isRegistered()) { listener.unregister(); return true; - } else + } else { return false; + } } public void addNotificationsListener(NotificationListener nl) { - notificationListenersList.add(nl); + notificationListenersList.add(nl); } public void removeNotificationsListener(NotificationListener nl) { notificationListenersList.remove(nl); } - void fireNotificationReceived(XMBeanNotificationsListener listener, - XMBean mbean, - DefaultMutableTreeNode node, - Object[] rowData, - long received) { - if(enabled) { + // Call on EDT + void fireNotificationReceived( + XMBeanNotificationsListener listener, XMBean mbean, + DefaultMutableTreeNode node, Object[] rowData, long received) { + if (enabled) { DefaultTableModel tableModel = (DefaultTableModel) getModel(); - if(listener == currentListener) { - - //tableModel.addRow(rowData); + if (listener == currentListener) { tableModel.insertRow(0, rowData); - - //tableModel.newDataAvailable(new TableModelEvent(tableModel)); repaint(); } } - - Notification notif = new Notification(NOTIFICATION_RECEIVED_EVENT, - this, - 0); - notif.setUserData(new Long(received)); - for(NotificationListener nl : notificationListenersList) - nl.handleNotification(notif,node); + Notification notif = + new Notification(NOTIFICATION_RECEIVED_EVENT, this, 0); + notif.setUserData(received); + for (NotificationListener nl : notificationListenersList) { + nl.handleNotification(notif, node); + } } + // Call on EDT private void updateModel(List data) { emptyTable(); DefaultTableModel tableModel = (DefaultTableModel) getModel(); - for(Object[] rowData : data) + for (Object[] rowData : data) { tableModel.addRow(rowData); + } } public synchronized boolean isListenerRegistered(XMBean mbean) { XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); - if(listener == null) return false; + listeners.get(mbean.getObjectName()); + if (listener == null) { + return false; + } return listener.isRegistered(); } + // Call on EDT public synchronized void loadNotifications(XMBean mbean) { XMBeanNotificationsListener listener = - listeners.get(mbean.getObjectName()); + listeners.get(mbean.getObjectName()); emptyTable(); - if(listener != null ) { + if (listener != null) { enabled = true; List data = listener.getData(); updateModel(data); currentListener = listener; validate(); repaint(); - } else + } else { enabled = false; + } } + // Call on EDT private void setColumnEditors() { TableColumnModel tcm = getColumnModel(); for (int i = 0; i < columnNames.length; i++) { @@ -364,40 +376,40 @@ public class XMBeanNotifications extends JTable implements NotificationListener } } + // Call on EDT public boolean isTableEditable() { return true; } + // Call on EDT public synchronized void emptyTable() { - DefaultTableModel model = (DefaultTableModel)getModel(); + DefaultTableModel model = (DefaultTableModel) getModel(); //invalidate(); - while (model.getRowCount()>0) + while (model.getRowCount() > 0) { model.removeRow(0); + } validate(); } - synchronized void updateUserDataCell(int row, - int col) { + // Call on EDT + synchronized void updateUserDataCell(int row, int col) { Object obj = getModel().getValueAt(row, 2); - if(obj instanceof UserDataCell) { + if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; - if(!cell.isInited()) { - if(rowMinHeight == -1) + if (!cell.isInited()) { + if (rowMinHeight == -1) { rowMinHeight = getRowHeight(row); - - cell.init(super.getCellRenderer(row, col), - rowMinHeight); + } + cell.init(super.getCellRenderer(row, col), rowMinHeight); } cell.switchState(); - setRowHeight(row, - cell.getHeight()); + setRowHeight(row, cell.getHeight()); - if(!cell.isMaximized()) { + if (!cell.isMaximized()) { cancelCellEditing(); //Back to simple editor. - editCellAt(row, - 2); + editCellAt(row, 2); } invalidate(); @@ -406,7 +418,9 @@ public class XMBeanNotifications extends JTable implements NotificationListener } class UserDataCellRenderer extends DefaultTableCellRenderer { + Component comp; + UserDataCellRenderer(Component comp) { this.comp = comp; Dimension d = comp.getPreferredSize(); @@ -415,56 +429,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener } } - public Component getTableCellRendererComponent(JTable table, - Object value, - boolean isSelected, - boolean hasFocus, - int row, - int column) { + @Override + public Component getTableCellRendererComponent( + JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { return comp; } public Component getComponent() { return comp; } - } class UserDataCell { + TableCellRenderer minRenderer; UserDataCellRenderer maxRenderer; int minHeight; boolean minimized = true; boolean init = false; Object userData; - UserDataCell(Object userData, Component max) { - this.userData = userData; - this.maxRenderer = new UserDataCellRenderer(max); - } + UserDataCell(Object userData, Component max) { + this.userData = userData; + this.maxRenderer = new UserDataCellRenderer(max); - public String toString() { - if(userData == null) return null; - if(userData.getClass().isArray()) { - String name = - Utils.getArrayClassName(userData.getClass().getName()); - int length = Array.getLength(userData); - return name + "[" + length +"]"; - } + } - if(userData instanceof CompositeData || - userData instanceof TabularData) + @Override + public String toString() { + if (userData == null) { + return null; + } + if (userData.getClass().isArray()) { + String name = + Utils.getArrayClassName(userData.getClass().getName()); + int length = Array.getLength(userData); + return name + "[" + length + "]"; + } + + if (userData instanceof CompositeData || + userData instanceof TabularData) { return userData.getClass().getName(); + } return userData.toString(); - } + } boolean isInited() { return init; } - void init(TableCellRenderer minRenderer, - int minHeight) { + void init(TableCellRenderer minRenderer, int minHeight) { this.minRenderer = minRenderer; this.minHeight = minHeight; init = true; @@ -473,9 +493,11 @@ public class XMBeanNotifications extends JTable implements NotificationListener void switchState() { minimized = !minimized; } + boolean isMaximized() { return !minimized; } + void minimize() { minimized = true; } @@ -485,30 +507,39 @@ public class XMBeanNotifications extends JTable implements NotificationListener } int getHeight() { - if(minimized) return minHeight; - else + if (minimized) { + return minHeight; + } else { return (int) maxRenderer.getComponent(). - getPreferredSize().getHeight() ; + getPreferredSize().getHeight(); + } } TableCellRenderer getRenderer() { - if(minimized) return minRenderer; - else return maxRenderer; + if (minimized) { + return minRenderer; + } else { + return maxRenderer; + } } } class NotifMouseListener extends MouseAdapter { + @Override public void mousePressed(MouseEvent e) { - if(e.getButton() == MouseEvent.BUTTON1) { - if(e.getClickCount() >= 2) { + if (e.getButton() == MouseEvent.BUTTON1) { + if (e.getClickCount() >= 2) { int row = XMBeanNotifications.this.getSelectedRow(); int col = XMBeanNotifications.this.getSelectedColumn(); - if(col != 2) return; - if(col == -1 || row == -1) return; + if (col != 2) { + return; + } + if (col == -1 || row == -1) { + return; + } - XMBeanNotifications.this.updateUserDataCell(row, - col); + XMBeanNotifications.this.updateUserDataCell(row, col); } } } @@ -516,20 +547,21 @@ public class XMBeanNotifications extends JTable implements NotificationListener class UserDataCellEditor extends XTextFieldEditor { // implements javax.swing.table.TableCellEditor - public Component getTableCellEditorComponent(JTable table, - Object value, - boolean isSelected, - int row, - int column) { + @Override + public Component getTableCellEditorComponent( + JTable table, + Object value, + boolean isSelected, + int row, + int column) { Object val = value; - if(column == 2) { - Object obj = getModel().getValueAt(row, - column); - if(obj instanceof UserDataCell) { + if (column == 2) { + Object obj = getModel().getValueAt(row, column); + if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; - if(cell.getRenderer() instanceof UserDataCellRenderer) { + if (cell.getRenderer() instanceof UserDataCellRenderer) { UserDataCellRenderer zr = - (UserDataCellRenderer) cell.getRenderer(); + (UserDataCellRenderer) cell.getRenderer(); return zr.getComponent(); } } else { @@ -539,12 +571,14 @@ public class XMBeanNotifications extends JTable implements NotificationListener return comp; } } - return super.getTableCellEditorComponent(table, - val, - isSelected, - row, - column); + return super.getTableCellEditorComponent( + table, + val, + isSelected, + row, + column); } + @Override public boolean stopCellEditing() { int editingRow = getEditingRow(); @@ -554,7 +588,7 @@ public class XMBeanNotifications extends JTable implements NotificationListener if (obj instanceof UserDataCell) { UserDataCell cell = (UserDataCell) obj; if (cell.isMaximized()) { - this.cancelCellEditing(); + cancelCellEditing(); return true; } } @@ -564,17 +598,20 @@ public class XMBeanNotifications extends JTable implements NotificationListener } class XMBeanNotificationsListener implements NotificationListener { + private String[] columnNames; private XMBean xmbean; private DefaultMutableTreeNode node; - private long received; + private volatile long received; private XMBeanNotifications notifications; - private boolean unregistered; + private volatile boolean unregistered; private ArrayList data = new ArrayList(); - public XMBeanNotificationsListener(XMBeanNotifications notifications, - XMBean xmbean, - DefaultMutableTreeNode node, - String[] columnNames) { + + public XMBeanNotificationsListener( + XMBeanNotifications notifications, + XMBean xmbean, + DefaultMutableTreeNode node, + String[] columnNames) { this.notifications = notifications; this.xmbean = xmbean; this.node = node; @@ -591,22 +628,24 @@ public class XMBeanNotifications extends JTable implements NotificationListener received = 0; } - public boolean isRegistered() { + public synchronized boolean isRegistered() { return !unregistered; } public synchronized void unregister() { try { - xmbean.getMBeanServerConnection(). - removeNotificationListener(xmbean.getObjectName(),this,null,null); - }catch(Exception e) { - System.out.println("Error removing listener :"+ - e.getMessage()); + xmbean.getMBeanServerConnection().removeNotificationListener( + xmbean.getObjectName(), this, null, null); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error removing listener:"); + e.printStackTrace(); + } } unregistered = true; } - public long getReceivedNotifications() { + public synchronized long getReceivedNotifications() { return received; } @@ -614,52 +653,62 @@ public class XMBeanNotifications extends JTable implements NotificationListener clear(); this.node = node; try { - xmbean.getMBeanServerConnection(). - addNotificationListener(xmbean.getObjectName(),this,null,null); + xmbean.getMBeanServerConnection().addNotificationListener( + xmbean.getObjectName(), this, null, null); unregistered = false; - }catch(Exception e) { - System.out.println("Error adding listener :"+ - e.getMessage()); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error adding listener:"); + e.printStackTrace(); + } } } - public synchronized void handleNotification(Notification e, - Object handback) { - try { - if(unregistered) return; - Date receivedDate = new Date(e.getTimeStamp()); - String time = timeFormater.format(receivedDate); + public synchronized void handleNotification( + final Notification n, Object hb) { + EventQueue.invokeLater(new Runnable() { - Object userData = e.getUserData(); - Component comp = null; - UserDataCell cell = null; - if((comp = XDataViewer.createNotificationViewer(userData)) - != null) { - XDataViewer.registerForMouseEvent(comp, mouseListener); - cell = new UserDataCell(userData, comp); + public void run() { + synchronized (XMBeanNotificationsListener.this) { + try { + if (unregistered) { + return; + } + Date receivedDate = new Date(n.getTimeStamp()); + String time = timeFormater.format(receivedDate); + + Object userData = n.getUserData(); + Component comp = null; + UserDataCell cell = null; + if ((comp = XDataViewer.createNotificationViewer(userData)) != null) { + XDataViewer.registerForMouseEvent(comp, mouseListener); + cell = new UserDataCell(userData, comp); + } + + Object[] rowData = { + time, + n.getType(), + (cell == null ? userData : cell), + n.getSequenceNumber(), + n.getMessage(), + n, + n.getSource() + }; + received++; + data.add(0, rowData); + + notifications.fireNotificationReceived( + XMBeanNotificationsListener.this, + xmbean, node, rowData, received); + } catch (Exception e) { + if (JConsole.isDebug()) { + System.err.println("Error handling notification:"); + e.printStackTrace(); + } + } + } } - - Object[] rowData = {time, - e.getType(), - (cell == null ? userData : cell), - new Long(e.getSequenceNumber()), - e.getMessage(), - e, - e.getSource()}; - received++; - data.add(0, rowData); - - notifications.fireNotificationReceived(this, - xmbean, - node, - rowData, - received); - } - catch (Exception ex) { - ex.printStackTrace(); - System.out.println("Error when handling notification :"+ - ex.toString()); - } + }); } } } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java index c5325e14344..81f295f3215 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import javax.management.*; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java index 280607b74d2..f5aa3132ca2 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; // java import diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java index c74bb948b1b..14b9a676f00 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java @@ -33,10 +33,7 @@ import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.FlowLayout; import java.awt.Component; -import java.awt.EventQueue; import java.awt.event.*; -import java.awt.Insets; -import java.awt.Dimension; import java.util.*; import java.io.*; @@ -49,29 +46,30 @@ import sun.tools.jconsole.JConsole; public abstract class XOperations extends JPanel implements ActionListener { public final static String OPERATION_INVOCATION_EVENT = - "jam.xoperations.invoke.result"; + "jam.xoperations.invoke.result"; private java.util.List notificationListenersList; - private Hashtable operationEntryTable; - private XMBean mbean; private MBeanInfo mbeanInfo; private MBeansTab mbeansTab; + public XOperations(MBeansTab mbeansTab) { - super(new GridLayout(1,1)); + super(new GridLayout(1, 1)); this.mbeansTab = mbeansTab; operationEntryTable = new Hashtable(); ArrayList l = - new ArrayList(1); + new ArrayList(1); notificationListenersList = - Collections.synchronizedList(l); + Collections.synchronizedList(l); } + // Call on EDT public void removeOperations() { removeAll(); } - public void loadOperations(XMBean mbean,MBeanInfo mbeanInfo) { + // Call on EDT + public void loadOperations(XMBean mbean, MBeanInfo mbeanInfo) { this.mbean = mbean; this.mbeanInfo = mbeanInfo; // add operations information @@ -80,131 +78,149 @@ public abstract class XOperations extends JPanel implements ActionListener { // remove listeners, if any Component listeners[] = getComponents(); - for (int i = 0; i < listeners.length; i++) - if (listeners[i] instanceof JButton) - ((JButton)listeners[i]).removeActionListener(this); + for (int i = 0; i < listeners.length; i++) { + if (listeners[i] instanceof JButton) { + ((JButton) listeners[i]).removeActionListener(this); + } + } removeAll(); setLayout(new BorderLayout()); JButton methodButton; JLabel methodLabel; - JPanel innerPanelLeft,innerPanelRight; - JPanel outerPanelLeft,outerPanelRight; - outerPanelLeft = new JPanel(new GridLayout(operations.length,1)); - outerPanelRight = new JPanel(new GridLayout(operations.length,1)); + JPanel innerPanelLeft, innerPanelRight; + JPanel outerPanelLeft, outerPanelRight; + outerPanelLeft = new JPanel(new GridLayout(operations.length, 1)); + outerPanelRight = new JPanel(new GridLayout(operations.length, 1)); - for (int i=0;i20) { + String returnType = operations[i].getReturnType(); + if (returnType == null) { + methodLabel = new JLabel("null", JLabel.RIGHT); + if (JConsole.isDebug()) { + System.err.println( + "WARNING: The operation's return type " + + "shouldn't be \"null\". Check how the " + + "MBeanOperationInfo for the \"" + + operations[i].getName() + "\" operation has " + + "been defined in the MBean's implementation code."); + } + } else { + methodLabel = new JLabel( + Utils.getReadableClassName(returnType), JLabel.RIGHT); + } + innerPanelLeft.add(methodLabel); + if (methodLabel.getText().length() > 20) { methodLabel.setText(methodLabel.getText(). - substring(methodLabel.getText(). - lastIndexOf(".")+1, - methodLabel.getText().length())); + substring(methodLabel.getText(). + lastIndexOf(".") + 1, + methodLabel.getText().length())); } methodButton = new JButton(operations[i].getName()); methodButton.setToolTipText(operations[i].getDescription()); boolean callable = isCallable(operations[i].getSignature()); - if(callable) + if (callable) { methodButton.addActionListener(this); - else + } else { methodButton.setEnabled(false); + } MBeanParameterInfo[] signature = operations[i].getSignature(); OperationEntry paramEntry = new OperationEntry(operations[i], - callable, - methodButton, - this); + callable, + methodButton, + this); operationEntryTable.put(methodButton, paramEntry); innerPanelRight.add(methodButton); - if(signature.length==0) - innerPanelRight.add(new JLabel("( )",JLabel.CENTER)); - else - innerPanelRight.add(paramEntry); + if (signature.length == 0) { + innerPanelRight.add(new JLabel("( )", JLabel.CENTER)); + } else { + innerPanelRight.add(paramEntry); + } - outerPanelLeft.add(innerPanelLeft,BorderLayout.WEST); - outerPanelRight.add(innerPanelRight,BorderLayout.CENTER); + outerPanelLeft.add(innerPanelLeft, BorderLayout.WEST); + outerPanelRight.add(innerPanelRight, BorderLayout.CENTER); } - add(outerPanelLeft,BorderLayout.WEST); - add(outerPanelRight,BorderLayout.CENTER); + add(outerPanelLeft, BorderLayout.WEST); + add(outerPanelRight, BorderLayout.CENTER); validate(); } private boolean isCallable(MBeanParameterInfo[] signature) { - for(int i = 0; i < signature.length; i++) { - if(!Utils.isEditableType(signature[i].getType())) + for (int i = 0; i < signature.length; i++) { + if (!Utils.isEditableType(signature[i].getType())) { return false; + } } return true; } + // Call on EDT public void actionPerformed(final ActionEvent e) { - performInvokeRequest((JButton)e.getSource()); + performInvokeRequest((JButton) e.getSource()); } void performInvokeRequest(final JButton button) { - mbeansTab.workerAdd(new Runnable() { - public void run() { + final OperationEntry entryIf = operationEntryTable.get(button); + new SwingWorker() { + @Override + public Object doInBackground() throws Exception { + return mbean.invoke(button.getText(), + entryIf.getParameters(), entryIf.getSignature()); + } + @Override + protected void done() { try { - OperationEntry entryIf = operationEntryTable.get(button); - Object result = null; - result = mbean.invoke(button.getText(), - entryIf.getParameters(), - entryIf.getSignature()); + Object result = get(); // sends result notification to upper level if // there is a return value if (entryIf.getReturnType() != null && - !entryIf.getReturnType().equals(Void.TYPE.getName()) && - !entryIf.getReturnType().equals(Void.class.getName())) - fireChangedNotification(OPERATION_INVOCATION_EVENT, - button, - result); - else - EventQueue.invokeLater(new ThreadDialog( - button, - Resources.getText("Method successfully invoked"), - Resources.getText("Info"), - JOptionPane.INFORMATION_MESSAGE)); - } catch (Throwable ex) { - if (JConsole.isDebug()) { - ex.printStackTrace(); + !entryIf.getReturnType().equals(Void.TYPE.getName()) && + !entryIf.getReturnType().equals(Void.class.getName())) { + fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result); + } else { + new ThreadDialog( + button, + Resources.getText("Method successfully invoked"), + Resources.getText("Info"), + JOptionPane.INFORMATION_MESSAGE).run(); } - ex = Utils.getActualException(ex); - String message = ex.toString(); - EventQueue.invokeLater(new ThreadDialog( - button, - Resources.getText("Problem invoking") + " " + - button.getText() + " : " + message, - Resources.getText("Error"), - JOptionPane.ERROR_MESSAGE)); + } catch (Throwable t) { + t = Utils.getActualException(t); + if (JConsole.isDebug()) { + t.printStackTrace(); + } + new ThreadDialog( + button, + Resources.getText("Problem invoking") + " " + + button.getText() + " : " + t.toString(), + Resources.getText("Error"), + JOptionPane.ERROR_MESSAGE).run(); } } - }); + }.execute(); } public void addOperationsListener(NotificationListener nl) { - notificationListenersList.add(nl); - } + notificationListenersList.add(nl); + } public void removeOperationsListener(NotificationListener nl) { notificationListenersList.remove(nl); } - private void fireChangedNotification(String type, - Object source, - Object handback) { - Notification e = new Notification(type,source,0); - for(NotificationListener nl : notificationListenersList) - nl.handleNotification(e,handback); + // Call on EDT + private void fireChangedNotification( + String type, Object source, Object handback) { + Notification n = new Notification(type, source, 0); + for (NotificationListener nl : notificationListenersList) { + nl.handleNotification(n, handback); + } } - protected abstract MBeanOperationInfo[] - updateOperations(MBeanOperationInfo[] operations); + protected abstract MBeanOperationInfo[] updateOperations(MBeanOperationInfo[] operations); } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java index 292dc78adf6..9135b7a5402 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java @@ -22,7 +22,9 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; + import sun.tools.jconsole.Plotter; import javax.swing.JTable; import java.awt.Graphics; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java index 017a4a7df93..5bcf72dd719 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.awt.*; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java index 6360a082ae4..11fce7f45bf 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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,7 +28,6 @@ package sun.tools.jconsole.inspector; import java.awt.*; import java.awt.event.*; import java.io.*; -import java.util.Enumeration; import javax.management.*; import javax.swing.*; import javax.swing.border.*; @@ -45,31 +44,22 @@ public class XSheet extends JPanel private JPanel mainPanel; private JPanel southPanel; - // Node being currently displayed - private DefaultMutableTreeNode node; - + private volatile DefaultMutableTreeNode currentNode; // MBean being currently displayed - private XMBean mbean; - + private volatile XMBean mbean; // XMBeanAttributes container private XMBeanAttributes mbeanAttributes; - // XMBeanOperations container private XMBeanOperations mbeanOperations; - // XMBeanNotifications container private XMBeanNotifications mbeanNotifications; - // XMBeanInfo container private XMBeanInfo mbeanInfo; - // Refresh JButton (mbean attributes case) private JButton refreshButton; - // Subscribe/Unsubscribe/Clear JButton (mbean notifications case) - private JButton clearButton, subscribeButton, unsubscribeButton; - + private JButton clearButton, subscribeButton, unsubscribeButton; // Reference to MBeans tab private MBeansTab mbeansTab; @@ -86,6 +76,7 @@ public class XSheet extends JPanel private void setupScreen() { setLayout(new BorderLayout()); + setBorder(BorderFactory.createLineBorder(Color.GRAY)); // add main panel to XSheet mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); @@ -129,17 +120,32 @@ public class XSheet extends JPanel mbeanInfo = new XMBeanInfo(); } - public boolean isMBeanNode(DefaultMutableTreeNode node) { - XNodeInfo uo = (XNodeInfo) node.getUserObject(); - return uo.getType().equals(Type.MBEAN); + private boolean isSelectedNode(DefaultMutableTreeNode n, DefaultMutableTreeNode cn) { + return (cn == n); } - public void displayNode(DefaultMutableTreeNode node) { + // Call on EDT + private void showErrorDialog(Object message, String title) { + new ThreadDialog(this, message, title, JOptionPane.ERROR_MESSAGE).run(); + } + + public boolean isMBeanNode(DefaultMutableTreeNode node) { + Object userObject = node.getUserObject(); + if (userObject instanceof XNodeInfo) { + XNodeInfo uo = (XNodeInfo) userObject; + return uo.getType().equals(Type.MBEAN); + } + return false; + } + + // Call on EDT + public synchronized void displayNode(DefaultMutableTreeNode node) { clear(); + displayEmptyNode(); if (node == null) { - displayEmptyNode(); return; } + currentNode = node; Object userObject = node.getUserObject(); if (userObject instanceof XNodeInfo) { XNodeInfo uo = (XNodeInfo) userObject; @@ -173,27 +179,28 @@ public class XSheet extends JPanel } } + // Call on EDT private void displayMBeanNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.MBEAN)) { return; } - mbeansTab.workerAdd(new Runnable() { - public void run() { + mbean = (XMBean) uo.getData(); + SwingWorker sw = new SwingWorker() { + @Override + public MBeanInfo doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + return mbean.getMBeanInfo(); + } + @Override + protected void done() { try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mbeanInfo.addMBeanInfo(mbean, mbean.getMBeanInfo()); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { + MBeanInfo mbi = get(); + if (mbi != null) { + if (!isSelectedNode(node, currentNode)) { + return; + } + mbeanInfo.addMBeanInfo(mbean, mbi); invalidate(); mainPanel.removeAll(); mainPanel.add(mbeanInfo, BorderLayout.CENTER); @@ -202,9 +209,19 @@ public class XSheet extends JPanel validate(); repaint(); } - }); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Couldn't get MBeanInfo for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } } - }); + }; + sw.execute(); } // Call on EDT @@ -213,90 +230,90 @@ public class XSheet extends JPanel final XMBeanInfo mbi = mbeanInfo; switch (uo.getType()) { case ATTRIBUTE: - mbeansTab.workerAdd(new Runnable() { - public void run() { - Object attrData = uo.getData(); - XSheet.this.mbean = (XMBean) ((Object[]) attrData)[0]; - final MBeanAttributeInfo mbai = - (MBeanAttributeInfo) ((Object[]) attrData)[1]; - final XMBeanAttributes mba = mbeanAttributes; - try { - mba.loadAttributes(mbean, new MBeanInfo( - null, null, new MBeanAttributeInfo[] {mbai}, - null, null, null)); - } catch (Exception e) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - e.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { - invalidate(); - mainPanel.removeAll(); - JPanel attributePanel = - new JPanel(new BorderLayout()); - JPanel attributeBorderPanel = - new JPanel(new BorderLayout()); - attributeBorderPanel.setBorder( - BorderFactory.createTitledBorder( - Resources.getText("Attribute value"))); - JPanel attributeValuePanel = - new JPanel(new BorderLayout()); - attributeValuePanel.setBorder( - LineBorder.createGrayLineBorder()); - attributeValuePanel.add(mba.getTableHeader(), - BorderLayout.PAGE_START); - attributeValuePanel.add(mba, - BorderLayout.CENTER); - attributeBorderPanel.add(attributeValuePanel, - BorderLayout.CENTER); - JPanel refreshButtonPanel = new JPanel(); - refreshButtonPanel.add(refreshButton); - attributeBorderPanel.add(refreshButtonPanel, - BorderLayout.SOUTH); - refreshButton.setEnabled(true); - attributePanel.add(attributeBorderPanel, - BorderLayout.NORTH); - mbi.addMBeanAttributeInfo(mbai); - attributePanel.add(mbi, BorderLayout.CENTER); - mainPanel.add(attributePanel, - BorderLayout.CENTER); - southPanel.setVisible(false); - southPanel.removeAll(); - validate(); - repaint(); + SwingWorker sw = + new SwingWorker() { + @Override + public MBeanAttributeInfo doInBackground() { + Object attrData = uo.getData(); + mbean = (XMBean) ((Object[]) attrData)[0]; + MBeanAttributeInfo mbai = + (MBeanAttributeInfo) ((Object[]) attrData)[1]; + mbeanAttributes.loadAttributes(mbean, new MBeanInfo( + null, null, new MBeanAttributeInfo[]{mbai}, + null, null, null)); + return mbai; } - }); - } - }); + @Override + protected void done() { + try { + MBeanAttributeInfo mbai = get(); + if (!isSelectedNode(node, currentNode)) { + return; + } + invalidate(); + mainPanel.removeAll(); + JPanel attributePanel = + new JPanel(new BorderLayout()); + JPanel attributeBorderPanel = + new JPanel(new BorderLayout()); + attributeBorderPanel.setBorder( + BorderFactory.createTitledBorder( + Resources.getText("Attribute value"))); + JPanel attributeValuePanel = + new JPanel(new BorderLayout()); + attributeValuePanel.setBorder( + LineBorder.createGrayLineBorder()); + attributeValuePanel.add(mbeanAttributes.getTableHeader(), + BorderLayout.PAGE_START); + attributeValuePanel.add(mbeanAttributes, + BorderLayout.CENTER); + attributeBorderPanel.add(attributeValuePanel, + BorderLayout.CENTER); + JPanel refreshButtonPanel = new JPanel(); + refreshButtonPanel.add(refreshButton); + attributeBorderPanel.add(refreshButtonPanel, + BorderLayout.SOUTH); + refreshButton.setEnabled(true); + attributePanel.add(attributeBorderPanel, + BorderLayout.NORTH); + mbi.addMBeanAttributeInfo(mbai); + attributePanel.add(mbi, BorderLayout.CENTER); + mainPanel.add(attributePanel, + BorderLayout.CENTER); + southPanel.setVisible(false); + southPanel.removeAll(); + validate(); + repaint(); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem displaying MBean " + + "attribute for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } + } + }; + sw.execute(); break; case OPERATION: Object operData = uo.getData(); - XSheet.this.mbean = (XMBean) ((Object[]) operData)[0]; + mbean = (XMBean) ((Object[]) operData)[0]; MBeanOperationInfo mboi = (MBeanOperationInfo) ((Object[]) operData)[1]; - XMBeanOperations mbo = mbeanOperations; - try { - mbo.loadOperations(mbean, new MBeanInfo(null, null, null, - null, new MBeanOperationInfo[] {mboi}, null)); - } catch (Exception e) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - e.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } + mbeanOperations.loadOperations(mbean, + new MBeanInfo(null, null, null, null, + new MBeanOperationInfo[]{mboi}, null)); invalidate(); mainPanel.removeAll(); JPanel operationPanel = new JPanel(new BorderLayout()); JPanel operationBorderPanel = new JPanel(new BorderLayout()); operationBorderPanel.setBorder(BorderFactory.createTitledBorder( Resources.getText("Operation invocation"))); - operationBorderPanel.add(new JScrollPane(mbo)); + operationBorderPanel.add(new JScrollPane(mbeanOperations)); operationPanel.add(operationBorderPanel, BorderLayout.NORTH); mbi.addMBeanOperationInfo(mboi); operationPanel.add(mbi, BorderLayout.CENTER); @@ -320,134 +337,134 @@ public class XSheet extends JPanel } } + // Call on EDT private void displayMBeanAttributesNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.ATTRIBUTES)) { return; } - final XMBeanAttributes mba = mbeanAttributes; - mbeansTab.workerAdd(new Runnable() { - public void run() { - try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mba.loadAttributes(mbean, mbean.getMBeanInfo()); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { - invalidate(); - mainPanel.removeAll(); - JPanel borderPanel = new JPanel(new BorderLayout()); - borderPanel.setBorder(BorderFactory.createTitledBorder( - Resources.getText("Attribute values"))); - borderPanel.add(new JScrollPane(mba)); - mainPanel.add(borderPanel, BorderLayout.CENTER); - // add the refresh button to the south panel - southPanel.removeAll(); - southPanel.add(refreshButton, BorderLayout.SOUTH); - southPanel.setVisible(true); - refreshButton.setEnabled(true); - validate(); - repaint(); - } - }); + mbean = (XMBean) uo.getData(); + SwingWorker sw = new SwingWorker() { + @Override + public Void doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + mbeanAttributes.loadAttributes(mbean, mbean.getMBeanInfo()); + return null; } - }); + @Override + protected void done() { + try { + get(); + if (!isSelectedNode(node, currentNode)) { + return; + } + invalidate(); + mainPanel.removeAll(); + JPanel borderPanel = new JPanel(new BorderLayout()); + borderPanel.setBorder(BorderFactory.createTitledBorder( + Resources.getText("Attribute values"))); + borderPanel.add(new JScrollPane(mbeanAttributes)); + mainPanel.add(borderPanel, BorderLayout.CENTER); + // add the refresh button to the south panel + southPanel.removeAll(); + southPanel.add(refreshButton, BorderLayout.SOUTH); + southPanel.setVisible(true); + refreshButton.setEnabled(true); + validate(); + repaint(); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem displaying MBean " + + "attributes for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } + } + }; + sw.execute(); } + // Call on EDT private void displayMBeanOperationsNode(final DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.OPERATIONS)) { return; } - final XMBeanOperations mbo = mbeanOperations; - mbeansTab.workerAdd(new Runnable() { - public void run() { + mbean = (XMBean) uo.getData(); + SwingWorker sw = new SwingWorker() { + @Override + public MBeanInfo doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + return mbean.getMBeanInfo(); + } + @Override + protected void done() { try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mbo.loadOperations(mbean, mbean.getMBeanInfo()); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { + MBeanInfo mbi = get(); + if (mbi != null) { + if (!isSelectedNode(node, currentNode)) { + return; + } + mbeanOperations.loadOperations(mbean, mbi); invalidate(); mainPanel.removeAll(); JPanel borderPanel = new JPanel(new BorderLayout()); borderPanel.setBorder(BorderFactory.createTitledBorder( Resources.getText("Operation invocation"))); - borderPanel.add(new JScrollPane(mbo)); + borderPanel.add(new JScrollPane(mbeanOperations)); mainPanel.add(borderPanel, BorderLayout.CENTER); southPanel.setVisible(false); southPanel.removeAll(); validate(); repaint(); } - }); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem displaying MBean " + + "operations for MBean [" + + mbean.getObjectName() + "]"); + t.printStackTrace(); + } + showErrorDialog(t.toString(), + Resources.getText("Problem displaying MBean")); + } } - }); + }; + sw.execute(); } - private void displayMBeanNotificationsNode( - final DefaultMutableTreeNode node) { + // Call on EDT + private void displayMBeanNotificationsNode(DefaultMutableTreeNode node) { final XNodeInfo uo = (XNodeInfo) node.getUserObject(); if (!uo.getType().equals(Type.NOTIFICATIONS)) { return; } - final XMBeanNotifications mbn = mbeanNotifications; - mbeansTab.workerAdd(new Runnable() { - public void run() { - try { - XSheet.this.node = node; - XSheet.this.mbean = (XMBean) uo.getData(); - mbn.loadNotifications(mbean); - updateNotifications(); - } catch (Throwable ex) { - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem displaying MBean"), - JOptionPane.ERROR_MESSAGE)); - return; - } - EventQueue.invokeLater(new Runnable() { - public void run() { - invalidate(); - mainPanel.removeAll(); - JPanel borderPanel = new JPanel(new BorderLayout()); - borderPanel.setBorder(BorderFactory.createTitledBorder( - Resources.getText("Notification buffer"))); - borderPanel.add(new JScrollPane(mbn)); - mainPanel.add(borderPanel, BorderLayout.CENTER); - // add the subscribe/unsubscribe/clear buttons to - // the south panel - southPanel.removeAll(); - southPanel.add(subscribeButton, BorderLayout.WEST); - southPanel.add(unsubscribeButton, BorderLayout.CENTER); - southPanel.add(clearButton, BorderLayout.EAST); - southPanel.setVisible(true); - subscribeButton.setEnabled(true); - unsubscribeButton.setEnabled(true); - clearButton.setEnabled(true); - validate(); - repaint(); - } - }); - } - }); + mbean = (XMBean) uo.getData(); + mbeanNotifications.loadNotifications(mbean); + updateNotifications(); + invalidate(); + mainPanel.removeAll(); + JPanel borderPanel = new JPanel(new BorderLayout()); + borderPanel.setBorder(BorderFactory.createTitledBorder( + Resources.getText("Notification buffer"))); + borderPanel.add(new JScrollPane(mbeanNotifications)); + mainPanel.add(borderPanel, BorderLayout.CENTER); + // add the subscribe/unsubscribe/clear buttons to the south panel + southPanel.removeAll(); + southPanel.add(subscribeButton, BorderLayout.WEST); + southPanel.add(unsubscribeButton, BorderLayout.CENTER); + southPanel.add(clearButton, BorderLayout.EAST); + southPanel.setVisible(true); + subscribeButton.setEnabled(true); + unsubscribeButton.setEnabled(true); + clearButton.setEnabled(true); + validate(); + repaint(); } // Call on EDT @@ -462,21 +479,60 @@ public class XSheet extends JPanel /** * Subscribe button action. */ - private void registerListener() throws InstanceNotFoundException, - IOException { - mbeanNotifications.registerListener(node); - updateNotifications(); - validate(); + private void registerListener() { + new SwingWorker() { + @Override + public Void doInBackground() + throws InstanceNotFoundException, IOException { + mbeanNotifications.registerListener(currentNode); + return null; + } + @Override + protected void done() { + try { + get(); + updateNotifications(); + validate(); + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem adding listener"); + t.printStackTrace(); + } + showErrorDialog(t.getMessage(), + Resources.getText("Problem adding listener")); + } + } + }.execute(); } /** * Unsubscribe button action. */ private void unregisterListener() { - if (mbeanNotifications.unregisterListener(node)) { - clearNotifications(); - validate(); - } + new SwingWorker() { + @Override + public Boolean doInBackground() { + return mbeanNotifications.unregisterListener(currentNode); + } + @Override + protected void done() { + try { + if (get()) { + updateNotifications(); + validate(); + } + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + System.err.println("Problem removing listener"); + t.printStackTrace(); + } + showErrorDialog(t.getMessage(), + Resources.getText("Problem removing listener")); + } + } + }.execute(); } /** @@ -486,15 +542,11 @@ public class XSheet extends JPanel mbeanAttributes.refreshAttributes(); } + // Call on EDT private void updateNotifications() { - if (mbean.isBroadcaster()) { - if (mbeanNotifications.isListenerRegistered(mbean)) { - long received = - mbeanNotifications.getReceivedNotifications(mbean); - updateReceivedNotifications(node, received, false); - } else { - clearNotifications(); - } + if (mbeanNotifications.isListenerRegistered(mbean)) { + long received = mbeanNotifications.getReceivedNotifications(mbean); + updateReceivedNotifications(currentNode, received, false); } else { clearNotifications(); } @@ -503,11 +555,11 @@ public class XSheet extends JPanel /** * Update notification node label in MBean tree: "Notifications[received]". */ + // Call on EDT private void updateReceivedNotifications( DefaultMutableTreeNode emitter, long received, boolean bold) { String text = Resources.getText("Notifications") + "[" + received + "]"; - DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) - mbeansTab.getTree().getLastSelectedPathComponent(); + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent(); if (bold && emitter != selectedNode) { text = "" + text + ""; } @@ -517,41 +569,40 @@ public class XSheet extends JPanel /** * Update notification node label in MBean tree: "Notifications". */ + // Call on EDT private void clearNotifications() { - updateNotificationsNodeLabel(node, + updateNotificationsNodeLabel(currentNode, Resources.getText("Notifications")); } /** * Update notification node label in MBean tree: "Notifications[0]". */ + // Call on EDT private void clearNotifications0() { - updateNotificationsNodeLabel(node, + updateNotificationsNodeLabel(currentNode, Resources.getText("Notifications") + "[0]"); } /** * Update the label of the supplied MBean tree node. */ + // Call on EDT private void updateNotificationsNodeLabel( - final DefaultMutableTreeNode node, final String label) { - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (mbeansTab.getTree()) { - invalidate(); - XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject(); - XNodeInfo newUserObject = new XNodeInfo( - oldUserObject.getType(), oldUserObject.getData(), - label, oldUserObject.getToolTipText()); - node.setUserObject(newUserObject); - DefaultTreeModel model = - (DefaultTreeModel) mbeansTab.getTree().getModel(); - model.nodeChanged(node); - validate(); - repaint(); - } - } - }); + DefaultMutableTreeNode node, String label) { + synchronized (mbeansTab.getTree()) { + invalidate(); + XNodeInfo oldUserObject = (XNodeInfo) node.getUserObject(); + XNodeInfo newUserObject = new XNodeInfo( + oldUserObject.getType(), oldUserObject.getData(), + label, oldUserObject.getToolTipText()); + node.setUserObject(newUserObject); + DefaultTreeModel model = + (DefaultTreeModel) mbeansTab.getTree().getModel(); + model.nodeChanged(node); + validate(); + repaint(); + } } /** @@ -577,6 +628,7 @@ public class XSheet extends JPanel } } + // Call on EDT private void clear() { mbeanAttributes.stopCellEditing(); mbeanAttributes.emptyTable(); @@ -586,13 +638,14 @@ public class XSheet extends JPanel mbeanNotifications.emptyTable(); mbeanNotifications.disableNotifications(); mbean = null; - node = null; + currentNode = null; } /** * Notification listener: handles asynchronous reception * of MBean operation results and MBean notifications. */ + // Call on EDT public void handleNotification(Notification e, Object handback) { // Operation result if (e.getType().equals(XOperations.OPERATION_INVOCATION_EVENT)) { @@ -628,13 +681,12 @@ public class XSheet extends JPanel message = comp; } } - EventQueue.invokeLater(new ThreadDialog( + new ThreadDialog( (Component) e.getSource(), message, Resources.getText("Operation return value"), - JOptionPane.INFORMATION_MESSAGE)); - } - // Got notification + JOptionPane.INFORMATION_MESSAGE).run(); + } // Got notification else if (e.getType().equals( XMBeanNotifications.NOTIFICATION_RECEIVED_EVENT)) { DefaultMutableTreeNode emitter = (DefaultMutableTreeNode) handback; @@ -646,16 +698,19 @@ public class XSheet extends JPanel /** * Action listener: handles actions in panel buttons */ + // Call on EDT public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JButton) { JButton button = (JButton) e.getSource(); // Refresh button if (button == refreshButton) { - mbeansTab.workerAdd(new Runnable() { - public void run() { + new SwingWorker() { + @Override + public Void doInBackground() { refreshAttributes(); + return null; } - }); + }.execute(); return; } // Clear button @@ -665,38 +720,12 @@ public class XSheet extends JPanel } // Subscribe button if (button == subscribeButton) { - mbeansTab.workerAdd(new Runnable() { - public void run() { - try { - registerListener(); - } catch (Throwable ex) { - ex = Utils.getActualException(ex); - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem adding listener"), - JOptionPane.ERROR_MESSAGE)); - } - } - }); + registerListener(); return; } // Unsubscribe button if (button == unsubscribeButton) { - mbeansTab.workerAdd(new Runnable() { - public void run() { - try { - unregisterListener(); - } catch (Throwable ex) { - ex = Utils.getActualException(ex); - EventQueue.invokeLater(new ThreadDialog( - XSheet.this, - ex.getMessage(), - Resources.getText("Problem removing listener"), - JOptionPane.ERROR_MESSAGE)); - } - } - }); + unregisterListener(); return; } } diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java index 5b695c81699..c75ca66ccf5 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import javax.swing.*; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java index 2e7f8cb6f67..a84819d27c5 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.awt.*; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java index 9476d5a8500..237df937788 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + package sun.tools.jconsole.inspector; import java.awt.Component; diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java index c6f4ce4976d..38ee4065a35 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2007 Sun Microsystems, Inc. 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,7 +25,7 @@ package sun.tools.jconsole.inspector; -import java.awt.EventQueue; +import java.io.IOException; import java.util.*; import javax.management.*; import javax.swing.*; @@ -34,13 +34,14 @@ import sun.tools.jconsole.JConsole; import sun.tools.jconsole.MBeansTab; import sun.tools.jconsole.Resources; import sun.tools.jconsole.inspector.XNodeInfo; -import sun.tools.jconsole.inspector.XNodeInfo.Type; +import static sun.tools.jconsole.inspector.XNodeInfo.Type; @SuppressWarnings("serial") public class XTree extends JTree { private static final List orderedKeyPropertyList = new ArrayList(); + static { String keyPropertyList = System.getProperty("com.sun.tools.jconsole.mbeans.keyPropertyList"); @@ -54,9 +55,7 @@ public class XTree extends JTree { } } } - private MBeansTab mbeansTab; - private Map nodes = new HashMap(); @@ -65,7 +64,7 @@ public class XTree extends JTree { } public XTree(TreeNode root, MBeansTab mbeansTab) { - super(root); + super(root, true); this.mbeansTab = mbeansTab; setRootVisible(false); setShowsRootHandles(true); @@ -90,15 +89,8 @@ public class XTree extends JTree { DefaultMutableTreeNode parent, DefaultMutableTreeNode child, int index) { - // Tree does not show up when there is only the root node - // DefaultTreeModel model = (DefaultTreeModel) getModel(); - DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); - boolean rootLeaf = root.isLeaf(); model.insertNodeInto(child, parent, index); - if (rootLeaf) { - model.nodeStructureChanged(root); - } } /** @@ -114,32 +106,29 @@ public class XTree extends JTree { int childCount = parent.getChildCount(); if (childCount == 0) { addChildNode(parent, child, 0); - } else if (child instanceof ComparableDefaultMutableTreeNode) { + return; + } + if (child instanceof ComparableDefaultMutableTreeNode) { ComparableDefaultMutableTreeNode comparableChild = - (ComparableDefaultMutableTreeNode)child; - int i = 0; - for (; i < childCount; i++) { + (ComparableDefaultMutableTreeNode) child; + for (int i = childCount - 1; i >= 0; i--) { DefaultMutableTreeNode brother = (DefaultMutableTreeNode) parent.getChildAt(i); - //child < brother - if (comparableChild.compareTo(brother) < 0) { - addChildNode(parent, child, i); - break; - } - //child = brother - else if (comparableChild.compareTo(brother) == 0) { - addChildNode(parent, child, i); - break; + // expr1: child node must be inserted after metadata nodes + // - OR - + // expr2: "child >= brother" + if ((i <= 2 && isMetadataNode(brother)) || + comparableChild.compareTo(brother) >= 0) { + addChildNode(parent, child, i + 1); + return; } } - //child < all brothers - if (i == childCount) { - addChildNode(parent, child, childCount); - } - } else { - //not comparable, add at the end - addChildNode(parent, child, childCount); + // "child < all brothers", add at the beginning + addChildNode(parent, child, 0); + return; } + // "child not comparable", add at the end + addChildNode(parent, child, childCount); } /** @@ -147,6 +136,7 @@ public class XTree extends JTree { * but does not affect actual MBeanServer contents. */ // Call on EDT + @Override public synchronized void removeAll() { DefaultTreeModel model = (DefaultTreeModel) getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); @@ -155,51 +145,56 @@ public class XTree extends JTree { nodes.clear(); } - public void delMBeanFromView(final ObjectName mbean) { - EventQueue.invokeLater(new Runnable() { - public void run() { - // We assume here that MBeans are removed one by one (on MBean - // unregistered notification). Deletes the tree node associated - // with the given MBean and recursively all the node parents - // which are leaves and non XMBean. - // - synchronized (XTree.this) { - DefaultMutableTreeNode node = null; - Dn dn = buildDn(mbean); - if (dn.size() > 0) { - DefaultTreeModel model = (DefaultTreeModel) getModel(); - Token token = dn.getToken(0); - String hashKey = dn.getHashKey(token); - node = nodes.get(hashKey); - if ((node != null) && (!node.isRoot())) { - if (hasMBeanChildren(node)) { - removeNonMBeanChildren(node); - String label = token.getValue().toString(); - XNodeInfo userObject = new XNodeInfo( - Type.NONMBEAN, label, - label, token.toString()); - changeNodeValue(node, userObject); - } else { - DefaultMutableTreeNode parent = - (DefaultMutableTreeNode) node.getParent(); - model.removeNodeFromParent(node); - nodes.remove(hashKey); - delParentFromView(dn, 1, parent); - } - } - } + // Call on EDT + public synchronized void removeMBeanFromView(ObjectName mbean) { + // We assume here that MBeans are removed one by one (on MBean + // unregistered notification). Deletes the tree node associated + // with the given MBean and recursively all the node parents + // which are leaves and non XMBean. + // + DefaultMutableTreeNode node = null; + Dn dn = new Dn(mbean); + if (dn.getTokenCount() > 0) { + DefaultTreeModel model = (DefaultTreeModel) getModel(); + Token token = dn.getToken(0); + String hashKey = dn.getHashKey(token); + node = nodes.get(hashKey); + if ((node != null) && (!node.isRoot())) { + if (hasNonMetadataNodes(node)) { + removeMetadataNodes(node); + String label = token.getValue(); + XNodeInfo userObject = new XNodeInfo( + Type.NONMBEAN, label, + label, token.getTokenValue()); + changeNodeValue(node, userObject); + } else { + DefaultMutableTreeNode parent = + (DefaultMutableTreeNode) node.getParent(); + model.removeNodeFromParent(node); + nodes.remove(hashKey); + removeParentFromView(dn, 1, parent); } } - }); + } } /** - * Returns true if any of the children nodes is an MBean. + * Returns true if any of the children nodes is a non MBean metadata node. */ - private boolean hasMBeanChildren(DefaultMutableTreeNode node) { - for (Enumeration e = node.children(); e.hasMoreElements(); ) { + private boolean hasNonMetadataNodes(DefaultMutableTreeNode node) { + for (Enumeration e = node.children(); e.hasMoreElements();) { DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement(); - if (((XNodeInfo) n.getUserObject()).getType().equals(Type.MBEAN)) { + Object uo = n.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + break; + default: + return true; + } + } else { return true; } } @@ -207,16 +202,68 @@ public class XTree extends JTree { } /** - * Remove all the children nodes which are not MBean. + * Returns true if any of the children nodes is an MBean metadata node. */ - private void removeNonMBeanChildren(DefaultMutableTreeNode node) { + public boolean hasMetadataNodes(DefaultMutableTreeNode node) { + for (Enumeration e = node.children(); e.hasMoreElements();) { + DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement(); + Object uo = n.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + return true; + default: + break; + } + } else { + return false; + } + } + return false; + } + + /** + * Returns true if the given node is an MBean metadata node. + */ + public boolean isMetadataNode(DefaultMutableTreeNode node) { + Object uo = node.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + return true; + default: + return false; + } + } else { + return false; + } + } + + /** + * Remove the metadata nodes associated with a given MBean node. + */ + // Call on EDT + private void removeMetadataNodes(DefaultMutableTreeNode node) { Set metadataNodes = new HashSet(); DefaultTreeModel model = (DefaultTreeModel) getModel(); - for (Enumeration e = node.children(); e.hasMoreElements(); ) { + for (Enumeration e = node.children(); e.hasMoreElements();) { DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement(); - if (!((XNodeInfo) n.getUserObject()).getType().equals(Type.MBEAN)) { - metadataNodes.add(n); + Object uo = n.getUserObject(); + if (uo instanceof XNodeInfo) { + switch (((XNodeInfo) uo).getType()) { + case ATTRIBUTES: + case NOTIFICATIONS: + case OPERATIONS: + metadataNodes.add(n); + break; + default: + break; + } } } for (DefaultMutableTreeNode n : metadataNodes) { @@ -228,7 +275,8 @@ public class XTree extends JTree { * Removes only the parent nodes which are non MBean and leaf. * This method assumes the child nodes have been removed before. */ - private DefaultMutableTreeNode delParentFromView( + // Call on EDT + private DefaultMutableTreeNode removeParentFromView( Dn dn, int index, DefaultMutableTreeNode node) { if ((!node.isRoot()) && node.isLeaf() && (!(((XNodeInfo) node.getUserObject()).getType().equals(Type.MBEAN)))) { @@ -237,115 +285,100 @@ public class XTree extends JTree { removeChildNode(node); String hashKey = dn.getHashKey(dn.getToken(index)); nodes.remove(hashKey); - delParentFromView(dn, index + 1, parent); + removeParentFromView(dn, index + 1, parent); } return node; } - public synchronized void addMBeanToView(final ObjectName mbean) { - final XMBean xmbean; - try { - xmbean = new XMBean(mbean, mbeansTab); - if (xmbean == null) { - return; - } - } catch (Exception e) { - // Got exception while trying to retrieve the - // given MBean from the underlying MBeanServer + // Call on EDT + public synchronized void addMBeansToView(Set mbeans) { + Set dns = new TreeSet(); + for (ObjectName mbean : mbeans) { + Dn dn = new Dn(mbean); + dns.add(dn); + } + for (Dn dn : dns) { + ObjectName mbean = dn.getObjectName(); + XMBean xmbean = new XMBean(mbean, mbeansTab); + addMBeanToView(mbean, xmbean, dn); + } + } + + // Call on EDT + public synchronized void addMBeanToView(ObjectName mbean) { + // Build XMBean for the given MBean + // + XMBean xmbean = new XMBean(mbean, mbeansTab); + // Build Dn for the given MBean + // + Dn dn = new Dn(mbean); + // Add the new nodes to the MBean tree from leaf to root + // + addMBeanToView(mbean, xmbean, dn); + } + + // Call on EDT + private synchronized void addMBeanToView( + ObjectName mbean, XMBean xmbean, Dn dn) { + + DefaultMutableTreeNode childNode = null; + DefaultMutableTreeNode parentNode = null; + + // Add the node or replace its user object if already added + // + Token token = dn.getToken(0); + String hashKey = dn.getHashKey(token); + if (nodes.containsKey(hashKey)) { + // Found existing node previously created when adding another node // - if (JConsole.isDebug()) { - e.printStackTrace(); - } + childNode = nodes.get(hashKey); + // Replace user object to reflect that this node is an MBean + // + Object data = createNodeValue(xmbean, token); + String label = data.toString(); + XNodeInfo userObject = + new XNodeInfo(Type.MBEAN, data, label, mbean.toString()); + changeNodeValue(childNode, userObject); return; } - EventQueue.invokeLater(new Runnable() { - public void run() { - synchronized (XTree.this) { - // Add the new nodes to the MBean tree from leaf to root - Dn dn = buildDn(mbean); - if (dn.size() == 0) return; - Token token = dn.getToken(0); - DefaultMutableTreeNode node = null; - boolean nodeCreated = true; + // Create new leaf node + // + childNode = createDnNode(dn, token, xmbean); + nodes.put(hashKey, childNode); - // - // Add the node or replace its user object if already added - // - - String hashKey = dn.getHashKey(token); - if (nodes.containsKey(hashKey)) { - //already in the tree, means it has been created previously - //when adding another node - node = nodes.get(hashKey); - //sets the user object - final Object data = createNodeValue(xmbean, token); - final String label = data.toString(); - final XNodeInfo userObject = - new XNodeInfo(Type.MBEAN, data, label, mbean.toString()); - changeNodeValue(node, userObject); - nodeCreated = false; - } else { - //create a new node - node = createDnNode(dn, token, xmbean); - if (node != null) { - nodes.put(hashKey, node); - nodeCreated = true; - } else { - return; - } - } - - // - // Add (virtual) nodes without user object if necessary - // - - for (int i = 1; i < dn.size(); i++) { - DefaultMutableTreeNode currentNode = null; - token = dn.getToken(i); - hashKey = dn.getHashKey(token); - if (nodes.containsKey(hashKey)) { - //node already present - if (nodeCreated) { - //previous node created, link to do - currentNode = nodes.get(hashKey); - addChildNode(currentNode, node); - return; - } else { - //both nodes already present - return; - } - } else { - //creates the node that can be a virtual one - if (token.getKeyDn().equals("domain")) { - //better match on keyDn that on Dn - currentNode = createDomainNode(dn, token); - if (currentNode != null) { - final DefaultMutableTreeNode root = - (DefaultMutableTreeNode) getModel().getRoot(); - addChildNode(root, currentNode); - } - } else { - currentNode = createSubDnNode(dn, token); - if (currentNode == null) { - //skip - continue; - } - } - nodes.put(hashKey, currentNode); - addChildNode(currentNode, node); - nodeCreated = true; - } - node = currentNode; - } + // Add intermediate non MBean nodes + // + for (int i = 1; i < dn.getTokenCount(); i++) { + token = dn.getToken(i); + hashKey = dn.getHashKey(token); + if (nodes.containsKey(hashKey)) { + // Intermediate node already present, add new node as child + // + parentNode = nodes.get(hashKey); + addChildNode(parentNode, childNode); + return; + } else { + // Create new intermediate node + // + if ("domain".equals(token.getTokenType())) { + parentNode = createDomainNode(dn, token); + DefaultMutableTreeNode root = + (DefaultMutableTreeNode) getModel().getRoot(); + addChildNode(root, parentNode); + } else { + parentNode = createSubDnNode(dn, token); } + nodes.put(hashKey, parentNode); + addChildNode(parentNode, childNode); } - }); + childNode = parentNode; + } } // Call on EDT private synchronized void changeNodeValue( - final DefaultMutableTreeNode node, XNodeInfo nodeValue) { + DefaultMutableTreeNode node, XNodeInfo nodeValue) { if (node instanceof ComparableDefaultMutableTreeNode) { // should it stay at the same place? DefaultMutableTreeNode clone = @@ -373,9 +406,12 @@ public class XTree extends JTree { } // Load the MBean metadata if type is MBEAN if (nodeValue.getType().equals(Type.MBEAN)) { - XMBeanInfo.loadInfo(node); - DefaultTreeModel model = (DefaultTreeModel) getModel(); - model.nodeStructureChanged(node); + removeMetadataNodes(node); + TreeNode[] treeNodes = node.getPath(); + TreePath path = new TreePath(treeNodes); + if (isExpanded(path)) { + addMetadataNodes(node); + } } // Clear the current selection and set it // again so valueChanged() gets called @@ -386,7 +422,9 @@ public class XTree extends JTree { } } - //creates the domain node, called on a domain token + /** + * Creates the domain node. + */ private DefaultMutableTreeNode createDomainNode(Dn dn, Token token) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); String label = dn.getDomain(); @@ -396,7 +434,9 @@ public class XTree extends JTree { return node; } - //creates the node corresponding to the whole Dn + /** + * Creates the node corresponding to the whole Dn, i.e. an MBean. + */ private DefaultMutableTreeNode createDnNode( Dn dn, Token token, XMBean xmbean) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); @@ -405,38 +445,36 @@ public class XTree extends JTree { XNodeInfo userObject = new XNodeInfo(Type.MBEAN, data, label, xmbean.getObjectName().toString()); node.setUserObject(userObject); - XMBeanInfo.loadInfo(node); return node; } - //creates a node with the token value, call for each non domain sub - //dn token + /** + * Creates the node corresponding to a subDn, i.e. a non-MBean + * intermediate node. + */ private DefaultMutableTreeNode createSubDnNode(Dn dn, Token token) { DefaultMutableTreeNode node = new ComparableDefaultMutableTreeNode(); - String label = isKeyValueView() ? token.toString() : - token.getValue().toString(); + String label = isKeyValueView() ? token.getTokenValue() : token.getValue(); XNodeInfo userObject = - new XNodeInfo(Type.NONMBEAN, label, label, token.toString()); + new XNodeInfo(Type.NONMBEAN, label, label, token.getTokenValue()); node.setUserObject(userObject); return node; } private Object createNodeValue(XMBean xmbean, Token token) { - String label = isKeyValueView() ? token.toString() : - token.getValue().toString(); + String label = isKeyValueView() ? token.getTokenValue() : token.getValue(); xmbean.setText(label); return xmbean; } /** - * Parses MBean ObjectName comma-separated properties string and put the - * individual key/value pairs into the map. Key order in the properties + * Parses the MBean ObjectName comma-separated properties string and puts + * the individual key/value pairs into the map. Key order in the properties * string is preserved by the map. */ - private Map extractKeyValuePairs( - String properties, ObjectName mbean) { - String props = properties; - Map map = new LinkedHashMap(); + private static Map extractKeyValuePairs( + String props, ObjectName mbean) { + Map map = new LinkedHashMap(); int eq = props.indexOf("="); while (eq != -1) { String key = props.substring(0, eq); @@ -461,9 +499,9 @@ public class XTree extends JTree { * in the comma-separated key property list does not apply to the given * MBean then it will be discarded. */ - private String getKeyPropertyListString(ObjectName mbean) { + private static String getKeyPropertyListString(ObjectName mbean) { String props = mbean.getKeyPropertyListString(); - Map map = extractKeyValuePairs(props, mbean); + Map map = extractKeyValuePairs(props, mbean); StringBuilder sb = new StringBuilder(); // Add the key/value pairs to the buffer following the // key order defined by the "orderedKeyPropertyList" @@ -474,7 +512,7 @@ public class XTree extends JTree { } } // Add the remaining key/value pairs to the buffer - for (Map.Entry entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { sb.append(entry.getKey() + "=" + entry.getValue() + ","); } String orderedKeyPropertyListString = sb.toString(); @@ -483,67 +521,158 @@ public class XTree extends JTree { return orderedKeyPropertyListString; } - /** - * Builds the Dn for the given MBean. - */ - private Dn buildDn(ObjectName mbean) { - - String domain = mbean.getDomain(); - String globalDn = getKeyPropertyListString(mbean); - - Dn dn = buildDn(domain, globalDn, mbean); - - //update the Dn tokens to add the domain - dn.updateDn(); - - //reverse the Dn (from leaf to root) - dn.reverseOrder(); - - //compute the hashDn - dn.computeHashDn(); - - return dn; + // Call on EDT + public void addMetadataNodes(DefaultMutableTreeNode node) { + XMBean mbean = (XMBean) ((XNodeInfo) node.getUserObject()).getData(); + DefaultTreeModel model = (DefaultTreeModel) getModel(); + MBeanInfoNodesSwingWorker sw = + new MBeanInfoNodesSwingWorker(model, node, mbean); + if (sw != null) { + sw.execute(); + } } - /** - * Builds the Dn for the given MBean. - */ - private Dn buildDn(String domain, String globalDn, ObjectName mbean) { - Dn dn = new Dn(domain, globalDn); - String keyDn = "no_key"; - if (isTreeView()) { - String props = globalDn; - Map map = extractKeyValuePairs(props, mbean); - for (Map.Entry entry : map.entrySet()) { - dn.addToken(new Token(keyDn, - entry.getKey() + "=" + entry.getValue())); + private static class MBeanInfoNodesSwingWorker + extends SwingWorker { + + private final DefaultTreeModel model; + private final DefaultMutableTreeNode node; + private final XMBean mbean; + + public MBeanInfoNodesSwingWorker( + DefaultTreeModel model, + DefaultMutableTreeNode node, + XMBean mbean) { + this.model = model; + this.node = node; + this.mbean = mbean; + } + + @Override + public Object[] doInBackground() throws InstanceNotFoundException, + IntrospectionException, ReflectionException, IOException { + Object result[] = new Object[2]; + // Retrieve MBeanInfo for this MBean + result[0] = mbean.getMBeanInfo(); + // Check if this MBean is a notification emitter + result[1] = mbean.isBroadcaster(); + return result; + } + + @Override + protected void done() { + try { + Object result[] = get(); + MBeanInfo mbeanInfo = (MBeanInfo) result[0]; + Boolean isBroadcaster = (Boolean) result[1]; + if (mbeanInfo != null) { + addMBeanInfoNodes(model, node, mbean, mbeanInfo, isBroadcaster); + } + } catch (Exception e) { + Throwable t = Utils.getActualException(e); + if (JConsole.isDebug()) { + t.printStackTrace(); + } } - } else { - //flat view - dn.addToken(new Token(keyDn, "properties=" + globalDn)); } - return dn; - } - // - //utility objects - // + // Call on EDT + private void addMBeanInfoNodes( + DefaultTreeModel tree, DefaultMutableTreeNode node, + XMBean mbean, MBeanInfo mbeanInfo, Boolean isBroadcaster) { + MBeanAttributeInfo[] ai = mbeanInfo.getAttributes(); + MBeanOperationInfo[] oi = mbeanInfo.getOperations(); + MBeanNotificationInfo[] ni = mbeanInfo.getNotifications(); - public static class ComparableDefaultMutableTreeNode - extends DefaultMutableTreeNode - implements Comparable { - public int compareTo(DefaultMutableTreeNode node) { - return (this.toString().compareTo(node.toString())); + // Insert the Attributes/Operations/Notifications metadata nodes as + // the three first children of this MBean node. This is only useful + // when this MBean node denotes an MBean but it's not a leaf in the + // MBean tree + // + int childIndex = 0; + + // MBeanAttributeInfo node + // + if (ai != null && ai.length > 0) { + DefaultMutableTreeNode attributes = new DefaultMutableTreeNode(); + XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean, + Resources.getText("Attributes"), null); + attributes.setUserObject(attributesUO); + node.insert(attributes, childIndex++); + for (MBeanAttributeInfo mbai : ai) { + DefaultMutableTreeNode attribute = new DefaultMutableTreeNode(); + XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE, + new Object[]{mbean, mbai}, mbai.getName(), null); + attribute.setUserObject(attributeUO); + attribute.setAllowsChildren(false); + attributes.add(attribute); + } + } + // MBeanOperationInfo node + // + if (oi != null && oi.length > 0) { + DefaultMutableTreeNode operations = new DefaultMutableTreeNode(); + XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean, + Resources.getText("Operations"), null); + operations.setUserObject(operationsUO); + node.insert(operations, childIndex++); + for (MBeanOperationInfo mboi : oi) { + // Compute the operation's tool tip text: + // "operationname(param1type,param2type,...)" + // + StringBuilder sb = new StringBuilder(); + for (MBeanParameterInfo mbpi : mboi.getSignature()) { + sb.append(mbpi.getType() + ","); + } + String signature = sb.toString(); + if (signature.length() > 0) { + // Remove the trailing ',' + // + signature = signature.substring(0, signature.length() - 1); + } + String toolTipText = mboi.getName() + "(" + signature + ")"; + // Create operation node + // + DefaultMutableTreeNode operation = new DefaultMutableTreeNode(); + XNodeInfo operationUO = new XNodeInfo(Type.OPERATION, + new Object[]{mbean, mboi}, mboi.getName(), toolTipText); + operation.setUserObject(operationUO); + operation.setAllowsChildren(false); + operations.add(operation); + } + } + // MBeanNotificationInfo node + // + if (isBroadcaster != null && isBroadcaster.booleanValue()) { + DefaultMutableTreeNode notifications = new DefaultMutableTreeNode(); + XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean, + Resources.getText("Notifications"), null); + notifications.setUserObject(notificationsUO); + node.insert(notifications, childIndex++); + if (ni != null && ni.length > 0) { + for (MBeanNotificationInfo mbni : ni) { + DefaultMutableTreeNode notification = + new DefaultMutableTreeNode(); + XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION, + mbni, mbni.getName(), null); + notification.setUserObject(notificationUO); + notification.setAllowsChildren(false); + notifications.add(notification); + } + } + } + // Update tree model + // + model.reload(node); } } - // - //tree preferences + // Tree preferences // + private static boolean treeView; + private static boolean treeViewInit = false; - private boolean treeView; - private boolean treeViewInit = false; - public boolean isTreeView() { + private static boolean isTreeView() { if (!treeViewInit) { treeView = getTreeViewValue(); treeViewInit = true; @@ -551,78 +680,84 @@ public class XTree extends JTree { return treeView; } - private boolean getTreeViewValue() { - String treeView = System.getProperty("treeView"); - return ((treeView == null) ? true : !(treeView.equals("false"))); + private static boolean getTreeViewValue() { + String tv = System.getProperty("treeView"); + return ((tv == null) ? true : !(tv.equals("false"))); } - // - //MBean key-value preferences + // MBean key-value preferences // - private boolean keyValueView = Boolean.getBoolean("keyValueView"); - public boolean isKeyValueView() { + + private boolean isKeyValueView() { return keyValueView; } // - //utility classes + // Utility classes // + private static class ComparableDefaultMutableTreeNode + extends DefaultMutableTreeNode + implements Comparable { - public static class Dn { + public int compareTo(DefaultMutableTreeNode node) { + return (this.toString().compareTo(node.toString())); + } + } + private static class Dn implements Comparable { + + private ObjectName mbean; private String domain; - private String dn; + private String keyPropertyList; private String hashDn; - private ArrayList tokens = new ArrayList(); + private List tokens = new ArrayList(); - public Dn(String domain, String dn) { - this.domain = domain; - this.dn = dn; - } + public Dn(ObjectName mbean) { + this.mbean = mbean; + this.domain = mbean.getDomain(); + this.keyPropertyList = getKeyPropertyListString(mbean); - public void clearTokens() { - tokens.clear(); - } - - public void addToken(Token token) { - tokens.add(token); - } - - public void addToken(int index, Token token) { - tokens.add(index, token); - } - - public void setToken(int index, Token token) { - tokens.set(index, token); - } - - public void removeToken(int index) { - tokens.remove(index); - } - - public Token getToken(int index) { - return tokens.get(index); - } - - public void reverseOrder() { - ArrayList newOrder = new ArrayList(tokens.size()); - for (int i = tokens.size() - 1; i >= 0; i--) { - newOrder.add(tokens.get(i)); + if (isTreeView()) { + // Tree view + Map map = + extractKeyValuePairs(keyPropertyList, mbean); + for (Map.Entry entry : map.entrySet()) { + tokens.add(new Token("key", entry.getKey() + "=" + entry.getValue())); + } + } else { + // Flat view + tokens.add(new Token("key", "properties=" + keyPropertyList)); } - tokens = newOrder; + + // Add the domain as the first token in the Dn + tokens.add(0, new Token("domain", "domain=" + domain)); + + // Reverse the Dn (from leaf to root) + Collections.reverse(tokens); + + // Compute hash for Dn + computeHashDn(); } - public int size() { - return tokens.size(); + public ObjectName getObjectName() { + return mbean; } public String getDomain() { return domain; } - public String getDn() { - return dn; + public String getKeyPropertyList() { + return keyPropertyList; + } + + public Token getToken(int index) { + return tokens.get(index); + } + + public int getTokenCount() { + return tokens.size(); } public String getHashDn() { @@ -630,91 +765,51 @@ public class XTree extends JTree { } public String getHashKey(Token token) { - final int begin = getHashDn().indexOf(token.getHashToken()); - return getHashDn().substring(begin, getHashDn().length()); + final int begin = hashDn.indexOf(token.getTokenValue()); + return hashDn.substring(begin, hashDn.length()); } - public void computeHashDn() { - final StringBuilder hashDn = new StringBuilder(); - final int tokensSize = tokens.size(); - for (int i = 0; i < tokensSize; i++) { - Token token = tokens.get(i); - String hashToken = token.getHashToken(); - if (hashToken == null) { - hashToken = token.getToken() + (tokensSize - i); - token.setHashToken(hashToken); - } - hashDn.append(hashToken); - hashDn.append(","); + private void computeHashDn() { + if (tokens.isEmpty()) { + return; } - if (tokensSize > 0) { - this.hashDn = hashDn.substring(0, hashDn.length() - 1); - } else { - this.hashDn = ""; + final StringBuilder hdn = new StringBuilder(); + for (int i = 0; i < tokens.size(); i++) { + hdn.append(tokens.get(i).getTokenValue()); + hdn.append(","); } + hashDn = hdn.substring(0, hdn.length() - 1); } - /** - * Adds the domain as the first token in the Dn. - */ - public void updateDn() { - addToken(0, new Token("domain", "domain=" + getDomain())); - } - + @Override public String toString() { - return tokens.toString(); + return domain + ":" + keyPropertyList; + } + + public int compareTo(Dn dn) { + return this.toString().compareTo(dn.toString()); } } - public static class Token { + private static class Token { - private String keyDn; - private String token; - private String hashToken; + private String tokenType; + private String tokenValue; private String key; private String value; - public Token(String keyDn, String token) { - this.keyDn = keyDn; - this.token = token; + public Token(String tokenType, String tokenValue) { + this.tokenType = tokenType; + this.tokenValue = tokenValue; buildKeyValue(); } - public Token(String keyDn, String token, String hashToken) { - this.keyDn = keyDn; - this.token = token; - this.hashToken = hashToken; - buildKeyValue(); + public String getTokenType() { + return tokenType; } - public String getKeyDn() { - return keyDn; - } - - public String getToken() { - return token; - } - - public void setValue(String value) { - this.value = value; - this.token = key + "=" + value; - } - - public void setKey(String key) { - this.key = key; - this.token = key + "=" + value; - } - - public void setKeyDn(String keyDn) { - this.keyDn = keyDn; - } - - public void setHashToken(String hashToken) { - this.hashToken = hashToken; - } - - public String getHashToken() { - return hashToken; + public String getTokenValue() { + return tokenValue; } public String getKey() { @@ -725,26 +820,14 @@ public class XTree extends JTree { return value; } - public String toString(){ - return getToken(); - } - - public boolean equals(Object object) { - if (object instanceof Token) { - return token.equals(((Token) object)); - } else { - return false; - } - } - private void buildKeyValue() { - int index = token.indexOf("="); + int index = tokenValue.indexOf("="); if (index < 0) { - key = token; - value = token; + key = tokenValue; + value = tokenValue; } else { - key = token.substring(0, index); - value = token.substring(index + 1, token.length()); + key = tokenValue.substring(0, index); + value = tokenValue.substring(index + 1, tokenValue.length()); } } } From 5f387b52a10632128dd5da854e1c72915968fd16 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 23:23:47 -0700 Subject: [PATCH 115/274] 5080227: (coll spec) Bug in documentation for WeakHashMap Reviewed-by: dholmes --- jdk/src/share/classes/java/util/Hashtable.java | 2 +- jdk/src/share/classes/java/util/WeakHashMap.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java index 46ff36b4096..a91a01226fa 100644 --- a/jdk/src/share/classes/java/util/Hashtable.java +++ b/jdk/src/share/classes/java/util/Hashtable.java @@ -27,7 +27,7 @@ package java.util; import java.io.*; /** - * This class implements a hashtable, which maps keys to values. Any + * This class implements a hash table, which maps keys to values. Any * non-null object can be used as a key or as a value.

    * * To successfully store and retrieve objects from a hashtable, the diff --git a/jdk/src/share/classes/java/util/WeakHashMap.java b/jdk/src/share/classes/java/util/WeakHashMap.java index 861faa9c297..2287b7ef06c 100644 --- a/jdk/src/share/classes/java/util/WeakHashMap.java +++ b/jdk/src/share/classes/java/util/WeakHashMap.java @@ -29,7 +29,8 @@ import java.lang.ref.ReferenceQueue; /** - * A hashtable-based Map implementation with weak keys. + * Hash table based implementation of the Map interface, with + * weak keys. * An entry in a WeakHashMap will automatically be removed when * its key is no longer in ordinary use. More precisely, the presence of a * mapping for a given key will not prevent the key from being discarded by the From f8092959d4011f7e6c2a2a1b7cb1f471c7716a7c Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 23:23:47 -0700 Subject: [PATCH 116/274] 6595669: regtest LinkedBlockingQueue/OfferRemoveLoops.java fails Reviewed-by: dholmes --- .../concurrent/LinkedBlockingQueue/OfferRemoveLoops.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java b/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java index bcec477ce8d..baca8f1b0f1 100644 --- a/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java +++ b/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6316155 + * @bug 6316155 6595669 * @summary Test concurrent offer vs. remove * @author Martin Buchholz */ @@ -50,15 +50,18 @@ public class OfferRemoveLoops { private static void testQueue(final BlockingQueue q) throws Throwable { System.out.println(q.getClass()); final int count = 10000; + final long quittingTime = System.nanoTime() + 1L * 1000L * 1000L * 1000L; Thread t1 = new ControlledThread() { protected void realRun() { for (int i = 0, j = 0; i < count; i++) - while (! q.remove(String.valueOf(i))) + while (! q.remove(String.valueOf(i)) + && System.nanoTime() - quittingTime < 0) Thread.yield();}}; Thread t2 = new ControlledThread() { protected void realRun() { for (int i = 0, j = 0; i < count; i++) - while (! q.offer(String.valueOf(i))) + while (! q.offer(String.valueOf(i)) + && System.nanoTime() - quittingTime < 0) Thread.yield();}}; t1.setDaemon(true); t2.setDaemon(true); t1.start(); t2.start(); From 2ebe861fe50caeb5b236a6967cbf77db11f951fc Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 23:23:47 -0700 Subject: [PATCH 117/274] 6612102: (coll) IdentityHashMap.iterator().remove() might decrement size twice Reviewed-by: dholmes --- .../classes/java/util/IdentityHashMap.java | 5 +- jdk/test/java/util/Map/LockStep.java | 127 ++++++++++++++++++ 2 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/util/Map/LockStep.java diff --git a/jdk/src/share/classes/java/util/IdentityHashMap.java b/jdk/src/share/classes/java/util/IdentityHashMap.java index 8f0a0cd5c76..9ace500ffc4 100644 --- a/jdk/src/share/classes/java/util/IdentityHashMap.java +++ b/jdk/src/share/classes/java/util/IdentityHashMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. 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 @@ -749,7 +749,6 @@ public class IdentityHashMap expectedModCount = ++modCount; int deletedSlot = lastReturnedIndex; lastReturnedIndex = -1; - size--; // back up index to revisit new contents after deletion index = deletedSlot; indexValid = false; @@ -782,6 +781,8 @@ public class IdentityHashMap return; } + size--; + Object item; for (int i = nextKeyIndex(d, len); (item = tab[i]) != null; i = nextKeyIndex(i, len)) { diff --git a/jdk/test/java/util/Map/LockStep.java b/jdk/test/java/util/Map/LockStep.java new file mode 100644 index 00000000000..58b24e27d7b --- /dev/null +++ b/jdk/test/java/util/Map/LockStep.java @@ -0,0 +1,127 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6612102 + * @summary Test Map implementations for mutual compatibility + */ + +import java.util.*; +import java.util.concurrent.*; + +/** + * Based on the strange scenario required to reproduce + * (coll) IdentityHashMap.iterator().remove() might decrement size twice + * + * It would be good to add more "Lockstep-style" tests to this file. + */ +public class LockStep { + void mapsEqual(Map m1, Map m2) { + equal(m1, m2); + equal(m2, m1); + equal(m1.size(), m2.size()); + equal(m1.isEmpty(), m2.isEmpty()); + equal(m1.keySet(), m2.keySet()); + equal(m2.keySet(), m1.keySet()); + } + + void mapsEqual(List maps) { + Map first = maps.get(0); + for (Map map : maps) + mapsEqual(first, map); + } + + void put(List maps, Object key, Object val) { + for (Map map : maps) + map.put(key, val); + mapsEqual(maps); + } + + void removeLastTwo(List maps) { + Map first = maps.get(0); + int size = first.size(); + Iterator fit = first.keySet().iterator(); + for (int j = 0; j < size - 2; j++) + fit.next(); + Object x1 = fit.next(); + Object x2 = fit.next(); + + for (Map map : maps) { + Iterator it = map.keySet().iterator(); + while (it.hasNext()) { + Object x = it.next(); + if (x == x1 || x == x2) + it.remove(); + } + } + mapsEqual(maps); + } + + void remove(Map m, Iterator it) { + int size = m.size(); + it.remove(); + if (m.size() != size-1) + throw new Error(String.format("Incorrect size!%nmap=%s, size=%d%n", + m.toString(), m.size())); + } + + void test(String[] args) throws Throwable { + final int iterations = 100; + final Random r = new Random(); + + for (int i = 0; i < iterations; i++) { + List maps = Arrays.asList( + new Map[] { + new IdentityHashMap(11), + new HashMap(16), + new LinkedHashMap(16), + new WeakHashMap(16), + new Hashtable(16), + new TreeMap(), + new ConcurrentHashMap(16), + new ConcurrentSkipListMap() }); + + for (int j = 0; j < 10; j++) + put(maps, r.nextInt(100), r.nextInt(100)); + removeLastTwo(maps); + } + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new LockStep().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} From 017015117137bebbd539ed25428b1fddc004230c Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 10 Mar 2008 23:23:47 -0700 Subject: [PATCH 118/274] 6602600: Fast removal of cancelled scheduled thread pool tasks Reviewed-by: alanb --- .../ScheduledThreadPoolExecutor.java | 568 ++++++++++++++++-- .../BasicCancelTest.java | 113 ++++ .../ScheduledThreadPoolExecutor/Stress.java | 54 ++ 3 files changed, 685 insertions(+), 50 deletions(-) create mode 100644 jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java create mode 100644 jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java diff --git a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java index f0b1f42f2b1..58e5efcde02 100644 --- a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -35,6 +35,7 @@ package java.util.concurrent; import java.util.concurrent.atomic.*; +import java.util.concurrent.locks.*; import java.util.*; /** @@ -45,12 +46,21 @@ import java.util.*; * flexibility or capabilities of {@link ThreadPoolExecutor} (which * this class extends) are required. * - *

    Delayed tasks execute no sooner than they are enabled, but + *

    Delayed tasks execute no sooner than they are enabled, but * without any real-time guarantees about when, after they are * enabled, they will commence. Tasks scheduled for exactly the same * execution time are enabled in first-in-first-out (FIFO) order of * submission. * + *

    When a submitted task is cancelled before it is run, execution + * is suppressed. By default, such a cancelled task is not + * automatically removed from the work queue until its delay + * elapses. While this enables further inspection and monitoring, it + * may also cause unbounded retention of cancelled tasks. To avoid + * this, set {@link #setRemoveOnCancelPolicy} to {@code true}, which + * causes tasks to be immediately removed from the work queue at + * time of cancellation. + * *

    While this class inherits from {@link ThreadPoolExecutor}, a few * of the inherited tuning methods are not useful for it. In * particular, because it acts as a fixed-sized pool using @@ -111,21 +121,11 @@ public class ScheduledThreadPoolExecutor * ScheduledExecutorService methods) which are treated as * delayed tasks with a delay of zero. * - * 2. Using a custom queue (DelayedWorkQueue) based on an + * 2. Using a custom queue (DelayedWorkQueue), a variant of * unbounded DelayQueue. The lack of capacity constraint and * the fact that corePoolSize and maximumPoolSize are * effectively identical simplifies some execution mechanics - * (see delayedExecute) compared to ThreadPoolExecutor - * version. - * - * The DelayedWorkQueue class is defined below for the sake of - * ensuring that all elements are instances of - * RunnableScheduledFuture. Since DelayQueue otherwise - * requires type be Delayed, but not necessarily Runnable, and - * the workQueue requires the opposite, we need to explicitly - * define a class that requires both to ensure that users don't - * add objects that aren't RunnableScheduledFutures via - * getQueue().add() etc. + * (see delayedExecute) compared to ThreadPoolExecutor. * * 3. Supporting optional run-after-shutdown parameters, which * leads to overrides of shutdown methods to remove and cancel @@ -149,6 +149,11 @@ public class ScheduledThreadPoolExecutor */ private volatile boolean executeExistingDelayedTasksAfterShutdown = true; + /** + * True if ScheduledFutureTask.cancel should remove from queue + */ + private volatile boolean removeOnCancel = false; + /** * Sequence number to break scheduling ties, and in turn to * guarantee FIFO order among tied entries. @@ -167,8 +172,10 @@ public class ScheduledThreadPoolExecutor /** Sequence number to break ties FIFO */ private final long sequenceNumber; + /** The time the task is enabled to execute in nanoTime units */ private long time; + /** * Period in nanoseconds for repeating tasks. A positive * value indicates fixed-rate execution. A negative value @@ -180,6 +187,11 @@ public class ScheduledThreadPoolExecutor /** The actual task to be re-enqueued by reExecutePeriodic */ RunnableScheduledFuture outerTask = this; + /** + * Index into delay queue, to support faster cancellation. + */ + int heapIndex; + /** * Creates a one-shot action with given nanoTime-based trigger time. */ @@ -255,6 +267,13 @@ public class ScheduledThreadPoolExecutor time = now() - p; } + public boolean cancel(boolean mayInterruptIfRunning) { + boolean cancelled = super.cancel(mayInterruptIfRunning); + if (cancelled && removeOnCancel && heapIndex >= 0) + remove(this); + return cancelled; + } + /** * Overrides FutureTask version so as to reset/requeue if periodic. */ @@ -654,6 +673,33 @@ public class ScheduledThreadPoolExecutor return executeExistingDelayedTasksAfterShutdown; } + /** + * Sets the policy on whether cancelled tasks should be immediately + * removed from the work queue at time of cancellation. This value is + * by default {@code false}. + * + * @param value if {@code true}, remove on cancellation, else don't + * @see #getRemoveOnCancelPolicy + * @since 1.7 + */ + public void setRemoveOnCancelPolicy(boolean value) { + removeOnCancel = value; + } + + /** + * Gets the policy on whether cancelled tasks should be immediately + * removed from the work queue at time of cancellation. This value is + * by default {@code false}. + * + * @return {@code true} if cancelled tasks are immediately removed + * from the queue + * @see #setRemoveOnCancelPolicy + * @since 1.7 + */ + public boolean getRemoveOnCancelPolicy() { + return removeOnCancel; + } + /** * Initiates an orderly shutdown in which previously submitted * tasks are executed, but no new tasks will be accepted. If the @@ -707,56 +753,478 @@ public class ScheduledThreadPoolExecutor } /** - * An annoying wrapper class to convince javac to use a - * DelayQueue as a BlockingQueue + * Specialized delay queue. To mesh with TPE declarations, this + * class must be declared as a BlockingQueue even though + * it can only hold RunnableScheduledFutures. */ - private static class DelayedWorkQueue - extends AbstractCollection + static class DelayedWorkQueue extends AbstractQueue implements BlockingQueue { - private final DelayQueue dq = new DelayQueue(); - public Runnable poll() { return dq.poll(); } - public Runnable peek() { return dq.peek(); } - public Runnable take() throws InterruptedException { return dq.take(); } - public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException { - return dq.poll(timeout, unit); + /* + * A DelayedWorkQueue is based on a heap-based data structure + * like those in DelayQueue and PriorityQueue, except that + * every ScheduledFutureTask also records its index into the + * heap array. This eliminates the need to find a task upon + * cancellation, greatly speeding up removal (down from O(n) + * to O(log n)), and reducing garbage retention that would + * otherwise occur by waiting for the element to rise to top + * before clearing. But because the queue may also hold + * RunnableScheduledFutures that are not ScheduledFutureTasks, + * we are not guaranteed to have such indices available, in + * which case we fall back to linear search. (We expect that + * most tasks will not be decorated, and that the faster cases + * will be much more common.) + * + * All heap operations must record index changes -- mainly + * within siftUp and siftDown. Upon removal, a task's + * heapIndex is set to -1. Note that ScheduledFutureTasks can + * appear at most once in the queue (this need not be true for + * other kinds of tasks or work queues), so are uniquely + * identified by heapIndex. + */ + + private static final int INITIAL_CAPACITY = 16; + private RunnableScheduledFuture[] queue = + new RunnableScheduledFuture[INITIAL_CAPACITY]; + private final ReentrantLock lock = new ReentrantLock(); + private int size = 0; + + /** + * Thread designated to wait for the task at the head of the + * queue. This variant of the Leader-Follower pattern + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to + * minimize unnecessary timed waiting. When a thread becomes + * the leader, it waits only for the next delay to elapse, but + * other threads await indefinitely. The leader thread must + * signal some other thread before returning from take() or + * poll(...), unless some other thread becomes leader in the + * interim. Whenever the head of the queue is replaced with a + * task with an earlier expiration time, the leader field is + * invalidated by being reset to null, and some waiting + * thread, but not necessarily the current leader, is + * signalled. So waiting threads must be prepared to acquire + * and lose leadership while waiting. + */ + private Thread leader = null; + + /** + * Condition signalled when a newer task becomes available at the + * head of the queue or a new thread may need to become leader. + */ + private final Condition available = lock.newCondition(); + + /** + * Set f's heapIndex if it is a ScheduledFutureTask. + */ + private void setIndex(RunnableScheduledFuture f, int idx) { + if (f instanceof ScheduledFutureTask) + ((ScheduledFutureTask)f).heapIndex = idx; } - public boolean add(Runnable x) { - return dq.add((RunnableScheduledFuture)x); + /** + * Sift element added at bottom up to its heap-ordered spot. + * Call only when holding lock. + */ + private void siftUp(int k, RunnableScheduledFuture key) { + while (k > 0) { + int parent = (k - 1) >>> 1; + RunnableScheduledFuture e = queue[parent]; + if (key.compareTo(e) >= 0) + break; + queue[k] = e; + setIndex(e, k); + k = parent; + } + queue[k] = key; + setIndex(key, k); } + + /** + * Sift element added at top down to its heap-ordered spot. + * Call only when holding lock. + */ + private void siftDown(int k, RunnableScheduledFuture key) { + int half = size >>> 1; + while (k < half) { + int child = (k << 1) + 1; + RunnableScheduledFuture c = queue[child]; + int right = child + 1; + if (right < size && c.compareTo(queue[right]) > 0) + c = queue[child = right]; + if (key.compareTo(c) <= 0) + break; + queue[k] = c; + setIndex(c, k); + k = child; + } + queue[k] = key; + setIndex(key, k); + } + + /** + * Resize the heap array. Call only when holding lock. + */ + private void grow() { + int oldCapacity = queue.length; + int newCapacity = oldCapacity + (oldCapacity >> 1); // grow 50% + if (newCapacity < 0) // overflow + newCapacity = Integer.MAX_VALUE; + queue = Arrays.copyOf(queue, newCapacity); + } + + /** + * Find index of given object, or -1 if absent + */ + private int indexOf(Object x) { + if (x != null) { + if (x instanceof ScheduledFutureTask) { + int i = ((ScheduledFutureTask) x).heapIndex; + // Sanity check; x could conceivably be a + // ScheduledFutureTask from some other pool. + if (i >= 0 && i < size && queue[i] == x) + return i; + } else { + for (int i = 0; i < size; i++) + if (x.equals(queue[i])) + return i; + } + } + return -1; + } + + public boolean contains(Object x) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return indexOf(x) != -1; + } finally { + lock.unlock(); + } + } + + public boolean remove(Object x) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = indexOf(x); + if (i < 0) + return false; + + setIndex(queue[i], -1); + int s = --size; + RunnableScheduledFuture replacement = queue[s]; + queue[s] = null; + if (s != i) { + siftDown(i, replacement); + if (queue[i] == replacement) + siftUp(i, replacement); + } + return true; + } finally { + lock.unlock(); + } + } + + public int size() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return size; + } finally { + lock.unlock(); + } + } + + public boolean isEmpty() { + return size() == 0; + } + + public int remainingCapacity() { + return Integer.MAX_VALUE; + } + + public RunnableScheduledFuture peek() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return queue[0]; + } finally { + lock.unlock(); + } + } + public boolean offer(Runnable x) { - return dq.offer((RunnableScheduledFuture)x); - } - public void put(Runnable x) { - dq.put((RunnableScheduledFuture)x); - } - public boolean offer(Runnable x, long timeout, TimeUnit unit) { - return dq.offer((RunnableScheduledFuture)x, timeout, unit); + if (x == null) + throw new NullPointerException(); + RunnableScheduledFuture e = (RunnableScheduledFuture)x; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + int i = size; + if (i >= queue.length) + grow(); + size = i + 1; + if (i == 0) { + queue[0] = e; + setIndex(e, 0); + } else { + siftUp(i, e); + } + if (queue[0] == e) { + leader = null; + available.signal(); + } + } finally { + lock.unlock(); + } + return true; + } + + public void put(Runnable e) { + offer(e); + } + + public boolean add(Runnable e) { + return offer(e); + } + + public boolean offer(Runnable e, long timeout, TimeUnit unit) { + return offer(e); + } + + /** + * Performs common bookkeeping for poll and take: Replaces + * first element with last and sifts it down. Call only when + * holding lock. + * @param f the task to remove and return + */ + private RunnableScheduledFuture finishPoll(RunnableScheduledFuture f) { + int s = --size; + RunnableScheduledFuture x = queue[s]; + queue[s] = null; + if (s != 0) + siftDown(0, x); + setIndex(f, -1); + return f; + } + + public RunnableScheduledFuture poll() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first = queue[0]; + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + return null; + else + return finishPoll(first); + } finally { + lock.unlock(); + } + } + + public RunnableScheduledFuture take() throws InterruptedException { + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + RunnableScheduledFuture first = queue[0]; + if (first == null) + available.await(); + else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return finishPoll(first); + else if (leader != null) + available.await(); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + available.awaitNanos(delay); + } finally { + if (leader == thisThread) + leader = null; + } + } + } + } + } finally { + if (leader == null && queue[0] != null) + available.signal(); + lock.unlock(); + } + } + + public RunnableScheduledFuture poll(long timeout, TimeUnit unit) + throws InterruptedException { + long nanos = unit.toNanos(timeout); + final ReentrantLock lock = this.lock; + lock.lockInterruptibly(); + try { + for (;;) { + RunnableScheduledFuture first = queue[0]; + if (first == null) { + if (nanos <= 0) + return null; + else + nanos = available.awaitNanos(nanos); + } else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return finishPoll(first); + if (nanos <= 0) + return null; + if (nanos < delay || leader != null) + nanos = available.awaitNanos(nanos); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + long timeLeft = available.awaitNanos(delay); + nanos -= delay - timeLeft; + } finally { + if (leader == thisThread) + leader = null; + } + } + } + } + } finally { + if (leader == null && queue[0] != null) + available.signal(); + lock.unlock(); + } + } + + public void clear() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + for (int i = 0; i < size; i++) { + RunnableScheduledFuture t = queue[i]; + if (t != null) { + queue[i] = null; + setIndex(t, -1); + } + } + size = 0; + } finally { + lock.unlock(); + } + } + + /** + * Return and remove first element only if it is expired. + * Used only by drainTo. Call only when holding lock. + */ + private RunnableScheduledFuture pollExpired() { + RunnableScheduledFuture first = queue[0]; + if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) + return null; + return finishPoll(first); + } + + public int drainTo(Collection c) { + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first; + int n = 0; + while ((first = pollExpired()) != null) { + c.add(first); + ++n; + } + return n; + } finally { + lock.unlock(); + } } - public Runnable remove() { return dq.remove(); } - public Runnable element() { return dq.element(); } - public void clear() { dq.clear(); } - public int drainTo(Collection c) { return dq.drainTo(c); } public int drainTo(Collection c, int maxElements) { - return dq.drainTo(c, maxElements); + if (c == null) + throw new NullPointerException(); + if (c == this) + throw new IllegalArgumentException(); + if (maxElements <= 0) + return 0; + final ReentrantLock lock = this.lock; + lock.lock(); + try { + RunnableScheduledFuture first; + int n = 0; + while (n < maxElements && (first = pollExpired()) != null) { + c.add(first); + ++n; + } + return n; + } finally { + lock.unlock(); + } + } + + public Object[] toArray() { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + return Arrays.copyOf(queue, size, Object[].class); + } finally { + lock.unlock(); + } + } + + @SuppressWarnings("unchecked") + public T[] toArray(T[] a) { + final ReentrantLock lock = this.lock; + lock.lock(); + try { + if (a.length < size) + return (T[]) Arrays.copyOf(queue, size, a.getClass()); + System.arraycopy(queue, 0, a, 0, size); + if (a.length > size) + a[size] = null; + return a; + } finally { + lock.unlock(); + } } - public int remainingCapacity() { return dq.remainingCapacity(); } - public boolean remove(Object x) { return dq.remove(x); } - public boolean contains(Object x) { return dq.contains(x); } - public int size() { return dq.size(); } - public boolean isEmpty() { return dq.isEmpty(); } - public Object[] toArray() { return dq.toArray(); } - public T[] toArray(T[] array) { return dq.toArray(array); } public Iterator iterator() { - return new Iterator() { - private Iterator it = dq.iterator(); - public boolean hasNext() { return it.hasNext(); } - public Runnable next() { return it.next(); } - public void remove() { it.remove(); } - }; + return new Itr(Arrays.copyOf(queue, size)); + } + + /** + * Snapshot iterator that works off copy of underlying q array. + */ + private class Itr implements Iterator { + final RunnableScheduledFuture[] array; + int cursor = 0; // index of next element to return + int lastRet = -1; // index of last element, or -1 if no such + + Itr(RunnableScheduledFuture[] array) { + this.array = array; + } + + public boolean hasNext() { + return cursor < array.length; + } + + public Runnable next() { + if (cursor >= array.length) + throw new NoSuchElementException(); + lastRet = cursor; + return array[cursor++]; + } + + public void remove() { + if (lastRet < 0) + throw new IllegalStateException(); + DelayedWorkQueue.this.remove(array[lastRet]); + lastRet = -1; + } } } } diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java new file mode 100644 index 00000000000..0e782d1d2f6 --- /dev/null +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6602600 + * @run main/othervm -Xmx8m BasicCancelTest + * @summary Check effectiveness of RemoveOnCancelPolicy + */ + +import java.util.concurrent.*; +import java.util.Random; + +/** + * Simple timer cancellation test. Submits tasks to a scheduled executor + * service and immediately cancels them. + */ +public class BasicCancelTest { + + void checkShutdown(final ExecutorService es) { + final Runnable nop = new Runnable() {public void run() {}}; + try { + if (new Random().nextBoolean()) { + check(es.isShutdown()); + if (es instanceof ThreadPoolExecutor) + check(((ThreadPoolExecutor) es).isTerminating() + || es.isTerminated()); + THROWS(RejectedExecutionException.class, + new F(){void f(){es.execute(nop);}}); + } + } catch (Throwable t) { unexpected(t); } + } + + void checkTerminated(final ThreadPoolExecutor tpe) { + try { + checkShutdown(tpe); + check(tpe.getQueue().isEmpty()); + check(tpe.isTerminated()); + check(! tpe.isTerminating()); + equal(tpe.getActiveCount(), 0); + equal(tpe.getPoolSize(), 0); + equal(tpe.getTaskCount(), tpe.getCompletedTaskCount()); + check(tpe.awaitTermination(0, TimeUnit.SECONDS)); + } catch (Throwable t) { unexpected(t); } + } + + void test(String[] args) throws Throwable { + + final ScheduledThreadPoolExecutor pool = + new ScheduledThreadPoolExecutor(1); + + // Needed to avoid OOME + pool.setRemoveOnCancelPolicy(true); + + final long moreThanYouCanChew = Runtime.getRuntime().freeMemory() / 4; + System.out.printf("moreThanYouCanChew=%d%n", moreThanYouCanChew); + + Runnable noopTask = new Runnable() { public void run() {}}; + + for (long i = 0; i < moreThanYouCanChew; i++) + pool.schedule(noopTask, 10, TimeUnit.MINUTES).cancel(true); + + pool.shutdown(); + check(pool.awaitTermination(1L, TimeUnit.DAYS)); + checkTerminated(pool); + equal(pool.getTaskCount(), 0L); + equal(pool.getCompletedTaskCount(), 0L); + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new BasicCancelTest().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} + abstract class F {abstract void f() throws Throwable;} + void THROWS(Class k, F... fs) { + for (F f : fs) + try {f.f(); fail("Expected " + k.getName() + " not thrown");} + catch (Throwable t) { + if (k.isAssignableFrom(t.getClass())) pass(); + else unexpected(t);}} +} diff --git a/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java new file mode 100644 index 00000000000..d6095371209 --- /dev/null +++ b/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + */ + +import java.util.concurrent.*; + +/** + * This is not a regression test, but a stress benchmark test for + * 6602600: Fast removal of cancelled scheduled thread pool tasks + * + * This runs in the same wall clock time, but much reduced cpu time, + * with the changes for 6602600. + */ +public class Stress { + + public static void main(String[] args) throws Throwable { + + final CountDownLatch count = new CountDownLatch(1000); + + final ScheduledThreadPoolExecutor pool = + new ScheduledThreadPoolExecutor(100); + pool.prestartAllCoreThreads(); + + final Runnable incTask = new Runnable() { public void run() { + count.countDown(); + }}; + + pool.scheduleAtFixedRate(incTask, 0, 10, TimeUnit.MILLISECONDS); + + count.await(); + + pool.shutdown(); + pool.awaitTermination(1L, TimeUnit.DAYS); + } +} From f280870c0fef26927d89856cf449befdba68f19d Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 10 Mar 2008 23:23:47 -0700 Subject: [PATCH 119/274] 6609775: Reduce context switches in DelayQueue due to signalAll Reviewed-by: alanb --- .../java/util/concurrent/DelayQueue.java | 108 +++++++++++------- .../util/concurrent/DelayQueue/Stress.java | 61 ++++++++++ 2 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 jdk/test/java/util/concurrent/DelayQueue/Stress.java diff --git a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java index 57350dd1c3c..a815bbc9bbb 100644 --- a/jdk/src/share/classes/java/util/concurrent/DelayQueue.java +++ b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java @@ -69,9 +69,33 @@ public class DelayQueue extends AbstractQueue implements BlockingQueue { private transient final ReentrantLock lock = new ReentrantLock(); - private transient final Condition available = lock.newCondition(); private final PriorityQueue q = new PriorityQueue(); + /** + * Thread designated to wait for the element at the head of + * the queue. This variant of the Leader-Follower pattern + * (http://www.cs.wustl.edu/~schmidt/POSA/POSA2/) serves to + * minimize unnecessary timed waiting. When a thread becomes + * the leader, it waits only for the next delay to elapse, but + * other threads await indefinitely. The leader thread must + * signal some other thread before returning from take() or + * poll(...), unless some other thread becomes leader in the + * interim. Whenever the head of the queue is replaced with + * an element with an earlier expiration time, the leader + * field is invalidated by being reset to null, and some + * waiting thread, but not necessarily the current leader, is + * signalled. So waiting threads must be prepared to acquire + * and lose leadership while waiting. + */ + private Thread leader = null; + + /** + * Condition signalled when a newer element becomes available + * at the head of the queue or a new thread may need to + * become leader. + */ + private final Condition available = lock.newCondition(); + /** * Creates a new DelayQueue that is initially empty. */ @@ -111,10 +135,11 @@ public class DelayQueue extends AbstractQueue final ReentrantLock lock = this.lock; lock.lock(); try { - E first = q.peek(); q.offer(e); - if (first == null || e.compareTo(first) < 0) - available.signalAll(); + if (q.peek() == e) { + leader = null; + available.signal(); + } return true; } finally { lock.unlock(); @@ -160,13 +185,8 @@ public class DelayQueue extends AbstractQueue E first = q.peek(); if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0) return null; - else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); - return x; - } + else + return q.poll(); } finally { lock.unlock(); } @@ -185,23 +205,29 @@ public class DelayQueue extends AbstractQueue try { for (;;) { E first = q.peek(); - if (first == null) { + if (first == null) available.await(); - } else { - long delay = first.getDelay(TimeUnit.NANOSECONDS); - if (delay > 0) { - long tl = available.awaitNanos(delay); - } else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); // wake up other takers - return x; - + else { + long delay = first.getDelay(TimeUnit.NANOSECONDS); + if (delay <= 0) + return q.poll(); + else if (leader != null) + available.await(); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + available.awaitNanos(delay); + } finally { + if (leader == thisThread) + leader = null; + } } } } } finally { + if (leader == null && q.peek() != null) + available.signal(); lock.unlock(); } } @@ -230,23 +256,28 @@ public class DelayQueue extends AbstractQueue nanos = available.awaitNanos(nanos); } else { long delay = first.getDelay(TimeUnit.NANOSECONDS); - if (delay > 0) { - if (nanos <= 0) - return null; - if (delay > nanos) - delay = nanos; - long timeLeft = available.awaitNanos(delay); - nanos -= delay - timeLeft; - } else { - E x = q.poll(); - assert x != null; - if (q.size() != 0) - available.signalAll(); - return x; + if (delay <= 0) + return q.poll(); + if (nanos <= 0) + return null; + if (nanos < delay || leader != null) + nanos = available.awaitNanos(nanos); + else { + Thread thisThread = Thread.currentThread(); + leader = thisThread; + try { + long timeLeft = available.awaitNanos(delay); + nanos -= delay - timeLeft; + } finally { + if (leader == thisThread) + leader = null; + } } } } } finally { + if (leader == null && q.peek() != null) + available.signal(); lock.unlock(); } } @@ -303,8 +334,6 @@ public class DelayQueue extends AbstractQueue c.add(q.poll()); ++n; } - if (n > 0) - available.signalAll(); return n; } finally { lock.unlock(); @@ -335,8 +364,6 @@ public class DelayQueue extends AbstractQueue c.add(q.poll()); ++n; } - if (n > 0) - available.signalAll(); return n; } finally { lock.unlock(); @@ -485,6 +512,7 @@ public class DelayQueue extends AbstractQueue return cursor < array.length; } + @SuppressWarnings("unchecked") public E next() { if (cursor >= array.length) throw new NoSuchElementException(); diff --git a/jdk/test/java/util/concurrent/DelayQueue/Stress.java b/jdk/test/java/util/concurrent/DelayQueue/Stress.java new file mode 100644 index 00000000000..e225f542efd --- /dev/null +++ b/jdk/test/java/util/concurrent/DelayQueue/Stress.java @@ -0,0 +1,61 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + */ + +import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.*; + +/** + * This is not a regression test, but a stress benchmark test for + * 6609775: Reduce context switches in DelayQueue due to signalAll + * + * This runs in the same wall clock time, but much reduced cpu time, + * with the changes for 6609775. + */ +public class Stress { + + public static void main(String[] args) throws Throwable { + + final DelayQueue q = new DelayQueue(); + final long t0 = System.nanoTime(); + for (long i = 0; i < 1000; i++) { + final long expiry = t0 + i*10L*1000L*1000L; + q.add(new Delayed() { + public long getDelay(TimeUnit unit) { + return unit.convert(expiry - System.nanoTime(), + NANOSECONDS); + } + public int compareTo(Delayed x) { + long d = getDelay(NANOSECONDS) + - x.getDelay(NANOSECONDS); + return d < 0 ? -1 : d > 0 ? 1 : 0; }}); + } + + for (int i = 0; i < 300; i++) + new Thread() { public void run() { + try { + while (!q.isEmpty()) + q.poll(10L, TimeUnit.SECONDS); + } catch (Throwable t) { t.printStackTrace(); } + }}.start(); + } +} From 2bcc7a86a0c7f2d5b8c8f59c997e0e52c7f9cf19 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 10 Mar 2008 23:23:47 -0700 Subject: [PATCH 120/274] 6620549: ExecutorService#shutdown should clearly state that it does not block Reviewed-by: dholmes --- .../java/util/concurrent/ExecutorService.java | 12 ++++++++-- .../ScheduledThreadPoolExecutor.java | 24 +++++++++++++------ .../util/concurrent/ThreadPoolExecutor.java | 8 +++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/util/concurrent/ExecutorService.java b/jdk/src/share/classes/java/util/concurrent/ExecutorService.java index 36b035c33dc..6f1f5fa8551 100644 --- a/jdk/src/share/classes/java/util/concurrent/ExecutorService.java +++ b/jdk/src/share/classes/java/util/concurrent/ExecutorService.java @@ -145,6 +145,10 @@ public interface ExecutorService extends Executor { * tasks are executed, but no new tasks will be accepted. * Invocation has no additional effect if already shut down. * + *

    This method does not wait for previously submitted tasks to + * complete execution. Use {@link #awaitTermination awaitTermination} + * to do that. + * * @throws SecurityException if a security manager exists and * shutting down this ExecutorService may manipulate * threads that the caller is not permitted to modify @@ -157,8 +161,12 @@ public interface ExecutorService extends Executor { /** * Attempts to stop all actively executing tasks, halts the - * processing of waiting tasks, and returns a list of the tasks that were - * awaiting execution. + * processing of waiting tasks, and returns a list of the tasks + * that were awaiting execution. + * + *

    This method does not wait for actively executing tasks to + * terminate. Use {@link #awaitTermination awaitTermination} to + * do that. * *

    There are no guarantees beyond best-effort attempts to stop * processing actively executing tasks. For example, typical diff --git a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java index 58e5efcde02..dc7fe113f2a 100644 --- a/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java +++ b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java @@ -702,13 +702,19 @@ public class ScheduledThreadPoolExecutor /** * Initiates an orderly shutdown in which previously submitted - * tasks are executed, but no new tasks will be accepted. If the - * {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} has - * been set {@code false}, existing delayed tasks whose delays - * have not yet elapsed are cancelled. And unless the - * {@code ContinueExistingPeriodicTasksAfterShutdownPolicy} has - * been set {@code true}, future executions of existing periodic - * tasks will be cancelled. + * tasks are executed, but no new tasks will be accepted. + * Invocation has no additional effect if already shut down. + * + *

    This method does not wait for previously submitted tasks to + * complete execution. Use {@link #awaitTermination awaitTermination} + * to do that. + * + *

    If the {@code ExecuteExistingDelayedTasksAfterShutdownPolicy} + * has been set {@code false}, existing delayed tasks whose delays + * have not yet elapsed are cancelled. And unless the {@code + * ContinueExistingPeriodicTasksAfterShutdownPolicy} has been set + * {@code true}, future executions of existing periodic tasks will + * be cancelled. * * @throws SecurityException {@inheritDoc} */ @@ -721,6 +727,10 @@ public class ScheduledThreadPoolExecutor * processing of waiting tasks, and returns a list of the tasks * that were awaiting execution. * + *

    This method does not wait for actively executing tasks to + * terminate. Use {@link #awaitTermination awaitTermination} to + * do that. + * *

    There are no guarantees beyond best-effort attempts to stop * processing actively executing tasks. This implementation * cancels tasks via {@link Thread#interrupt}, so any task that diff --git a/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java index 150ceca1747..7ea1d5ab4ba 100644 --- a/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java +++ b/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java @@ -1342,6 +1342,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * tasks are executed, but no new tasks will be accepted. * Invocation has no additional effect if already shut down. * + *

    This method does not wait for previously submitted tasks to + * complete execution. Use {@link #awaitTermination awaitTermination} + * to do that. + * * @throws SecurityException {@inheritDoc} */ public void shutdown() { @@ -1364,6 +1368,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService { * that were awaiting execution. These tasks are drained (removed) * from the task queue upon return from this method. * + *

    This method does not wait for actively executing tasks to + * terminate. Use {@link #awaitTermination awaitTermination} to + * do that. + * *

    There are no guarantees beyond best-effort attempts to stop * processing actively executing tasks. This implementation * cancels tasks via {@link Thread#interrupt}, so any task that From e4f30f808482975aa0979e3b85fdb76e0ea7d969 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 10 Mar 2008 23:23:47 -0700 Subject: [PATCH 121/274] 6625723: Excessive ThreadLocal storage used by ReentrantReadWriteLock Reviewed-by: dholmes --- .../locks/ReentrantReadWriteLock.java | 187 +++++++++++++----- .../locks/ReentrantReadWriteLock/Count.java | 149 ++++++++++---- 2 files changed, 253 insertions(+), 83 deletions(-) diff --git a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java index c9280c85127..8888efb2477 100644 --- a/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -222,7 +222,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /** Inner class providing writelock */ private final ReentrantReadWriteLock.WriteLock writerLock; /** Performs all synchronization mechanics */ - private final Sync sync; + final Sync sync; /** * Creates a new {@code ReentrantReadWriteLock} with @@ -239,7 +239,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * @param fair {@code true} if this lock should use a fair ordering policy */ public ReentrantReadWriteLock(boolean fair) { - sync = (fair)? new FairSync() : new NonfairSync(); + sync = fair ? new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new WriteLock(this); } @@ -256,8 +256,8 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /* * Read vs write count extraction constants and functions. - * Lock state is logically divided into two shorts: The lower - * one representing the exclusive (writer) lock hold count, + * Lock state is logically divided into two unsigned shorts: + * The lower one representing the exclusive (writer) lock hold count, * and the upper the shared (reader) hold count. */ @@ -279,13 +279,6 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab int count; // Use id, not reference, to avoid garbage retention final long tid = Thread.currentThread().getId(); - /** Decrement if positive; return previous value */ - int tryDecrement() { - int c = count; - if (c > 0) - count = c - 1; - return c; - } } /** @@ -303,7 +296,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * The number of read locks held by current thread. * Initialized only in constructor and readObject. */ - transient ThreadLocalHoldCounter readHolds; + private transient ThreadLocalHoldCounter readHolds; /** * The hold count of the last thread to successfully acquire @@ -312,7 +305,17 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * acquire. This is non-volatile since it is just used * as a heuristic, and would be great for threads to cache. */ - transient HoldCounter cachedHoldCounter; + private transient HoldCounter cachedHoldCounter; + + /** + * firstReader is the first thread to have acquired the read lock. + * firstReaderHoldCount is firstReader's hold count. + * This allows tracking of read holds for uncontended read + * locks to be very cheap. + */ + private final static long INVALID_THREAD_ID = -1; + private transient long firstReader = INVALID_THREAD_ID; + private transient int firstReaderHoldCount; Sync() { readHolds = new ThreadLocalHoldCounter(); @@ -390,12 +393,25 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab } protected final boolean tryReleaseShared(int unused) { - HoldCounter rh = cachedHoldCounter; - Thread current = Thread.currentThread(); - if (rh == null || rh.tid != current.getId()) - rh = readHolds.get(); - if (rh.tryDecrement() <= 0) - throw new IllegalMonitorStateException(); + long tid = Thread.currentThread().getId(); + if (firstReader == tid) { + // assert firstReaderHoldCount > 0; + if (firstReaderHoldCount == 1) + firstReader = INVALID_THREAD_ID; + else + firstReaderHoldCount--; + } else { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) + rh = readHolds.get(); + int count = rh.count; + if (count <= 1) { + readHolds.remove(); + if (count <= 0) + throw unmatchedUnlockException(); + } + --rh.count; + } for (;;) { int c = getState(); int nextc = c - SHARED_UNIT; @@ -404,12 +420,16 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab } } + private IllegalMonitorStateException unmatchedUnlockException() { + return new IllegalMonitorStateException( + "attempt to unlock read lock, not locked by current thread"); + } + protected final int tryAcquireShared(int unused) { /* * Walkthrough: * 1. If write lock held by another thread, fail. - * 2. If count saturated, throw error. - * 3. Otherwise, this thread is eligible for + * 2. Otherwise, this thread is eligible for * lock wrt state, so ask if it should block * because of queue policy. If not, try * to grant by CASing state and updating count. @@ -417,23 +437,33 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * acquires, which is postponed to full version * to avoid having to check hold count in * the more typical non-reentrant case. - * 4. If step 3 fails either because thread - * apparently not eligible or CAS fails, - * chain to version with full retry loop. + * 3. If step 2 fails either because thread + * apparently not eligible or CAS fails or count + * saturated, chain to version with full retry loop. */ Thread current = Thread.currentThread(); int c = getState(); if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return -1; - if (sharedCount(c) == MAX_COUNT) - throw new Error("Maximum lock count exceeded"); + int r = sharedCount(c); if (!readerShouldBlock() && + r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - cachedHoldCounter = rh = readHolds.get(); - rh.count++; + long tid = current.getId(); + if (r == 0) { + firstReader = tid; + firstReaderHoldCount = 1; + } else if (firstReader == tid) { + firstReaderHoldCount++; + } else { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) + cachedHoldCounter = rh = readHolds.get(); + else if (rh.count == 0) + readHolds.set(rh); + rh.count++; + } return 1; } return fullTryAcquireShared(current); @@ -450,20 +480,56 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab * complicating tryAcquireShared with interactions between * retries and lazily reading hold counts. */ - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - rh = readHolds.get(); + HoldCounter rh = null; for (;;) { int c = getState(); - int w = exclusiveCount(c); - if ((w != 0 && getExclusiveOwnerThread() != current) || - ((rh.count | w) == 0 && readerShouldBlock())) - return -1; + if (exclusiveCount(c) != 0) { + if (getExclusiveOwnerThread() != current) + //if (removeNeeded) readHolds.remove(); + return -1; + // else we hold the exclusive lock; blocking here + // would cause deadlock. + } else if (readerShouldBlock()) { + // Make sure we're not acquiring read lock reentrantly + long tid = current.getId(); + if (firstReader == tid) { + // assert firstReaderHoldCount > 0; + } else { + if (rh == null) { + rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) { + rh = readHolds.get(); + if (rh.count == 0) + readHolds.remove(); + } + } + if (rh.count == 0) + return -1; + } + } if (sharedCount(c) == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { - cachedHoldCounter = rh; // cache for release - rh.count++; + long tid = current.getId(); + if (sharedCount(c) == 0) { + firstReader = tid; + firstReaderHoldCount = 1; + } else if (firstReader == tid) { + firstReaderHoldCount++; + } else { + if (rh == null) { + rh = cachedHoldCounter; + if (rh != null && rh.tid == tid) { + if (rh.count == 0) + readHolds.set(rh); + } else { + rh = readHolds.get(); + } + } else if (rh.count == 0) + readHolds.set(rh); + cachedHoldCounter = rh; // cache for release + rh.count++; + } return 1; } } @@ -472,14 +538,14 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /** * Performs tryLock for write, enabling barging in both modes. * This is identical in effect to tryAcquire except for lack - * of calls to writerShouldBlock + * of calls to writerShouldBlock. */ final boolean tryWriteLock() { Thread current = Thread.currentThread(); int c = getState(); if (c != 0) { int w = exclusiveCount(c); - if (w == 0 ||current != getExclusiveOwnerThread()) + if (w == 0 || current != getExclusiveOwnerThread()) return false; if (w == MAX_COUNT) throw new Error("Maximum lock count exceeded"); @@ -493,7 +559,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab /** * Performs tryLock for read, enabling barging in both modes. * This is identical in effect to tryAcquireShared except for - * lack of calls to readerShouldBlock + * lack of calls to readerShouldBlock. */ final boolean tryReadLock() { Thread current = Thread.currentThread(); @@ -502,13 +568,24 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return false; - if (sharedCount(c) == MAX_COUNT) + int r = sharedCount(c); + if (r == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { - HoldCounter rh = cachedHoldCounter; - if (rh == null || rh.tid != current.getId()) - cachedHoldCounter = rh = readHolds.get(); - rh.count++; + long tid = current.getId(); + if (r == 0) { + firstReader = tid; + firstReaderHoldCount = 1; + } else if (firstReader == tid) { + firstReaderHoldCount++; + } else { + HoldCounter rh = cachedHoldCounter; + if (rh == null || rh.tid != tid) + cachedHoldCounter = rh = readHolds.get(); + else if (rh.count == 0) + readHolds.set(rh); + rh.count++; + } return true; } } @@ -546,7 +623,20 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab } final int getReadHoldCount() { - return getReadLockCount() == 0? 0 : readHolds.get().count; + if (getReadLockCount() == 0) + return 0; + + long tid = Thread.currentThread().getId(); + if (firstReader == tid) + return firstReaderHoldCount; + + HoldCounter rh = cachedHoldCounter; + if (rh != null && rh.tid == tid) + return rh.count; + + int count = readHolds.get().count; + if (count == 0) readHolds.remove(); + return count; } /** @@ -557,6 +647,7 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializab throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); readHolds = new ThreadLocalHoldCounter(); + firstReader = INVALID_THREAD_ID; setState(0); // reset to unlocked state } diff --git a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java index 0e7b9e4549d..a4d78117341 100644 --- a/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java +++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. 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,21 +23,89 @@ /* * @test - * @bug 6207928 6328220 6378321 + * @bug 6207928 6328220 6378321 6625723 * @summary Recursive lock invariant sanity checks * @author Martin Buchholz */ +import java.io.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.*; // I am the Cownt, and I lahve to cownt. public class Count { - private static void realMain(String[] args) throws Throwable { - final ReentrantLock rl = new ReentrantLock(); - final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + final Random rnd = new Random(); + + void lock(Lock lock) { + try { + switch (rnd.nextInt(4)) { + case 0: lock.lock(); break; + case 1: lock.lockInterruptibly(); break; + case 2: check(lock.tryLock()); break; + case 3: check(lock.tryLock(45, TimeUnit.MINUTES)); break; + } + } catch (Throwable t) { unexpected(t); } + } + + void test(String[] args) throws Throwable { + for (boolean fair : new boolean[] { true, false }) + for (boolean serialClone : new boolean[] { true, false }) { + testReentrantLocks(fair, serialClone); + testConcurrentReadLocks(fair, serialClone); + } + } + + void testConcurrentReadLocks(final boolean fair, + final boolean serialClone) throws Throwable { + final int nThreads = 10; + final CyclicBarrier barrier = new CyclicBarrier(nThreads); + final ExecutorService es = Executors.newFixedThreadPool(nThreads); + final ReentrantReadWriteLock rwl = serialClone ? + serialClone(new ReentrantReadWriteLock(fair)) : + new ReentrantReadWriteLock(fair); + for (int i = 0; i < nThreads; i++) { + es.submit(new Runnable() { public void run() { + try { + int n = 5; + for (int i = 0; i < n; i++) { + barrier.await(); + equal(rwl.getReadHoldCount(), i); + equal(rwl.getWriteHoldCount(), 0); + check(! rwl.isWriteLocked()); + equal(rwl.getReadLockCount(), nThreads * i); + barrier.await(); + lock(rwl.readLock()); + } + for (int i = 0; i < n; i++) { + rwl.readLock().unlock(); + barrier.await(); + equal(rwl.getReadHoldCount(), n-i-1); + equal(rwl.getReadLockCount(), nThreads*(n-i-1)); + equal(rwl.getWriteHoldCount(), 0); + check(! rwl.isWriteLocked()); + barrier.await(); + } + THROWS(IllegalMonitorStateException.class, + new F(){void f(){rwl.readLock().unlock();}}, + new F(){void f(){rwl.writeLock().unlock();}}); + barrier.await(); + } catch (Throwable t) { unexpected(t); }}});} + es.shutdown(); + check(es.awaitTermination(10, TimeUnit.SECONDS)); + } + + void testReentrantLocks(final boolean fair, + final boolean serialClone) throws Throwable { + final ReentrantLock rl = serialClone ? + serialClone(new ReentrantLock(fair)) : + new ReentrantLock(fair); + final ReentrantReadWriteLock rwl = serialClone ? + serialClone(new ReentrantReadWriteLock(fair)) : + new ReentrantReadWriteLock(fair); final int depth = 10; + equal(rl.isFair(), fair); + equal(rwl.isFair(), fair); check(! rl.isLocked()); check(! rwl.isWriteLocked()); check(! rl.isHeldByCurrentThread()); @@ -50,28 +118,11 @@ public class Count { equal(rwl.getReadHoldCount(), i); equal(rwl.getWriteHoldCount(), i); equal(rwl.writeLock().getHoldCount(), i); - switch (i%4) { - case 0: - rl.lock(); - rwl.writeLock().lock(); - rwl.readLock().lock(); - break; - case 1: - rl.lockInterruptibly(); - rwl.writeLock().lockInterruptibly(); - rwl.readLock().lockInterruptibly(); - break; - case 2: - check(rl.tryLock()); - check(rwl.writeLock().tryLock()); - check(rwl.readLock().tryLock()); - break; - case 3: - check(rl.tryLock(454, TimeUnit.MILLISECONDS)); - check(rwl.writeLock().tryLock(454, TimeUnit.NANOSECONDS)); - check(rwl.readLock().tryLock(454, TimeUnit.HOURS)); - break; - } + equal(rl.isLocked(), i > 0); + equal(rwl.isWriteLocked(), i > 0); + lock(rl); + lock(rwl.writeLock()); + lock(rwl.readLock()); } for (int i = depth; i > 0; i--) { @@ -95,20 +146,48 @@ public class Count { rwl.writeLock().unlock(); rl.unlock(); } + THROWS(IllegalMonitorStateException.class, + new F(){void f(){rl.unlock();}}, + new F(){void f(){rwl.readLock().unlock();}}, + new F(){void f(){rwl.writeLock().unlock();}}); } //--------------------- Infrastructure --------------------------- - static volatile int passed = 0, failed = 0; - static void pass() {passed++;} - static void fail() {failed++; Thread.dumpStack();} - static void fail(String msg) {System.out.println(msg); fail();} - static void unexpected(Throwable t) {failed++; t.printStackTrace();} - static void check(boolean cond) {if (cond) pass(); else fail();} - static void equal(Object x, Object y) { + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { if (x == null ? y == null : x.equals(y)) pass(); else fail(x + " not equal to " + y);} public static void main(String[] args) throws Throwable { - try {realMain(args);} catch (Throwable t) {unexpected(t);} + new Count().instanceMain(args);} + void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); if (failed > 0) throw new AssertionError("Some tests failed");} + abstract class F {abstract void f() throws Throwable;} + void THROWS(Class k, F... fs) { + for (F f : fs) + try {f.f(); fail("Expected " + k.getName() + " not thrown");} + catch (Throwable t) { + if (k.isAssignableFrom(t.getClass())) pass(); + else unexpected(t);}} + + static byte[] serializedForm(Object obj) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + new ObjectOutputStream(baos).writeObject(obj); + return baos.toByteArray(); + } catch (IOException e) { throw new RuntimeException(e); }} + static Object readObject(byte[] bytes) + throws IOException, ClassNotFoundException { + InputStream is = new ByteArrayInputStream(bytes); + return new ObjectInputStream(is).readObject();} + @SuppressWarnings("unchecked") + static T serialClone(T obj) { + try { return (T) readObject(serializedForm(obj)); } + catch (Exception e) { throw new RuntimeException(e); }} } From af3cf15e6ea376954f009e0f10351a40b4b42880 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 23:23:48 -0700 Subject: [PATCH 122/274] 6633113: test/java/util/concurrent/SynchronousQueue/Fairness.java fails intermittently Reviewed-by: dholmes --- .../concurrent/SynchronousQueue/Fairness.java | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java b/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java index 2a8a35a83fe..5adb71d99f7 100644 --- a/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java +++ b/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java @@ -23,36 +23,49 @@ /* * @test - * @bug 4992438 - * @compile -source 1.5 Fairness.java - * @run main Fairness + * @bug 4992438 6633113 * @summary Checks that fairness setting is respected. */ import java.util.concurrent.*; +import java.util.concurrent.locks.*; public class Fairness { private static void testFairness(boolean fair, final BlockingQueue q) - throws Exception + throws Throwable { - for (int i = 0; i < 3; i++) { - final Integer I = new Integer(i); - new Thread() { public void run() { - try { q.put(I); } catch (Exception e) {} - }}.start(); - Thread.currentThread().sleep(100); + final ReentrantLock lock = new ReentrantLock(); + final Condition ready = lock.newCondition(); + final int threadCount = 10; + final Throwable[] badness = new Throwable[1]; + lock.lock(); + for (int i = 0; i < threadCount; i++) { + final Integer I = i; + Thread t = new Thread() { public void run() { + try { + lock.lock(); + ready.signal(); + lock.unlock(); + q.put(I); + } catch (Throwable t) { badness[0] = t; }}}; + t.start(); + ready.await(); + // Probably unnecessary, but should be bullet-proof + while (t.getState() == Thread.State.RUNNABLE) + Thread.yield(); } - for (int i = 0; i < 3; i++) { - int j = q.take().intValue(); - System.err.printf("%d%n",j); + for (int i = 0; i < threadCount; i++) { + int j = q.take(); // Non-fair queues are lifo in our implementation - if (fair ? j != i : j != 2-i) - throw new Exception("No fair!"); + if (fair ? j != i : j != threadCount - 1 - i) + throw new Error(String.format("fair=%b i=%d j=%d%n", + fair, i, j)); } + if (badness[0] != null) throw new Error(badness[0]); } - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws Throwable { testFairness(false, new SynchronousQueue()); testFairness(false, new SynchronousQueue(false)); testFairness(true, new SynchronousQueue(true)); From 95c7559bd3dc7a1f11fcf1986a6b2cbc1714e670 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 23:23:48 -0700 Subject: [PATCH 123/274] 6583872: (coll) Direct uninformed users away from Vector/Hashtable Reviewed-by: dholmes --- jdk/src/share/classes/java/util/Hashtable.java | 12 +++++++++--- jdk/src/share/classes/java/util/Vector.java | 10 +++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java index a91a01226fa..c19a6ad249a 100644 --- a/jdk/src/share/classes/java/util/Hashtable.java +++ b/jdk/src/share/classes/java/util/Hashtable.java @@ -100,9 +100,15 @@ import java.io.*; * *

    As of the Java 2 platform v1.2, this class was retrofitted to * implement the {@link Map} interface, making it a member of the - * Java - * Collections Framework. Unlike the new collection - * implementations, {@code Hashtable} is synchronized. + * + * + * Java Collections Framework. Unlike the new collection + * implementations, {@code Hashtable} is synchronized. If a + * thread-safe implementation is not needed, it is recommended to use + * {@link HashMap} in place of {@code Hashtable}. If a thread-safe + * highly-concurrent implementation is desired, then it is recommended + * to use {@link java.util.concurrent.ConcurrentHashMap} in place of + * {@code Hashtable}. * * @author Arthur van Hoff * @author Josh Bloch diff --git a/jdk/src/share/classes/java/util/Vector.java b/jdk/src/share/classes/java/util/Vector.java index 209371c538d..ce5a2982fc2 100644 --- a/jdk/src/share/classes/java/util/Vector.java +++ b/jdk/src/share/classes/java/util/Vector.java @@ -64,15 +64,15 @@ package java.util; * *

    As of the Java 2 platform v1.2, this class was retrofitted to * implement the {@link List} interface, making it a member of the - * Java - * Collections Framework. Unlike the new collection - * implementations, {@code Vector} is synchronized. + * + * Java Collections Framework. Unlike the new collection + * implementations, {@code Vector} is synchronized. If a thread-safe + * implementation is not needed, it is recommended to use {@link + * ArrayList} in place of {@code Vector}. * * @author Lee Boynton * @author Jonathan Payne * @see Collection - * @see List - * @see ArrayList * @see LinkedList * @since JDK1.0 */ From 5d9d5e3e884771c0f98aae3ab680e0a3f23efb09 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 10 Mar 2008 23:23:48 -0700 Subject: [PATCH 124/274] 6625725: (coll) modCount should not be volatile Reviewed-by: dholmes --- jdk/src/share/classes/java/util/HashMap.java | 2 +- jdk/src/share/classes/java/util/IdentityHashMap.java | 2 +- jdk/src/share/classes/java/util/WeakHashMap.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index fbb7b730a72..daebd7867fe 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -173,7 +173,7 @@ public class HashMap * rehash). This field is used to make iterators on Collection-views of * the HashMap fail-fast. (See ConcurrentModificationException). */ - transient volatile int modCount; + transient int modCount; /** * Constructs an empty HashMap with the specified initial diff --git a/jdk/src/share/classes/java/util/IdentityHashMap.java b/jdk/src/share/classes/java/util/IdentityHashMap.java index 9ace500ffc4..7e27bd76e8d 100644 --- a/jdk/src/share/classes/java/util/IdentityHashMap.java +++ b/jdk/src/share/classes/java/util/IdentityHashMap.java @@ -173,7 +173,7 @@ public class IdentityHashMap /** * The number of modifications, to support fast-fail iterators */ - private transient volatile int modCount; + private transient int modCount; /** * The next size value at which to resize (capacity * load factor). diff --git a/jdk/src/share/classes/java/util/WeakHashMap.java b/jdk/src/share/classes/java/util/WeakHashMap.java index 2287b7ef06c..bdf52c57999 100644 --- a/jdk/src/share/classes/java/util/WeakHashMap.java +++ b/jdk/src/share/classes/java/util/WeakHashMap.java @@ -182,7 +182,7 @@ public class WeakHashMap * * @see ConcurrentModificationException */ - volatile int modCount; + int modCount; @SuppressWarnings("unchecked") private Entry[] newTable(int n) { From d5b852b81db360be394ae4d68eb632d5abd03cc2 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Tue, 11 Mar 2008 14:42:35 +0000 Subject: [PATCH 125/274] 6448457: (ch) Channels.newOutputStream().write() does not write all data Reviewed-by: iris, sherman --- .../classes/java/nio/channels/Channels.java | 29 +++++-- .../nio/channels/Channels/ShortWrite.java | 83 +++++++++++++++++++ 2 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 jdk/test/java/nio/channels/Channels/ShortWrite.java diff --git a/jdk/src/share/classes/java/nio/channels/Channels.java b/jdk/src/share/classes/java/nio/channels/Channels.java index a6e8a042d57..a39bb382022 100644 --- a/jdk/src/share/classes/java/nio/channels/Channels.java +++ b/jdk/src/share/classes/java/nio/channels/Channels.java @@ -66,7 +66,27 @@ public final class Channels { private Channels() { } // No instantiation - private static int write(WritableByteChannel ch, ByteBuffer bb) + /** + * Write all remaining bytes in buffer to the given channel. + * If the channel is selectable then it must be configured blocking. + */ + private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb) + throws IOException + { + while (bb.remaining() > 0) { + int n = ch.write(bb); + if (n <= 0) + throw new RuntimeException("no bytes written"); + } + } + + /** + * Write all remaining bytes in buffer to the given channel. + * + * @throws IllegalBlockingException + * If the channel is selectable and configured non-blocking. + */ + private static void writeFully(WritableByteChannel ch, ByteBuffer bb) throws IOException { if (ch instanceof SelectableChannel) { @@ -74,14 +94,13 @@ public final class Channels { synchronized (sc.blockingLock()) { if (!sc.isBlocking()) throw new IllegalBlockingModeException(); - return ch.write(bb); + writeFullyImpl(ch, bb); } } else { - return ch.write(bb); + writeFullyImpl(ch, bb); } } - // -- Byte streams from channels -- /** @@ -148,7 +167,7 @@ public final class Channels { bb.position(off); this.bb = bb; this.bs = bs; - Channels.write(ch, bb); + Channels.writeFully(ch, bb); } public void close() throws IOException { diff --git a/jdk/test/java/nio/channels/Channels/ShortWrite.java b/jdk/test/java/nio/channels/Channels/ShortWrite.java new file mode 100644 index 00000000000..0418add7359 --- /dev/null +++ b/jdk/test/java/nio/channels/Channels/ShortWrite.java @@ -0,0 +1,83 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6448457 + * @summary Test Channels.newOutputStream returns OutputStream that handles + * short writes from the underlying channel + */ + +import java.io.OutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.util.Random; + +public class ShortWrite { + + static Random rand = new Random(); + static int bytesWritten = 0; + + public static void main(String[] args) throws IOException { + + WritableByteChannel wbc = new WritableByteChannel() { + public int write(ByteBuffer src) { + int rem = src.remaining(); + if (rem > 0) { + // short write + int n = rand.nextInt(rem) + 1; + src.position(src.position() + n); + bytesWritten += n; + return n; + } else { + return 0; + } + } + public void close() throws IOException { + throw new RuntimeException("not implemented"); + } + public boolean isOpen() { + throw new RuntimeException("not implemented"); + } + }; + + // wrap Channel with OutputStream + OutputStream out = Channels.newOutputStream(wbc); + + + // write 100, 99, 98, ... 1 + // and check that the expected number of bytes is written + int expected = 0; + byte[] buf = new byte[100]; + for (int i=0; i Date: Tue, 11 Mar 2008 14:49:53 +0000 Subject: [PATCH 126/274] 6644607: (ch) test/java/nio/channels/SocketChannel/Connect.java throws UnknownHostException Reviewed-by: chegar --- jdk/test/java/nio/channels/TestUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/nio/channels/TestUtil.java b/jdk/test/java/nio/channels/TestUtil.java index 10cc488106f..94dcb997694 100644 --- a/jdk/test/java/nio/channels/TestUtil.java +++ b/jdk/test/java/nio/channels/TestUtil.java @@ -37,7 +37,7 @@ public class TestUtil { // Test hosts used by the channels tests - change these when // executing in a different network. public static final String HOST = "javaweb.sfbay.sun.com"; - public static final String REFUSING_HOST = "jano.sfbay.sun.com"; + public static final String REFUSING_HOST = "jano1.sfbay.sun.com"; public static final String FAR_HOST = "theclub.ireland.sun.com"; public static final String UNRESOLVABLE_HOST = "blah-blah.blah-blah.blah"; From 50708126d473ff321b2bf1d3bf22c175ff4e297e Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 11 Mar 2008 11:04:40 -0700 Subject: [PATCH 127/274] 6623167: C2 crashed in StoreCMNode::Value C2 crashed in StoreCMNode::Value because n->in(MemNode::OopStore) is 0. Reviewed-by: rasbold, never --- hotspot/src/share/vm/opto/memnode.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 03f43d88595..2cfa4281c48 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1771,9 +1771,16 @@ Node *StoreCMNode::Identity( PhaseTransform *phase ) { //------------------------------Value----------------------------------------- const Type *StoreCMNode::Value( PhaseTransform *phase ) const { + // Either input is TOP ==> the result is TOP + const Type *t = phase->type( in(MemNode::Memory) ); + if( t == Type::TOP ) return Type::TOP; + t = phase->type( in(MemNode::Address) ); + if( t == Type::TOP ) return Type::TOP; + t = phase->type( in(MemNode::ValueIn) ); + if( t == Type::TOP ) return Type::TOP; // If extra input is TOP ==> the result is TOP - const Type *t1 = phase->type( in(MemNode::OopStore) ); - if( t1 == Type::TOP ) return Type::TOP; + t = phase->type( in(MemNode::OopStore) ); + if( t == Type::TOP ) return Type::TOP; return StoreNode::Value( phase ); } From 96e8bcb6aaf54d9c7d7354c800e42ccf855afd43 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 11 Mar 2008 11:25:13 -0700 Subject: [PATCH 128/274] 6667620: (Escape Analysis) fix deoptimization for scalar replaced objects Deoptimization code for reallocation and relocking scalar replaced objects has to be fixed. Reviewed-by: rasbold, never --- hotspot/src/share/vm/ci/ciInstanceKlass.cpp | 35 ++++- hotspot/src/share/vm/ci/ciInstanceKlass.hpp | 9 ++ hotspot/src/share/vm/code/debugInfo.cpp | 9 +- hotspot/src/share/vm/code/scopeDesc.cpp | 4 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 26 +++- .../src/share/vm/runtime/deoptimization.cpp | 135 ++++++++++++------ 6 files changed, 163 insertions(+), 55 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp index 375d5bf94b1..9710b8dd407 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp @@ -34,7 +34,9 @@ // ciInstanceKlass::ciInstanceKlass // // Loaded instance klass. -ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : ciKlass(h_k) { +ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) : + ciKlass(h_k), _non_static_fields(NULL) +{ assert(get_Klass()->oop_is_instance(), "wrong type"); instanceKlass* ik = get_instanceKlass(); @@ -335,6 +337,37 @@ ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) return field; } +// ------------------------------------------------------------------ +// ciInstanceKlass::non_static_fields. + +class NonStaticFieldFiller: public FieldClosure { + GrowableArray* _arr; + ciEnv* _curEnv; +public: + NonStaticFieldFiller(ciEnv* curEnv, GrowableArray* arr) : + _curEnv(curEnv), _arr(arr) + {} + void do_field(fieldDescriptor* fd) { + ciField* field = new (_curEnv->arena()) ciField(fd); + _arr->append(field); + } +}; + +GrowableArray* ciInstanceKlass::non_static_fields() { + if (_non_static_fields == NULL) { + VM_ENTRY_MARK; + ciEnv* curEnv = ciEnv::current(); + instanceKlass* ik = get_instanceKlass(); + int max_n_fields = ik->fields()->length()/instanceKlass::next_offset; + + _non_static_fields = + new (curEnv->arena()) GrowableArray(max_n_fields); + NonStaticFieldFiller filler(curEnv, _non_static_fields); + ik->do_nonstatic_fields(&filler); + } + return _non_static_fields; +} + static int sort_field_by_offset(ciField** a, ciField** b) { return (*a)->offset_in_bytes() - (*b)->offset_in_bytes(); // (no worries about 32-bit overflow...) diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp index 3a084ab410b..d52818feca7 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp @@ -46,6 +46,7 @@ private: bool _has_subklass; ciFlags _flags; jint _nonstatic_field_size; + jint _nonstatic_oop_map_size; // Lazy fields get filled in only upon request. ciInstanceKlass* _super; @@ -58,6 +59,8 @@ private: ciInstanceKlass* _implementors[implementors_limit]; jint _nof_implementors; + GrowableArray* _non_static_fields; + protected: ciInstanceKlass(KlassHandle h_k); ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain); @@ -129,6 +132,9 @@ public: jint nonstatic_field_size() { assert(is_loaded(), "must be loaded"); return _nonstatic_field_size; } + jint nonstatic_oop_map_size() { + assert(is_loaded(), "must be loaded"); + return _nonstatic_oop_map_size; } ciInstanceKlass* super(); jint nof_implementors() { assert(is_loaded(), "must be loaded"); @@ -138,6 +144,9 @@ public: ciInstanceKlass* get_canonical_holder(int offset); ciField* get_field_by_offset(int field_offset, bool is_static); + + GrowableArray* non_static_fields(); + // total number of nonstatic fields (including inherited): int nof_nonstatic_fields() { if (_nonstatic_fields == NULL) diff --git a/hotspot/src/share/vm/code/debugInfo.cpp b/hotspot/src/share/vm/code/debugInfo.cpp index 2a2e1a56369..a84cee16fab 100644 --- a/hotspot/src/share/vm/code/debugInfo.cpp +++ b/hotspot/src/share/vm/code/debugInfo.cpp @@ -47,7 +47,8 @@ ScopeValue* DebugInfoReadStream::read_object_value() { } #endif ObjectValue* result = new ObjectValue(id); - _obj_pool->append(result); + // Cache the object since an object field could reference it. + _obj_pool->push(result); result->read_object(this); return result; } @@ -56,9 +57,9 @@ ScopeValue* DebugInfoReadStream::get_cached_object() { int id = read_int(); assert(_obj_pool != NULL, "object pool does not exist"); for (int i = _obj_pool->length() - 1; i >= 0; i--) { - ObjectValue* sv = (ObjectValue*) _obj_pool->at(i); - if (sv->id() == id) { - return sv; + ObjectValue* ov = (ObjectValue*) _obj_pool->at(i); + if (ov->id() == id) { + return ov; } } ShouldNotReachHere(); diff --git a/hotspot/src/share/vm/code/scopeDesc.cpp b/hotspot/src/share/vm/code/scopeDesc.cpp index 23a7e7d8d1a..96942b2ec59 100644 --- a/hotspot/src/share/vm/code/scopeDesc.cpp +++ b/hotspot/src/share/vm/code/scopeDesc.cpp @@ -91,7 +91,9 @@ GrowableArray* ScopeDesc::decode_object_values(int decode_offset) { DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result); int length = stream->read_int(); for (int index = 0; index < length; index++) { - result->push(ScopeValue::read_from(stream)); + // Objects values are pushed to 'result' array during read so that + // object's fields could reference it (OBJECT_ID_CODE). + (void)ScopeValue::read_from(stream); } assert(result->length() == length, "inconsistent debug information"); return result; diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index a1105d49486..beeb60641c6 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -791,17 +791,39 @@ void instanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, vo } +static int compare_fields_by_offset(int* a, int* b) { + return a[0] - b[0]; +} + void instanceKlass::do_nonstatic_fields(FieldClosure* cl) { - fieldDescriptor fd; instanceKlass* super = superklass(); if (super != NULL) { super->do_nonstatic_fields(cl); } + fieldDescriptor fd; int length = fields()->length(); + // In DebugInfo nonstatic fields are sorted by offset. + int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1)); + int j = 0; for (int i = 0; i < length; i += next_offset) { fd.initialize(as_klassOop(), i); - if (!(fd.is_static())) cl->do_field(&fd); + if (!fd.is_static()) { + fields_sorted[j + 0] = fd.offset(); + fields_sorted[j + 1] = i; + j += 2; + } } + if (j > 0) { + length = j; + // _sort_Fn is defined in growableArray.hpp. + qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset); + for (int i = 0; i < length; i += 2) { + fd.initialize(as_klassOop(), fields_sorted[i + 1]); + assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields"); + cl->do_field(&fd); + } + } + FREE_C_HEAP_ARRAY(int, fields_sorted); } diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index a4c3a181a1f..444925938be 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -141,41 +141,45 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread #ifdef COMPILER2 // Reallocate the non-escaping objects and restore their fields. Then // relock objects if synchronization on them was eliminated. - if (DoEscapeAnalysis && EliminateAllocations) { - GrowableArray* objects = chunk->at(0)->scope()->objects(); - bool reallocated = false; - if (objects != NULL) { - JRT_BLOCK - reallocated = realloc_objects(thread, &deoptee, objects, THREAD); - JRT_END - } - if (reallocated) { - reassign_fields(&deoptee, &map, objects); -#ifndef PRODUCT - if (TraceDeoptimization) { - ttyLocker ttyl; - tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); - print_objects(objects); + if (DoEscapeAnalysis) { + if (EliminateAllocations) { + GrowableArray* objects = chunk->at(0)->scope()->objects(); + bool reallocated = false; + if (objects != NULL) { + JRT_BLOCK + reallocated = realloc_objects(thread, &deoptee, objects, THREAD); + JRT_END } -#endif - } - for (int i = 0; i < chunk->length(); i++) { - GrowableArray* monitors = chunk->at(i)->scope()->monitors(); - if (monitors != NULL) { - relock_objects(&deoptee, &map, monitors); + if (reallocated) { + reassign_fields(&deoptee, &map, objects); #ifndef PRODUCT if (TraceDeoptimization) { ttyLocker ttyl; - tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); - for (int j = 0; i < monitors->length(); i++) { - MonitorValue* mv = monitors->at(i); - if (mv->eliminated()) { - StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner()); - tty->print_cr(" object <" INTPTR_FORMAT "> locked", owner->get_obj()()); + tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); + print_objects(objects); + } +#endif + } + } + if (EliminateLocks) { + for (int i = 0; i < chunk->length(); i++) { + GrowableArray* monitors = chunk->at(i)->scope()->monitors(); + if (monitors != NULL) { + relock_objects(&deoptee, &map, monitors); +#ifndef PRODUCT + if (TraceDeoptimization) { + ttyLocker ttyl; + tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); + for (int j = 0; j < monitors->length(); j++) { + MonitorValue* mv = monitors->at(j); + if (mv->eliminated()) { + StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner()); + tty->print_cr(" object <" INTPTR_FORMAT "> locked", owner->get_obj()()); + } } } - } #endif + } } } } @@ -656,6 +660,7 @@ public: void do_field(fieldDescriptor* fd) { + intptr_t val; StackValue* value = StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i())); int offset = fd->offset(); @@ -669,24 +674,36 @@ public: assert(value->type() == T_INT, "Agreement."); StackValue* low = StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i)); +#ifdef _LP64 + jlong res = (jlong)low->get_int(); +#else +#ifdef SPARC + // For SPARC we have to swap high and low words. + jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int()); +#else jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); +#endif //SPARC +#endif _obj->long_field_put(offset, res); break; } - + // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. case T_INT: case T_FLOAT: // 4 bytes. assert(value->type() == T_INT, "Agreement."); - _obj->int_field_put(offset, (jint)value->get_int()); + val = value->get_int(); + _obj->int_field_put(offset, (jint)*((jint*)&val)); break; case T_SHORT: case T_CHAR: // 2 bytes assert(value->type() == T_INT, "Agreement."); - _obj->short_field_put(offset, (jshort)value->get_int()); + val = value->get_int(); + _obj->short_field_put(offset, (jshort)*((jint*)&val)); break; - case T_BOOLEAN: // 1 byte + case T_BOOLEAN: case T_BYTE: // 1 byte assert(value->type() == T_INT, "Agreement."); - _obj->bool_field_put(offset, (jboolean)value->get_int()); + val = value->get_int(); + _obj->bool_field_put(offset, (jboolean)*((jint*)&val)); break; default: @@ -698,25 +715,49 @@ public: // restore elements of an eliminated type array void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) { - StackValue* low; - jlong lval; int index = 0; + intptr_t val; for (int i = 0; i < sv->field_size(); i++) { StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i)); switch(type) { - case T_BOOLEAN: obj->bool_at_put (index, (jboolean) value->get_int()); break; - case T_BYTE: obj->byte_at_put (index, (jbyte) value->get_int()); break; - case T_CHAR: obj->char_at_put (index, (jchar) value->get_int()); break; - case T_SHORT: obj->short_at_put(index, (jshort) value->get_int()); break; - case T_INT: obj->int_at_put (index, (jint) value->get_int()); break; - case T_FLOAT: obj->float_at_put(index, (jfloat) value->get_int()); break; - case T_LONG: - case T_DOUBLE: - low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++i)); - lval = jlong_from((jint)value->get_int(), (jint)low->get_int()); - sv->value()->long_field_put(index, lval); - break; + case T_LONG: case T_DOUBLE: { + assert(value->type() == T_INT, "Agreement."); + StackValue* low = + StackValue::create_stack_value(fr, reg_map, sv->field_at(++i)); +#ifdef _LP64 + jlong res = (jlong)low->get_int(); +#else +#ifdef SPARC + // For SPARC we have to swap high and low words. + jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int()); +#else + jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); +#endif //SPARC +#endif + obj->long_at_put(index, res); + break; + } + + // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. + case T_INT: case T_FLOAT: // 4 bytes. + assert(value->type() == T_INT, "Agreement."); + val = value->get_int(); + obj->int_at_put(index, (jint)*((jint*)&val)); + break; + + case T_SHORT: case T_CHAR: // 2 bytes + assert(value->type() == T_INT, "Agreement."); + val = value->get_int(); + obj->short_at_put(index, (jshort)*((jint*)&val)); + break; + + case T_BOOLEAN: case T_BYTE: // 1 byte + assert(value->type() == T_INT, "Agreement."); + val = value->get_int(); + obj->bool_at_put(index, (jboolean)*((jint*)&val)); + break; + default: ShouldNotReachHere(); } From 4cd40a47ff918c57cb296c8cd7f4f6e52fb16e15 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 11 Mar 2008 13:14:55 -0700 Subject: [PATCH 129/274] 6307187: clean up code for -Xlint:options Introduce common code for handling one-of and any-of options Reviewed-by: mcimadamore --- .../com/sun/tools/javac/code/Lint.java | 2 +- .../com/sun/tools/javac/main/JavacOption.java | 136 ++++++++++-- .../com/sun/tools/javac/main/OptionName.java | 14 +- .../tools/javac/main/RecognizedOptions.java | 201 ++++++++---------- .../test/tools/javac/6341866/T6341866.java | 2 +- 5 files changed, 218 insertions(+), 137 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java index 78474bbaa9c..1d43d5faddc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java @@ -194,7 +194,7 @@ public class Lint return map.get(option); } - private final String option; + public final String option; }; /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java index de724c58060..d607b433553 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java @@ -28,6 +28,8 @@ package com.sun.tools.javac.main; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Collection; /** * TODO: describe com.sun.tools.javac.main.JavacOption @@ -41,19 +43,29 @@ public interface JavacOption { OptionKind getKind(); - /** Does this option take a (separate) operand? */ + /** Does this option take a (separate) operand? + * @return true if this option takes a separate operand + */ boolean hasArg(); /** Does argument string match option pattern? - * @param arg The command line argument string. + * @param arg the command line argument string + * @return true if {@code arg} matches this option */ boolean matches(String arg); - /** Process the option (with arg). Return true if error detected. + /** Process an option with an argument. + * @param options the accumulated set of analyzed options + * @param option the option to be processed + * @param arg the arg for the option to be processed + * @return true if an error was detected */ boolean process(Options options, String option, String arg); - /** Process the option (without arg). Return true if error detected. + /** Process the option with no argument. + * @param options the accumulated set of analyzed options + * @param option the option to be processed + * @return true if an error was detected */ boolean process(Options options, String option); @@ -65,6 +77,11 @@ public interface JavacOption { HIDDEN, } + enum ChoiceKind { + ONEOF, + ANYOF + } + /** This class represents an option recognized by the main program */ static class Option implements JavacOption { @@ -85,6 +102,14 @@ public interface JavacOption { */ boolean hasSuffix; + /** The kind of choices for this option, if any. + */ + ChoiceKind choiceKind; + + /** The choices for this option, if any. + */ + Collection choices; + Option(OptionName name, String argsNameKey, String descrKey) { this.name = name; this.argsNameKey = argsNameKey; @@ -92,51 +117,116 @@ public interface JavacOption { char lastChar = name.optionName.charAt(name.optionName.length()-1); hasSuffix = lastChar == ':' || lastChar == '='; } + Option(OptionName name, String descrKey) { this(name, null, descrKey); } + Option(OptionName name, String descrKey, ChoiceKind choiceKind, String... choices) { + this(name, descrKey, choiceKind, Arrays.asList(choices)); + } + + Option(OptionName name, String descrKey, ChoiceKind choiceKind, Collection choices) { + this(name, null, descrKey); + if (choiceKind == null || choices == null) + throw new NullPointerException(); + this.choiceKind = choiceKind; + this.choices = choices; + } + + @Override public String toString() { return name.optionName; } - /** Does this option take a (separate) operand? - */ public boolean hasArg() { return argsNameKey != null && !hasSuffix; } - /** Does argument string match option pattern? - * @param arg The command line argument string. - */ - public boolean matches(String arg) { - return hasSuffix ? arg.startsWith(name.optionName) : arg.equals(name.optionName); + public boolean matches(String option) { + if (!hasSuffix) + return option.equals(name.optionName); + + if (!option.startsWith(name.optionName)) + return false; + + if (choices != null) { + String arg = option.substring(name.optionName.length()); + if (choiceKind == ChoiceKind.ONEOF) + return choices.contains(arg); + else { + for (String a: arg.split(",+")) { + if (!choices.contains(a)) + return false; + } + } + } + + return true; } /** Print a line of documentation describing this option, if standard. + * @param out the stream to which to write the documentation */ void help(PrintWriter out) { String s = " " + helpSynopsis(); out.print(s); - for (int j = s.length(); j < 29; j++) out.print(" "); + for (int j = Math.min(s.length(), 28); j < 29; j++) out.print(" "); Log.printLines(out, Main.getLocalizedString(descrKey)); } + String helpSynopsis() { - return name + - (argsNameKey == null ? "" : - ((hasSuffix ? "" : " ") + - Main.getLocalizedString(argsNameKey))); + StringBuilder sb = new StringBuilder(); + sb.append(name); + if (argsNameKey == null) { + if (choices != null) { + String sep = "{"; + for (String c: choices) { + sb.append(sep); + sb.append(c); + sep = ","; + } + sb.append("}"); + } + } else { + if (!hasSuffix) + sb.append(" "); + sb.append(Main.getLocalizedString(argsNameKey)); + } + + return sb.toString(); } /** Print a line of documentation describing this option, if non-standard. + * @param out the stream to which to write the documentation */ void xhelp(PrintWriter out) {} /** Process the option (with arg). Return true if error detected. */ public boolean process(Options options, String option, String arg) { - if (options != null) + if (options != null) { + if (choices != null) { + if (choiceKind == ChoiceKind.ONEOF) { + // some clients like to see just one of option+choice set + for (String c: choices) + options.remove(option + c); + String opt = option + arg; + options.put(opt, opt); + // some clients like to see option (without trailing ":") + // set to arg + String nm = option.substring(0, option.length() - 1); + options.put(nm, arg); + } else { + // set option+word for each word in arg + for (String a: arg.split(",+")) { + String opt = option + a; + options.put(opt, opt); + } + } + } options.put(option, arg); + } return false; } @@ -163,8 +253,17 @@ public interface JavacOption { XOption(OptionName name, String descrKey) { this(name, null, descrKey); } + XOption(OptionName name, String descrKey, ChoiceKind kind, String... choices) { + super(name, descrKey, kind, choices); + } + XOption(OptionName name, String descrKey, ChoiceKind kind, Collection choices) { + super(name, descrKey, kind, choices); + } + @Override void help(PrintWriter out) {} + @Override void xhelp(PrintWriter out) { super.help(out); } + @Override public OptionKind getKind() { return OptionKind.EXTENDED; } }; @@ -177,8 +276,11 @@ public interface JavacOption { HiddenOption(OptionName name, String argsNameKey) { super(name, argsNameKey, null); } + @Override void help(PrintWriter out) {} + @Override void xhelp(PrintWriter out) {} + @Override public OptionKind getKind() { return OptionKind.HIDDEN; } }; diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java b/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java index e3cec6f714b..81d20f5b4cf 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/OptionName.java @@ -37,13 +37,9 @@ package com.sun.tools.javac.main; public enum OptionName { G("-g"), G_NONE("-g:none"), - G_CUSTOM("-g:{lines,vars,source}"), + G_CUSTOM("-g:"), XLINT("-Xlint"), - XLINT_CUSTOM("-Xlint:{" - + "all," - + "cast,deprecation,divzero,empty,unchecked,fallthrough,path,serial,finally,overrides," - + "-cast,-deprecation,-divzero,-empty,-unchecked,-fallthrough,-path,-serial,-finally,-overrides," - + "none}"), + XLINT_CUSTOM("-Xlint:"), NOWARN("-nowarn"), VERBOSE("-verbose"), DEPRECATION("-deprecation"), @@ -58,12 +54,12 @@ public enum OptionName { DJAVA_EXT_DIRS("-Djava.ext.dirs="), ENDORSEDDIRS("-endorseddirs"), DJAVA_ENDORSED_DIRS("-Djava.endorsed.dirs="), - PROC_CUSTOM("-proc:{none,only}"), + PROC("-proc:"), PROCESSOR("-processor"), PROCESSORPATH("-processorpath"), D("-d"), S("-s"), - IMPLICIT("-implicit:{none,class}"), + IMPLICIT("-implicit:"), ENCODING("-encoding"), SOURCE("-source"), TARGET("-target"), @@ -86,7 +82,7 @@ public enum OptionName { XPRINT("-Xprint"), XPRINTROUNDS("-XprintRounds"), XPRINTPROCESSORINFO("-XprintProcessorInfo"), - XPREFER("-Xprefer:{source,newer}"), + XPREFER("-Xprefer:"), O("-O"), XJCOV("-Xjcov"), XD("-XD"), diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java index b205472f61f..688459011b1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java @@ -25,21 +25,23 @@ package com.sun.tools.javac.main; +import com.sun.tools.javac.code.Lint; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.main.JavacOption.HiddenOption; import com.sun.tools.javac.main.JavacOption.Option; import com.sun.tools.javac.main.JavacOption.XOption; -import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; -import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Options; import com.sun.tools.javac.processing.JavacProcessingEnvironment; import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Collection; import java.util.EnumSet; +import java.util.LinkedHashSet; import java.util.Set; import java.util.StringTokenizer; import javax.lang.model.SourceVersion; @@ -134,7 +136,7 @@ public class RecognizedOptions { DJAVA_EXT_DIRS, ENDORSEDDIRS, DJAVA_ENDORSED_DIRS, - PROC_CUSTOM, + PROC, PROCESSOR, PROCESSORPATH, D, @@ -195,7 +197,7 @@ public class RecognizedOptions { NOWARN, VERBOSE, DEPRECATION, - PROC_CUSTOM, + PROC, PROCESSOR, IMPLICIT, SOURCE, @@ -245,79 +247,58 @@ public class RecognizedOptions { } /** - * @param out the writer to use for diagnostic output + * Get all the recognized options. + * @param helper an {@code OptionHelper} to help when processing options + * @return an array of options */ public static Option[] getAll(final OptionHelper helper) { - return new Option[]{ + return new Option[] { new Option(G, "opt.g"), new Option(G_NONE, "opt.g.none") { + @Override public boolean process(Options options, String option) { options.put("-g:", "none"); return false; } }, - new Option(G_CUSTOM, "opt.g.lines.vars.source") { - public boolean matches(String s) { - return s.startsWith("-g:"); - } - public boolean process(Options options, String option) { - String suboptions = option.substring(3); - options.put("-g:", suboptions); - // enter all the -g suboptions as "-g:suboption" - for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) { - String tok = t.nextToken(); - String opt = "-g:" + tok; - options.put(opt, opt); - } - return false; - } - }, + new Option(G_CUSTOM, "opt.g.lines.vars.source", + Option.ChoiceKind.ANYOF, "lines", "vars", "source"), new XOption(XLINT, "opt.Xlint"), - new XOption(XLINT_CUSTOM, "opt.Xlint.suboptlist") { - public boolean matches(String s) { - return s.startsWith("-Xlint:"); - } - public boolean process(Options options, String option) { - String suboptions = option.substring(7); - options.put("-Xlint:", suboptions); - // enter all the -Xlint suboptions as "-Xlint:suboption" - for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) { - String tok = t.nextToken(); - String opt = "-Xlint:" + tok; - options.put(opt, opt); - } - return false; - } - }, + new XOption(XLINT_CUSTOM, "opt.Xlint.suboptlist", + Option.ChoiceKind.ANYOF, getXLintChoices()), // -nowarn is retained for command-line backward compatibility new Option(NOWARN, "opt.nowarn") { - public boolean process(Options options, String option) { - options.put("-Xlint:none", option); - return false; - } - }, + @Override + public boolean process(Options options, String option) { + options.put("-Xlint:none", option); + return false; + } + }, new Option(VERBOSE, "opt.verbose"), // -deprecation is retained for command-line backward compatibility new Option(DEPRECATION, "opt.deprecation") { - public boolean process(Options options, String option) { - options.put("-Xlint:deprecation", option); - return false; - } - }, + @Override + public boolean process(Options options, String option) { + options.put("-Xlint:deprecation", option); + return false; + } + }, new Option(CLASSPATH, "opt.arg.path", "opt.classpath"), new Option(CP, "opt.arg.path", "opt.classpath") { + @Override public boolean process(Options options, String option, String arg) { return super.process(options, "-classpath", arg); } }, new Option(SOURCEPATH, "opt.arg.path", "opt.sourcepath"), new Option(BOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") { + @Override public boolean process(Options options, String option, String arg) { options.remove("-Xbootclasspath/p:"); options.remove("-Xbootclasspath/a:"); @@ -327,6 +308,7 @@ public class RecognizedOptions { new XOption(XBOOTCLASSPATH_PREPEND,"opt.arg.path", "opt.Xbootclasspath.p"), new XOption(XBOOTCLASSPATH_APPEND, "opt.arg.path", "opt.Xbootclasspath.a"), new XOption(XBOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") { + @Override public boolean process(Options options, String option, String arg) { options.remove("-Xbootclasspath/p:"); options.remove("-Xbootclasspath/a:"); @@ -335,48 +317,29 @@ public class RecognizedOptions { }, new Option(EXTDIRS, "opt.arg.dirs", "opt.extdirs"), new XOption(DJAVA_EXT_DIRS, "opt.arg.dirs", "opt.extdirs") { + @Override public boolean process(Options options, String option, String arg) { return super.process(options, "-extdirs", arg); } }, new Option(ENDORSEDDIRS, "opt.arg.dirs", "opt.endorseddirs"), new XOption(DJAVA_ENDORSED_DIRS, "opt.arg.dirs", "opt.endorseddirs") { + @Override public boolean process(Options options, String option, String arg) { return super.process(options, "-endorseddirs", arg); } }, - new Option(PROC_CUSTOM, "opt.proc.none.only") { - public boolean matches(String s) { - return s.equals("-proc:none") || s.equals("-proc:only"); - } - - public boolean process(Options options, String option) { - if (option.equals("-proc:none")) { - options.remove("-proc:only"); - } else { - options.remove("-proc:none"); - } - options.put(option, option); - return false; - } - }, + new Option(PROC, "opt.proc.none.only", + Option.ChoiceKind.ONEOF, "none", "only"), new Option(PROCESSOR, "opt.arg.class.list", "opt.processor"), new Option(PROCESSORPATH, "opt.arg.path", "opt.processorpath"), new Option(D, "opt.arg.directory", "opt.d"), new Option(S, "opt.arg.directory", "opt.sourceDest"), - new Option(IMPLICIT, "opt.implicit") { - public boolean matches(String s) { - return s.equals("-implicit:none") || s.equals("-implicit:class"); - } - public boolean process(Options options, String option, String operand) { - int sep = option.indexOf(":"); - options.put(option.substring(0, sep), option.substring(sep+1)); - options.put(option,option); - return false; - } - }, + new Option(IMPLICIT, "opt.implicit", + Option.ChoiceKind.ONEOF, "none", "class"), new Option(ENCODING, "opt.arg.encoding", "opt.encoding"), new Option(SOURCE, "opt.arg.release", "opt.source") { + @Override public boolean process(Options options, String option, String operand) { Source source = Source.lookup(operand); if (source == null) { @@ -387,6 +350,7 @@ public class RecognizedOptions { } }, new Option(TARGET, "opt.arg.release", "opt.target") { + @Override public boolean process(Options options, String option, String operand) { Target target = Target.lookup(operand); if (target == null) { @@ -397,54 +361,62 @@ public class RecognizedOptions { } }, new Option(VERSION, "opt.version") { + @Override public boolean process(Options options, String option) { helper.printVersion(); return super.process(options, option); } }, new HiddenOption(FULLVERSION) { + @Override public boolean process(Options options, String option) { helper.printFullVersion(); return super.process(options, option); } }, new Option(HELP, "opt.help") { + @Override public boolean process(Options options, String option) { helper.printHelp(); return super.process(options, option); } }, new Option(A, "opt.arg.key.equals.value","opt.A") { - String helpSynopsis() { - hasSuffix = true; - return super.helpSynopsis(); - } + @Override + String helpSynopsis() { + hasSuffix = true; + return super.helpSynopsis(); + } - public boolean matches(String arg) { - return arg.startsWith("-A"); - } + @Override + public boolean matches(String arg) { + return arg.startsWith("-A"); + } - public boolean hasArg() { - return false; + @Override + public boolean hasArg() { + return false; + } + // Mapping for processor options created in + // JavacProcessingEnvironment + @Override + public boolean process(Options options, String option) { + int argLength = option.length(); + if (argLength == 2) { + helper.error("err.empty.A.argument"); + return true; } - // Mapping for processor options created in - // JavacProcessingEnvironment - public boolean process(Options options, String option) { - int argLength = option.length(); - if (argLength == 2) { - helper.error("err.empty.A.argument"); - return true; - } - int sepIndex = option.indexOf('='); - String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) ); - if (!JavacProcessingEnvironment.isValidOptionName(key)) { - helper.error("err.invalid.A.key", option); - return true; - } - return process(options, option, option); + int sepIndex = option.indexOf('='); + String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) ); + if (!JavacProcessingEnvironment.isValidOptionName(key)) { + helper.error("err.invalid.A.key", option); + return true; } + return process(options, option, option); + } }, new Option(X, "opt.X") { + @Override public boolean process(Options options, String option) { helper.printXhelp(); return super.process(options, option); @@ -454,10 +426,12 @@ public class RecognizedOptions { // This option exists only for the purpose of documenting itself. // It's actually implemented by the launcher. new Option(J, "opt.arg.flag", "opt.J") { + @Override String helpSynopsis() { hasSuffix = true; return super.helpSynopsis(); } + @Override public boolean process(Options options, String option) { throw new AssertionError ("the -J flag should be caught by the launcher."); @@ -469,6 +443,7 @@ public class RecognizedOptions { // new Option("-moreinfo", "opt.moreinfo") { new HiddenOption(MOREINFO) { + @Override public boolean process(Options options, String option) { Type.moreInfo = true; return super.process(options, option); @@ -512,6 +487,7 @@ public class RecognizedOptions { // display warnings for generic unchecked operations new HiddenOption(WARNUNCHECKED) { + @Override public boolean process(Options options, String option) { options.put("-Xlint:unchecked", option); return false; @@ -521,6 +497,7 @@ public class RecognizedOptions { new XOption(XMAXERRS, "opt.arg.number", "opt.maxerrs"), new XOption(XMAXWARNS, "opt.arg.number", "opt.maxwarns"), new XOption(XSTDOUT, "opt.arg.file", "opt.Xstdout") { + @Override public boolean process(Options options, String option, String arg) { try { helper.setOut(new PrintWriter(new FileWriter(arg), true)); @@ -538,17 +515,8 @@ public class RecognizedOptions { new XOption(XPRINTPROCESSORINFO, "opt.printProcessorInfo"), - new XOption(XPREFER, "opt.prefer") { - public boolean matches(String s) { - return s.equals("-Xprefer:source") || s.equals("-Xprefer:newer"); - } - public boolean process(Options options, String option, String operand) { - int sep = option.indexOf(":"); - options.put(option.substring(0, sep), option.substring(sep+1)); - options.put(option,option); - return false; - } - }, + new XOption(XPREFER, "opt.prefer", + Option.ChoiceKind.ONEOF, "source", "newer"), /* -O is a no-op, accepted for backward compatibility. */ new HiddenOption(O), @@ -562,10 +530,12 @@ public class RecognizedOptions { */ new HiddenOption(XD) { String s; + @Override public boolean matches(String s) { this.s = s; return s.startsWith(name.optionName); } + @Override public boolean process(Options options, String option) { s = s.substring(name.optionName.length()); int eq = s.indexOf('='); @@ -586,11 +556,13 @@ public class RecognizedOptions { */ new HiddenOption(SOURCEFILE) { String s; + @Override public boolean matches(String s) { this.s = s; return s.endsWith(".java") // Java source file || SourceVersion.isName(s); // Legal type name } + @Override public boolean process(Options options, String option) { if (s.endsWith(".java") ) { File f = new File(s); @@ -612,4 +584,15 @@ public class RecognizedOptions { }; } + private static Collection getXLintChoices() { + Collection choices = new LinkedHashSet(); + choices.add("all"); + for (Lint.LintCategory c : Lint.LintCategory.values()) + choices.add(c.option); + for (Lint.LintCategory c : Lint.LintCategory.values()) + choices.add("-" + c.option); + choices.add("none"); + return choices; + } + } diff --git a/langtools/test/tools/javac/6341866/T6341866.java b/langtools/test/tools/javac/6341866/T6341866.java index 5590566d6be..4c7eafca8f8 100644 --- a/langtools/test/tools/javac/6341866/T6341866.java +++ b/langtools/test/tools/javac/6341866/T6341866.java @@ -186,7 +186,7 @@ public class T6341866 { } static void error(String msg) { - System.err.println(msg); + System.err.println("ERROR: " + msg); } static File services(Class service) { From 3bf59e9c0a92fceaef110efb9e5d29a113394e76 Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Tue, 11 Mar 2008 14:19:53 -0700 Subject: [PATCH 130/274] 6673975: Disable ZapUnusedHeapArea to reduce GC execution times of debug JVM's Mangling the unused space is having an adverse affect on testing with fastdebug builds so turn it off by default. Reviewed-by: ysr, tonyp --- hotspot/src/share/vm/runtime/globals.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 80f9541bc39..67cb3285da5 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -586,7 +586,7 @@ class CommandLineFlags { develop(bool, ZapJNIHandleArea, trueInDebug, \ "Zap freed JNI handle space with 0xFEFEFEFE") \ \ - develop(bool, ZapUnusedHeapArea, trueInDebug, \ + develop(bool, ZapUnusedHeapArea, false, \ "Zap unused heap space with 0xBAADBABE") \ \ develop(bool, PrintVMMessages, true, \ From 7434ffcbfbbf8e17afa0744e0d3e9765430cdb71 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 12 Mar 2008 09:32:38 +0800 Subject: [PATCH 131/274] 6673164: dns_fallback parse error Reviewed-by: valeriep --- .../classes/sun/security/krb5/Config.java | 9 +-- jdk/test/sun/security/krb5/DnsFallback.java | 64 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 jdk/test/sun/security/krb5/DnsFallback.java diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java index 013fd1da136..a65ec868749 100644 --- a/jdk/src/share/classes/sun/security/krb5/Config.java +++ b/jdk/src/share/classes/sun/security/krb5/Config.java @@ -1040,11 +1040,12 @@ public class Config { * Check if need to use DNS to locate Kerberos services */ public boolean useDNS(String name) { - boolean value = getDefaultBooleanValue(name, "libdefaults"); - if (value == false) { - value = getDefaultBooleanValue("dns_fallback", "libdefaults"); + String value = getDefault(name, "libdefaults"); + if (value == null) { + return getDefaultBooleanValue("dns_fallback", "libdefaults"); + } else { + return value.equalsIgnoreCase("true"); } - return value; } /** diff --git a/jdk/test/sun/security/krb5/DnsFallback.java b/jdk/test/sun/security/krb5/DnsFallback.java new file mode 100644 index 00000000000..95fbf3b165b --- /dev/null +++ b/jdk/test/sun/security/krb5/DnsFallback.java @@ -0,0 +1,64 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6673164 + * @summary dns_fallback parse error + */ + +import sun.security.krb5.*; +import java.io.*; + +public class DnsFallback { + public static void main(String[] args) throws Exception { + check("true", "true", true); + check("false", "true", false); + check("true", "false", true); + check("false", "false", false); + check("true", null, true); + check("false", null, false); + check(null, "true", true); + check(null, "false", false); + } + + static void check(String realm, String fallback, boolean output) throws Exception { + FileOutputStream fo = new FileOutputStream("dnsfallback.conf"); + StringBuffer sb = new StringBuffer(); + sb.append("[libdefaults]\n"); + if (realm != null) { + sb.append("dns_lookup_realm=" + realm + "\n"); + } + if (fallback != null) { + sb.append("dns_fallback=" + fallback + "\n"); + } + fo.write(sb.toString().getBytes()); + fo.close(); + System.setProperty("java.security.krb5.conf", "dnsfallback.conf"); + Config.refresh(); + System.out.println("Testing " + realm + ", " + fallback + ", " + output); + if (Config.getInstance().useDNS_Realm() != output) { + throw new Exception("Fail"); + } + } +} + From b64d5e42097faa1a162c5532571e5caa41cc961d Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 11 Mar 2008 19:00:38 -0700 Subject: [PATCH 132/274] 6667615: (Escape Analysis) extend MDO to cache arguments escape state Use MDO to cache arguments escape state determined by the byte code escape analyzer. Reviewed-by: never --- hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp | 124 ++++++++++++++++--- hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp | 11 ++ hotspot/src/share/vm/ci/ciMethodData.cpp | 65 +++++++++- hotspot/src/share/vm/ci/ciMethodData.hpp | 18 ++- hotspot/src/share/vm/classfile/vmSymbols.cpp | 8 +- hotspot/src/share/vm/classfile/vmSymbols.hpp | 5 +- hotspot/src/share/vm/oops/methodDataOop.cpp | 57 ++++++++- hotspot/src/share/vm/oops/methodDataOop.hpp | 47 ++++++- 8 files changed, 306 insertions(+), 29 deletions(-) diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp index 5a414028b28..8b9d0d7f31e 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp @@ -104,7 +104,7 @@ public: }; void BCEscapeAnalyzer::set_returned(ArgumentMap vars) { - for (int i = 0; i <= _arg_size; i++) { + for (int i = 0; i < _arg_size; i++) { if (vars.contains(i)) _arg_returned.set_bit(i); } @@ -112,10 +112,9 @@ void BCEscapeAnalyzer::set_returned(ArgumentMap vars) { _return_allocated = _return_allocated && vars.contains_allocated() && !(vars.contains_unknown() || vars.contains_vars()); } - // return true if any element of vars is an argument bool BCEscapeAnalyzer::is_argument(ArgumentMap vars) { - for (int i = 0; i <= _arg_size; i++) { + for (int i = 0; i < _arg_size; i++) { if (vars.contains(i)) return true; } @@ -126,7 +125,7 @@ bool BCEscapeAnalyzer::is_argument(ArgumentMap vars) { bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){ if (_conservative) return true; - for (int i = 0; i <= _arg_size; i++) { + for (int i = 0; i < _arg_size; i++) { if (vars.contains(i) && _arg_stack.at(i)) return true; } @@ -134,12 +133,13 @@ bool BCEscapeAnalyzer::is_arg_stack(ArgumentMap vars){ } void BCEscapeAnalyzer::clear_bits(ArgumentMap vars, BitMap &bm) { - for (int i = 0; i <= _arg_size; i++) { + for (int i = 0; i < _arg_size; i++) { if (vars.contains(i)) { bm.clear_bit(i); } } } + void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { clear_bits(vars, _arg_local); } @@ -155,6 +155,17 @@ void BCEscapeAnalyzer::set_dirty(ArgumentMap vars) { clear_bits(vars, _dirty); } +void BCEscapeAnalyzer::set_modified(ArgumentMap vars, int offs, int size) { + + for (int i = 0; i < _arg_size; i++) { + if (vars.contains(i)) { + set_arg_modified(i, offs, size); + } + } + if (vars.contains_unknown()) + _unknown_modified = true; +} + bool BCEscapeAnalyzer::is_recursive_call(ciMethod* callee) { for (BCEscapeAnalyzer* scope = this; scope != NULL; scope = scope->_parent) { if (scope->method() == callee) { @@ -164,6 +175,40 @@ bool BCEscapeAnalyzer::is_recursive_call(ciMethod* callee) { return false; } +bool BCEscapeAnalyzer::is_arg_modified(int arg, int offset, int size_in_bytes) { + if (offset == OFFSET_ANY) + return _arg_modified[arg] != 0; + assert(arg >= 0 && arg < _arg_size, "must be an argument."); + bool modified = false; + int l = offset / HeapWordSize; + int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize; + if (l > ARG_OFFSET_MAX) + l = ARG_OFFSET_MAX; + if (h > ARG_OFFSET_MAX+1) + h = ARG_OFFSET_MAX + 1; + for (int i = l; i < h; i++) { + modified = modified || (_arg_modified[arg] & (1 << i)) != 0; + } + return modified; +} + +void BCEscapeAnalyzer::set_arg_modified(int arg, int offset, int size_in_bytes) { + if (offset == OFFSET_ANY) { + _arg_modified[arg] = (uint) -1; + return; + } + assert(arg >= 0 && arg < _arg_size, "must be an argument."); + int l = offset / HeapWordSize; + int h = round_to(offset + size_in_bytes, HeapWordSize) / HeapWordSize; + if (l > ARG_OFFSET_MAX) + l = ARG_OFFSET_MAX; + if (h > ARG_OFFSET_MAX+1) + h = ARG_OFFSET_MAX + 1; + for (int i = l; i < h; i++) { + _arg_modified[arg] |= (1 << i); + } +} + void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder) { int i; @@ -197,6 +242,7 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* for (i = 0; i < arg_size; i++) { set_method_escape(state.raw_pop()); } + _unknown_modified = true; // assume the worst since we don't analyze the called method return; } @@ -224,6 +270,11 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* ArgumentMap arg = state.raw_pop(); if (!is_argument(arg)) continue; + for (int j = 0; j < _arg_size; j++) { + if (arg.contains(j)) { + _arg_modified[j] |= analyzer._arg_modified[i]; + } + } if (!is_arg_stack(arg)) { // arguments have already been recognized as escaping } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) { @@ -233,6 +284,7 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* set_global_escape(arg); } } + _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects(); // record dependencies if at least one parameter retained stack-allocatable if (must_record_dependencies) { @@ -250,8 +302,10 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* ArgumentMap arg = state.raw_pop(); if (!is_argument(arg)) continue; + set_modified(arg, OFFSET_ANY, type2size[T_INT]*HeapWordSize); set_global_escape(arg); } + _unknown_modified = true; // assume the worst since we don't know the called method } } @@ -421,6 +475,7 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl state.spop(); ArgumentMap arr = state.apop(); set_method_escape(arr); + set_modified(arr, OFFSET_ANY, type2size[T_INT]*HeapWordSize); break; } case Bytecodes::_lastore: @@ -430,6 +485,7 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl state.spop(); ArgumentMap arr = state.apop(); set_method_escape(arr); + set_modified(arr, OFFSET_ANY, type2size[T_LONG]*HeapWordSize); break; } case Bytecodes::_aastore: @@ -437,6 +493,7 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl set_global_escape(state.apop()); state.spop(); ArgumentMap arr = state.apop(); + set_modified(arr, OFFSET_ANY, type2size[T_OBJECT]*HeapWordSize); break; } case Bytecodes::_pop: @@ -762,6 +819,7 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl if (s.cur_bc() != Bytecodes::_putstatic) { ArgumentMap p = state.apop(); set_method_escape(p); + set_modified(p, will_link ? field->offset() : OFFSET_ANY, type2size[field_type]*HeapWordSize); } } break; @@ -872,7 +930,7 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl } void BCEscapeAnalyzer::merge_block_states(StateInfo *blockstates, ciBlock *dest, StateInfo *s_state) { - StateInfo *d_state = blockstates+dest->index(); + StateInfo *d_state = blockstates + dest->index(); int nlocals = _method->max_locals(); // exceptions may cause transfer of control to handlers in the middle of a @@ -916,6 +974,7 @@ void BCEscapeAnalyzer::merge_block_states(StateInfo *blockstates, ciBlock *dest, } for (int i = 0; i < s_state->_stack_height; i++) { ArgumentMap t; + //extra_vars |= !d_state->_vars[i] & s_state->_vars[i]; t.clear(); t = s_state->_stack[i]; t.set_difference(d_state->_stack[i]); @@ -933,7 +992,7 @@ void BCEscapeAnalyzer::iterate_blocks(Arena *arena) { int datacount = (numblocks + 1) * (stkSize + numLocals); int datasize = datacount * sizeof(ArgumentMap); - StateInfo *blockstates = (StateInfo *) arena->Amalloc(_methodBlocks->num_blocks() * sizeof(StateInfo)); + StateInfo *blockstates = (StateInfo *) arena->Amalloc(numblocks * sizeof(StateInfo)); ArgumentMap *statedata = (ArgumentMap *) arena->Amalloc(datasize); for (int i = 0; i < datacount; i++) ::new ((void*)&statedata[i]) ArgumentMap(); ArgumentMap *dp = statedata; @@ -961,33 +1020,35 @@ void BCEscapeAnalyzer::iterate_blocks(Arena *arena) { ArgumentMap allVars; // all oop arguments to method ciSignature* sig = method()->signature(); int j = 0; + ciBlock* first_blk = _methodBlocks->block_containing(0); + int fb_i = first_blk->index(); if (!method()->is_static()) { // record information for "this" - blockstates[0]._vars[j].set(j); + blockstates[fb_i]._vars[j].set(j); allVars.add(j); j++; } for (int i = 0; i < sig->count(); i++) { ciType* t = sig->type_at(i); if (!t->is_primitive_type()) { - blockstates[0]._vars[j].set(j); + blockstates[fb_i]._vars[j].set(j); allVars.add(j); } j += t->size(); } - blockstates[0]._initialized = true; + blockstates[fb_i]._initialized = true; assert(j == _arg_size, "just checking"); ArgumentMap unknown_map; unknown_map.add_unknown(); - worklist.push(_methodBlocks->block_containing(0)); + worklist.push(first_blk); while(worklist.length() > 0) { ciBlock *blk = worklist.pop(); - StateInfo *blkState = blockstates+blk->index(); + StateInfo *blkState = blockstates + blk->index(); if (blk->is_handler() || blk->is_ret_target()) { // for an exception handler or a target of a ret instruction, we assume the worst case, - // that any variable or stack slot could contain any argument + // that any variable could contain any argument for (int i = 0; i < numLocals; i++) { state._vars[i] = allVars; } @@ -997,6 +1058,7 @@ void BCEscapeAnalyzer::iterate_blocks(Arena *arena) { state._stack_height = blkState->_stack_height; } for (int i = 0; i < state._stack_height; i++) { +// ??? should this be unknown_map ??? state._stack[i] = allVars; } } else { @@ -1053,6 +1115,7 @@ vmIntrinsics::ID BCEscapeAnalyzer::known_intrinsic() { vmIntrinsics::ID iid = method()->intrinsic_id(); if (iid == vmIntrinsics::_getClass || + iid == vmIntrinsics::_fillInStackTrace || iid == vmIntrinsics::_hashCode) return iid; else @@ -1060,12 +1123,16 @@ vmIntrinsics::ID BCEscapeAnalyzer::known_intrinsic() { } bool BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) { - ArgumentMap empty; - empty.clear(); + ArgumentMap arg; + arg.clear(); switch (iid) { case vmIntrinsics::_getClass: _return_local = false; break; + case vmIntrinsics::_fillInStackTrace: + arg.set(0); // 'this' + set_returned(arg); + break; case vmIntrinsics::_hashCode: // initialized state is correct break; @@ -1109,15 +1176,21 @@ void BCEscapeAnalyzer::initialize() { _return_allocated = true; } _allocated_escapes = false; + _unknown_modified = false; } void BCEscapeAnalyzer::clear_escape_info() { ciSignature* sig = method()->signature(); int arg_count = sig->count(); ArgumentMap var; + if (!method()->is_static()) { + arg_count++; // allow for "this" + } for (int i = 0; i < arg_count; i++) { + set_arg_modified(i, OFFSET_ANY, 4); var.clear(); var.set(i); + set_modified(var, OFFSET_ANY, 4); set_global_escape(var); } _arg_local.clear(); @@ -1126,6 +1199,7 @@ void BCEscapeAnalyzer::clear_escape_info() { _return_local = false; _return_allocated = false; _allocated_escapes = true; + _unknown_modified = true; } @@ -1205,8 +1279,17 @@ void BCEscapeAnalyzer::compute_escape_info() { } else { tty->print_cr(" non-local return values"); } + tty->print(" modified args: "); + for (int i = 0; i < _arg_size; i++) { + if (_arg_modified[i] == 0) + tty->print(" 0"); + else + tty->print(" 0x%x", _arg_modified[i]); + } tty->cr(); tty->print(" flags: "); + if (_unknown_modified) + tty->print(" unknown_modified"); if (_return_allocated) tty->print(" return_allocated"); tty->cr(); @@ -1228,6 +1311,7 @@ void BCEscapeAnalyzer::compute_escape_info() { if (_arg_returned.at(i)) { methodData()->set_arg_returned(i); } + methodData()->set_arg_modified(i, _arg_modified[i]); } if (_return_local) { methodData()->set_eflag(methodDataOopDesc::return_local); @@ -1244,6 +1328,7 @@ void BCEscapeAnalyzer::read_escape_info() { _arg_local.at_put(i, methodData()->is_arg_local(i)); _arg_stack.at_put(i, methodData()->is_arg_stack(i)); _arg_returned.at_put(i, methodData()->is_arg_returned(i)); + _arg_modified[i] = methodData()->arg_modified(i); } _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); @@ -1261,6 +1346,12 @@ void BCEscapeAnalyzer::read_escape_info() { tty->print_cr(" non-local return values"); } tty->print(" modified args: "); + for (int i = 0; i < _arg_size; i++) { + if (_arg_modified[i] == 0) + tty->print(" 0"); + else + tty->print(" 0x%x", _arg_modified[i]); + } tty->cr(); } #endif @@ -1281,6 +1372,7 @@ BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) , _return_local(false) , _return_allocated(false) , _allocated_escapes(false) + , _unknown_modified(false) , _dependencies() , _parent(parent) , _level(parent == NULL ? 0 : parent->level() + 1) { @@ -1290,6 +1382,8 @@ BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) _arg_returned.clear(); _dirty.clear(); Arena* arena = CURRENT_ENV->arena(); + _arg_modified = (uint *) arena->Amalloc(_arg_size * sizeof(uint)); + Copy::zero_to_bytes(_arg_modified, _arg_size * sizeof(uint)); if (methodData() == NULL) return; diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp index 4f9802bfa51..53fe46ad88a 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp @@ -46,9 +46,12 @@ class BCEscapeAnalyzer : public ResourceObj { BitMap _arg_stack; BitMap _arg_returned; BitMap _dirty; + enum{ ARG_OFFSET_MAX = 31}; + uint *_arg_modified; bool _return_local; bool _allocated_escapes; + bool _unknown_modified; bool _return_allocated; ciObjectList _dependencies; @@ -80,6 +83,7 @@ class BCEscapeAnalyzer : public ResourceObj { void set_method_escape(ArgumentMap vars); void set_global_escape(ArgumentMap vars); void set_dirty(ArgumentMap vars); + void set_modified(ArgumentMap vars, int offs, int size); bool is_recursive_call(ciMethod* callee); void add_dependence(ciKlass *klass, ciMethod *meth); @@ -140,6 +144,13 @@ class BCEscapeAnalyzer : public ResourceObj { return !_conservative && _return_allocated && !_allocated_escapes; } + // Tracking of argument modification + + enum {OFFSET_ANY = -1}; + bool is_arg_modified(int arg, int offset, int size_in_bytes); + void set_arg_modified(int arg, int offset, int size_in_bytes); + bool has_non_arg_side_affects() { return _unknown_modified; } + // Copy dependencies from this analysis into "deps" void copy_dependencies(Dependencies *deps); }; diff --git a/hotspot/src/share/vm/ci/ciMethodData.cpp b/hotspot/src/share/vm/ci/ciMethodData.cpp index b1ee47716a7..68591961bce 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.cpp +++ b/hotspot/src/share/vm/ci/ciMethodData.cpp @@ -42,6 +42,8 @@ ciMethodData::ciMethodData(methodDataHandle h_md) : ciObject(h_md) { // Set an initial hint. Don't use set_hint_di() because // first_di() may be out of bounds if data_size is 0. _hint_di = first_di(); + // Initialize the escape information (to "don't know."); + _eflags = _arg_local = _arg_stack = _arg_returned = 0; } // ------------------------------------------------------------------ @@ -59,6 +61,8 @@ ciMethodData::ciMethodData() : ciObject() { // Set an initial hint. Don't use set_hint_di() because // first_di() may be out of bounds if data_size is 0. _hint_di = first_di(); + // Initialize the escape information (to "don't know."); + _eflags = _arg_local = _arg_stack = _arg_returned = 0; } void ciMethodData::load_data() { @@ -142,6 +146,8 @@ ciProfileData* ciMethodData::data_at(int data_index) { return new ciBranchData(data_layout); case DataLayout::multi_branch_data_tag: return new ciMultiBranchData(data_layout); + case DataLayout::arg_info_data_tag: + return new ciArgInfoData(data_layout); }; } @@ -172,6 +178,9 @@ ciProfileData* ciMethodData::bci_to_data(int bci) { _saw_free_extra_data = true; // observed an empty slot (common case) return NULL; } + if (dp->tag() == DataLayout::arg_info_data_tag) { + break; // ArgInfoData is at the end of extra data section. + } if (dp->bci() == bci) { assert(dp->tag() == DataLayout::bit_data_tag, "sane"); return new ciBitData(dp); @@ -217,8 +226,14 @@ int ciMethodData::trap_recompiled_at(ciProfileData* data) { void ciMethodData::clear_escape_info() { VM_ENTRY_MARK; methodDataOop mdo = get_methodDataOop(); - if (mdo != NULL) + if (mdo != NULL) { mdo->clear_escape_info(); + ArgInfoData *aid = arg_info(); + int arg_count = (aid == NULL) ? 0 : aid->number_of_args(); + for (int i = 0; i < arg_count; i++) { + set_arg_modified(i, 0); + } + } _eflags = _arg_local = _arg_stack = _arg_returned = 0; } @@ -231,6 +246,10 @@ void ciMethodData::update_escape_info() { mdo->set_arg_local(_arg_local); mdo->set_arg_stack(_arg_stack); mdo->set_arg_returned(_arg_returned); + int arg_count = mdo->method()->size_of_parameters(); + for (int i = 0; i < arg_count; i++) { + mdo->set_arg_modified(i, arg_modified(i)); + } } } @@ -262,6 +281,14 @@ void ciMethodData::set_arg_returned(int i) { set_nth_bit(_arg_returned, i); } +void ciMethodData::set_arg_modified(int arg, uint val) { + ArgInfoData *aid = arg_info(); + if (aid == NULL) + return; + assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number"); + aid->set_arg_modified(arg, val); +} + bool ciMethodData::is_arg_local(int i) const { return is_set_nth_bit(_arg_local, i); } @@ -274,6 +301,14 @@ bool ciMethodData::is_arg_returned(int i) const { return is_set_nth_bit(_arg_returned, i); } +uint ciMethodData::arg_modified(int arg) const { + ArgInfoData *aid = arg_info(); + if (aid == NULL) + return 0; + assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number"); + return aid->arg_modified(arg); +} + ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) { // Get offset within methodDataOop of the data array ByteSize data_offset = methodDataOopDesc::data_offset(); @@ -287,6 +322,18 @@ ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_ return in_ByteSize(offset); } +ciArgInfoData *ciMethodData::arg_info() const { + // Should be last, have to skip all traps. + DataLayout* dp = data_layout_at(data_size()); + DataLayout* end = data_layout_at(data_size() + extra_data_size()); + for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { + if (dp->tag() == DataLayout::arg_info_data_tag) + return new ciArgInfoData(dp); + } + return NULL; +} + + // Implementation of the print method. void ciMethodData::print_impl(outputStream* st) { ciObject::print_impl(st); @@ -305,6 +352,22 @@ void ciMethodData::print_data_on(outputStream* st) { st->fill_to(6); data->print_data_on(st); } + st->print_cr("--- Extra data:"); + DataLayout* dp = data_layout_at(data_size()); + DataLayout* end = data_layout_at(data_size() + extra_data_size()); + for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) { + if (dp->tag() == DataLayout::no_tag) continue; + if (dp->tag() == DataLayout::bit_data_tag) { + data = new BitData(dp); + } else { + assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo"); + data = new ciArgInfoData(dp); + dp = end; // ArgInfoData is at the end of extra data section. + } + st->print("%d", dp_to_di(data->dp())); + st->fill_to(6); + data->print_data_on(st); + } } void ciReceiverTypeData::print_receiver_data_on(outputStream* st) { diff --git a/hotspot/src/share/vm/ci/ciMethodData.hpp b/hotspot/src/share/vm/ci/ciMethodData.hpp index 7e16d2f0974..91ed83f61eb 100644 --- a/hotspot/src/share/vm/ci/ciMethodData.hpp +++ b/hotspot/src/share/vm/ci/ciMethodData.hpp @@ -30,6 +30,7 @@ class ciRetData; class ciBranchData; class ciArrayData; class ciMultiBranchData; +class ciArgInfoData; typedef ProfileData ciProfileData; @@ -121,6 +122,11 @@ public: ciMultiBranchData(DataLayout* layout) : MultiBranchData(layout) {}; }; +class ciArgInfoData : public ArgInfoData { +public: + ciArgInfoData(DataLayout* layout) : ArgInfoData(layout) {}; +}; + // ciMethodData // // This class represents a methodDataOop in the HotSpot virtual @@ -163,9 +169,9 @@ private: ciMethodData(); // Accessors - int data_size() { return _data_size; } - int extra_data_size() { return _extra_data_size; } - intptr_t * data() { return _data; } + int data_size() const { return _data_size; } + int extra_data_size() const { return _extra_data_size; } + intptr_t * data() const { return _data; } methodDataOop get_methodDataOop() const { if (handle() == NULL) return NULL; @@ -178,7 +184,7 @@ private: void print_impl(outputStream* st); - DataLayout* data_layout_at(int data_index) { + DataLayout* data_layout_at(int data_index) const { assert(data_index % sizeof(intptr_t) == 0, "unaligned"); return (DataLayout*) (((address)_data) + data_index); } @@ -207,6 +213,8 @@ private: // What is the index of the first data entry? int first_di() { return 0; } + ciArgInfoData *arg_info() const; + public: bool is_method_data() { return true; } bool is_empty() { return _state == empty_state; } @@ -270,10 +278,12 @@ public: void set_arg_local(int i); void set_arg_stack(int i); void set_arg_returned(int i); + void set_arg_modified(int arg, uint val); bool is_arg_local(int i) const; bool is_arg_stack(int i) const; bool is_arg_returned(int i) const; + uint arg_modified(int arg) const; // Code generation helper ByteSize offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data); diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp index 36ab6d9ddd0..36bab9ae5ac 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.cpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp @@ -318,6 +318,11 @@ inline bool match_F_SN(jshort flags) { const int neg = JVM_ACC_SYNCHRONIZED; return (flags & (req | neg)) == req; } +inline bool match_F_RNY(jshort flags) { + const int req = JVM_ACC_NATIVE | JVM_ACC_SYNCHRONIZED; + const int neg = JVM_ACC_STATIC; + return (flags & (req | neg)) == req; +} // These are for forming case labels: #define ID3(x, y, z) (( jint)(z) + \ @@ -359,6 +364,7 @@ const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, case F_RN: fname = "native "; break; case F_SN: fname = "native static "; break; case F_S: fname = "static "; break; + case F_RNY:fname = "native synchronized "; break; } const char* kptr = strrchr(kname, '/'); if (kptr != NULL) kname = kptr + 1; @@ -485,7 +491,7 @@ void vmIntrinsics::verify_method(ID actual_id, methodOop m) { if (PrintMiscellaneous && (WizardMode || Verbose)) { tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):", declared_name, declared_id, actual_name, actual_id); - m->print_short_name(tty); + mh()->print_short_name(tty); tty->cr(); } } diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 75e7f1860d6..00a131f4e97 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -584,6 +584,8 @@ do_name( attemptUpdate_name, "attemptUpdate") \ do_signature(attemptUpdate_signature, "(JJ)Z") \ \ + do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \ + \ /* support for sun.misc.Unsafe */ \ do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \ \ @@ -871,7 +873,8 @@ class vmIntrinsics: AllStatic { F_R, // !static !synchronized (R="regular") F_S, // static !synchronized F_RN, // !static native !synchronized - F_SN // static native !synchronized + F_SN, // static native !synchronized + F_RNY // !static native synchronized }; public: diff --git a/hotspot/src/share/vm/oops/methodDataOop.cpp b/hotspot/src/share/vm/oops/methodDataOop.cpp index f149335940a..77f10e0587d 100644 --- a/hotspot/src/share/vm/oops/methodDataOop.cpp +++ b/hotspot/src/share/vm/oops/methodDataOop.cpp @@ -32,7 +32,7 @@ // Some types of data layouts need a length field. bool DataLayout::needs_array_len(u1 tag) { - return (tag == multi_branch_data_tag); + return (tag == multi_branch_data_tag) || (tag == arg_info_data_tag); } // Perform generic initialization of the data. More specific @@ -404,6 +404,17 @@ void MultiBranchData::print_data_on(outputStream* st) { } #endif +#ifndef PRODUCT +void ArgInfoData::print_data_on(outputStream* st) { + print_shared(st, "ArgInfoData"); + int nargs = number_of_args(); + for (int i = 0; i < nargs; i++) { + st->print(" 0x%x", arg_modified(i)); + } + st->cr(); +} + +#endif // ================================================================== // methodDataOop // @@ -508,6 +519,9 @@ int methodDataOopDesc::compute_allocation_size_in_bytes(methodHandle method) { int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); + // Add a cell to record information about modified arguments. + int arg_size = method->size_of_parameters(); + object_size += DataLayout::compute_size_in_bytes(arg_size+1); return object_size; } @@ -626,6 +640,8 @@ ProfileData* methodDataOopDesc::data_at(int data_index) { return new BranchData(data_layout); case DataLayout::multi_branch_data_tag: return new MultiBranchData(data_layout); + case DataLayout::arg_info_data_tag: + return new ArgInfoData(data_layout); }; } @@ -681,7 +697,17 @@ void methodDataOopDesc::initialize(methodHandle method) { // Add some extra DataLayout cells (at least one) to track stray traps. int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); - object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); + int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0); + + // Add a cell to record information about modified arguments. + // Set up _args_modified array after traps cells so that + // the code for traps cells works. + DataLayout *dp = data_layout_at(data_size + extra_size); + + int arg_size = method->size_of_parameters(); + dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1); + + object_size += extra_size + DataLayout::compute_size_in_bytes(arg_size+1); // Set an initial hint. Don't use set_hint_di() because // first_di() may be out of bounds if data_size is 0. @@ -764,6 +790,10 @@ ProfileData* methodDataOopDesc::bci_to_extra_data(int bci, bool create_if_missin // No need for "OrderAccess::load_acquire" ops, // since the data structure is monotonic. if (dp->tag() == DataLayout::no_tag) break; + if (dp->tag() == DataLayout::arg_info_data_tag) { + dp = end; // ArgInfoData is at the end of extra data section. + break; + } if (dp->bci() == bci) { assert(dp->tag() == DataLayout::bit_data_tag, "sane"); return new BitData(dp); @@ -785,6 +815,16 @@ ProfileData* methodDataOopDesc::bci_to_extra_data(int bci, bool create_if_missin return NULL; } +ArgInfoData *methodDataOopDesc::arg_info() { + DataLayout* dp = extra_data_base(); + DataLayout* end = extra_data_limit(); + for (; dp < end; dp = next_extra(dp)) { + if (dp->tag() == DataLayout::arg_info_data_tag) + return new ArgInfoData(dp); + } + return NULL; +} + #ifndef PRODUCT void methodDataOopDesc::print_data_on(outputStream* st) { ResourceMark rm; @@ -794,15 +834,20 @@ void methodDataOopDesc::print_data_on(outputStream* st) { st->fill_to(6); data->print_data_on(st); } + st->print_cr("--- Extra data:"); DataLayout* dp = extra_data_base(); DataLayout* end = extra_data_limit(); for (; dp < end; dp = next_extra(dp)) { // No need for "OrderAccess::load_acquire" ops, // since the data structure is monotonic. - if (dp->tag() == DataLayout::no_tag) break; - if (dp == extra_data_base()) - st->print_cr("--- Extra data:"); - data = new BitData(dp); + if (dp->tag() == DataLayout::no_tag) continue; + if (dp->tag() == DataLayout::bit_data_tag) { + data = new BitData(dp); + } else { + assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo"); + data = new ArgInfoData(dp); + dp = end; // ArgInfoData is at the end of extra data section. + } st->print("%d", dp_to_di(data->dp())); st->fill_to(6); data->print_data_on(st); diff --git a/hotspot/src/share/vm/oops/methodDataOop.hpp b/hotspot/src/share/vm/oops/methodDataOop.hpp index 2896a1410aa..bcc1ac27eca 100644 --- a/hotspot/src/share/vm/oops/methodDataOop.hpp +++ b/hotspot/src/share/vm/oops/methodDataOop.hpp @@ -101,7 +101,8 @@ public: virtual_call_data_tag, ret_data_tag, branch_data_tag, - multi_branch_data_tag + multi_branch_data_tag, + arg_info_data_tag }; enum { @@ -245,6 +246,7 @@ class JumpData; class BranchData; class ArrayData; class MultiBranchData; +class ArgInfoData; // ProfileData @@ -376,6 +378,8 @@ public: virtual bool is_BranchData() { return false; } virtual bool is_ArrayData() { return false; } virtual bool is_MultiBranchData() { return false; } + virtual bool is_ArgInfoData() { return false; } + BitData* as_BitData() { assert(is_BitData(), "wrong type"); @@ -413,6 +417,10 @@ public: assert(is_MultiBranchData(), "wrong type"); return is_MultiBranchData() ? (MultiBranchData*)this : NULL; } + ArgInfoData* as_ArgInfoData() { + assert(is_ArgInfoData(), "wrong type"); + return is_ArgInfoData() ? (ArgInfoData*)this : NULL; + } // Subclass specific initialization @@ -1047,6 +1055,33 @@ public: #endif }; +class ArgInfoData : public ArrayData { + +public: + ArgInfoData(DataLayout* layout) : ArrayData(layout) { + assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type"); + } + + virtual bool is_ArgInfoData() { return true; } + + + int number_of_args() { + return array_len(); + } + + uint arg_modified(int arg) { + return array_uint_at(arg); + } + + void set_arg_modified(int arg, uint val) { + array_set_int_at(arg, val); + } + +#ifndef PRODUCT + void print_data_on(outputStream* st); +#endif +}; + // methodDataOop // // A methodDataOop holds information which has been collected about @@ -1183,6 +1218,9 @@ private: // Find or create an extra ProfileData: ProfileData* bci_to_extra_data(int bci, bool create_if_missing); + // return the argument info cell + ArgInfoData *arg_info(); + public: static int header_size() { return sizeof(methodDataOopDesc)/wordSize; @@ -1222,11 +1260,18 @@ public: intx arg_local() { return _arg_local; } intx arg_stack() { return _arg_stack; } intx arg_returned() { return _arg_returned; } + uint arg_modified(int a) { ArgInfoData *aid = arg_info(); + assert(a >= 0 && a < aid->number_of_args(), "valid argument number"); + return aid->arg_modified(a); } void set_eflags(intx v) { _eflags = v; } void set_arg_local(intx v) { _arg_local = v; } void set_arg_stack(intx v) { _arg_stack = v; } void set_arg_returned(intx v) { _arg_returned = v; } + void set_arg_modified(int a, uint v) { ArgInfoData *aid = arg_info(); + assert(a >= 0 && a < aid->number_of_args(), "valid argument number"); + + aid->set_arg_modified(a, v); } void clear_escape_info() { _eflags = _arg_local = _arg_stack = _arg_returned = 0; } From 7dbe0828dec2e6c38f9e9b6d68dd5e65d6d2aa83 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 12 Mar 2008 13:06:00 -0700 Subject: [PATCH 133/274] 6668794: javac puts localized text in raw diagnostics 6668796: bad diagnostic "bad class file" given for source files Replace internal use of localized text with JCDiagnostic fragments; fix diagnostic for bad source file Reviewed-by: mcimadamore --- .../com/sun/tools/javac/code/Symbol.java | 32 +++++-- .../com/sun/tools/javac/comp/Check.java | 2 +- .../com/sun/tools/javac/jvm/ClassReader.java | 40 +++++---- .../sun/tools/javac/main/JavaCompiler.java | 23 +++-- .../JavacProcessingEnvironment.java | 2 +- .../tools/javac/resources/compiler.properties | 4 + .../test/tools/javac/6668794/badClass/A.java | 28 ++++++ .../test/tools/javac/6668794/badClass/B.java | 7 ++ .../tools/javac/6668794/badClass/Test.java | 88 +++++++++++++++++++ .../tools/javac/6668794/badSource/Test.java | 11 +++ .../tools/javac/6668794/badSource/Test.out | 1 + .../tools/javac/6668794/badSource/p/A.java | 28 ++++++ 12 files changed, 233 insertions(+), 33 deletions(-) create mode 100644 langtools/test/tools/javac/6668794/badClass/A.java create mode 100644 langtools/test/tools/javac/6668794/badClass/B.java create mode 100644 langtools/test/tools/javac/6668794/badClass/Test.java create mode 100644 langtools/test/tools/javac/6668794/badSource/Test.java create mode 100644 langtools/test/tools/javac/6668794/badSource/Test.out create mode 100644 langtools/test/tools/javac/6668794/badSource/p/A.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 86f0e5f1f2c..51823389f9f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -25,13 +25,9 @@ package com.sun.tools.javac.code; -import java.util.ArrayList; -import java.util.Collections; import java.util.Set; import java.util.concurrent.Callable; import javax.lang.model.element.*; -import javax.lang.model.type.ReferenceType; -import javax.lang.model.type.TypeMirror; import javax.tools.JavaFileObject; import com.sun.tools.javac.util.*; @@ -1272,8 +1268,14 @@ public abstract class Symbol implements Element { private static final long serialVersionUID = 0; public Symbol sym; - /** A localized string describing the failure. + /** A diagnostic object describing the failure */ + public JCDiagnostic diag; + + /** A localized string describing the failure. + * @deprecated Use {@code getDetail()} or {@code getMessage()} + */ + @Deprecated public String errmsg; public CompletionFailure(Symbol sym, String errmsg) { @@ -1282,8 +1284,26 @@ public abstract class Symbol implements Element { // this.printStackTrace();//DEBUG } + public CompletionFailure(Symbol sym, JCDiagnostic diag) { + this.sym = sym; + this.diag = diag; +// this.printStackTrace();//DEBUG + } + + public JCDiagnostic getDiagnostic() { + return diag; + } + + @Override public String getMessage() { - return errmsg; + if (diag != null) + return diag.getMessage(null); + else + return errmsg; + } + + public Object getDetailValue() { + return (diag != null ? diag : errmsg); } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 6b01fce3471..342696ceed8 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -173,7 +173,7 @@ public class Check { * @param ex The failure to report. */ public Type completionError(DiagnosticPosition pos, CompletionFailure ex) { - log.error(pos, "cant.access", ex.sym, ex.errmsg); + log.error(pos, "cant.access", ex.sym, ex.getDetailValue()); if (ex instanceof ClassReader.BadClassFile) throw new Abort(); else return syms.errType; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java index da75150e8cc..96729791774 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -131,6 +131,10 @@ public class ClassReader extends ClassFile implements Completer { */ private final JavaFileManager fileManager; + /** Factory for diagnostics + */ + JCDiagnostic.Factory diagFactory; + /** Can be reassigned from outside: * the completer to be used for ".java" files. If this remains unassigned * ".java" files will not be loaded. @@ -221,6 +225,7 @@ public class ClassReader extends ClassFile implements Completer { fileManager = context.get(JavaFileManager.class); if (fileManager == null) throw new AssertionError("FileManager initialization error"); + diagFactory = JCDiagnostic.Factory.instance(context); init(syms, definitive); log = Log.instance(context); @@ -256,23 +261,26 @@ public class ClassReader extends ClassFile implements Completer { * Error Diagnoses ***********************************************************************/ - public static class BadClassFile extends CompletionFailure { + + public class BadClassFile extends CompletionFailure { private static final long serialVersionUID = 0; - /** - * @param msg A localized message. - */ - public BadClassFile(ClassSymbol c, Object cname, Object msg) { - super(c, Log.getLocalizedString("bad.class.file.header", - cname, msg)); + public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag) { + super(sym, createBadClassFileDiagnostic(file, diag)); } } + // where + private JCDiagnostic createBadClassFileDiagnostic(JavaFileObject file, JCDiagnostic diag) { + String key = (file.getKind() == JavaFileObject.Kind.SOURCE + ? "bad.source.file.header" : "bad.class.file.header"); + return diagFactory.fragment(key, file, diag); + } public BadClassFile badClassFile(String key, Object... args) { return new BadClassFile ( currentOwner.enclClass(), currentClassFile, - Log.getLocalizedString(key, args)); + diagFactory.fragment(key, args)); } /************************************************************************ @@ -1893,10 +1901,10 @@ public class ClassReader extends ClassFile implements Completer { currentClassFile = previousClassFile; } } else { + JCDiagnostic diag = + diagFactory.fragment("class.file.not.found", c.flatname); throw - newCompletionFailure(c, - Log.getLocalizedString("class.file.not.found", - c.flatname)); + newCompletionFailure(c, diag); } } // where @@ -1934,22 +1942,22 @@ public class ClassReader extends ClassFile implements Completer { * In practice, only one can be used at a time, so we share one * to reduce the expense of allocating new exception objects. */ - private CompletionFailure newCompletionFailure(ClassSymbol c, - String localized) { + private CompletionFailure newCompletionFailure(TypeSymbol c, + JCDiagnostic diag) { if (!cacheCompletionFailure) { // log.warning("proc.messager", // Log.getLocalizedString("class.file.not.found", c.flatname)); // c.debug.printStackTrace(); - return new CompletionFailure(c, localized); + return new CompletionFailure(c, diag); } else { CompletionFailure result = cachedCompletionFailure; result.sym = c; - result.errmsg = localized; + result.diag = diag; return result; } } private CompletionFailure cachedCompletionFailure = - new CompletionFailure(null, null); + new CompletionFailure(null, (JCDiagnostic) null); { cachedCompletionFailure.setStackTrace(new StackTraceElement[0]); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index af97c6e022e..5bcccd35b7c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -198,6 +198,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter { */ public Log log; + /** Factory for creating diagnostic objects + */ + JCDiagnostic.Factory diagFactory; + /** The tree factory module. */ protected TreeMaker make; @@ -304,6 +308,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { names = Name.Table.instance(context); log = Log.instance(context); + diagFactory = JCDiagnostic.Factory.instance(context); reader = ClassReader.instance(context); make = TreeMaker.instance(context); writer = ClassWriter.instance(context); @@ -318,7 +323,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { syms = Symtab.instance(context); } catch (CompletionFailure ex) { // inlined Check.completionError as it is not initialized yet - log.error("cant.access", ex.sym, ex.errmsg); + log.error("cant.access", ex.sym, ex.getDetailValue()); if (ex instanceof ClassReader.BadClassFile) throw new Abort(); } @@ -683,16 +688,16 @@ public class JavaCompiler implements ClassReader.SourceCompleter { JavaFileObject.Kind.SOURCE); if (isPkgInfo) { if (enter.getEnv(tree.packge) == null) { - String msg - = log.getLocalizedString("file.does.not.contain.package", + JCDiagnostic diag = + diagFactory.fragment("file.does.not.contain.package", c.location()); - throw new ClassReader.BadClassFile(c, filename, msg); + throw reader.new BadClassFile(c, filename, diag); } } else { - throw new - ClassReader.BadClassFile(c, filename, log. - getLocalizedString("file.doesnt.contain.class", - c.fullname)); + JCDiagnostic diag = + diagFactory.fragment("file.doesnt.contain.class", + c.getQualifiedName()); + throw reader.new BadClassFile(c, filename, diag); } } @@ -997,7 +1002,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { annotationProcessingOccurred = c.annotationProcessingOccurred = true; return c; } catch (CompletionFailure ex) { - log.error("cant.access", ex.sym, ex.errmsg); + log.error("cant.access", ex.sym, ex.getDetailValue()); return this; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 4e7dfa99f26..684d28a2193 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -734,7 +734,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea } catch (CompletionFailure ex) { StringWriter out = new StringWriter(); ex.printStackTrace(new PrintWriter(out)); - log.error("proc.cant.access", ex.sym, ex.errmsg, out.toString()); + log.error("proc.cant.access", ex.sym, ex.getDetailValue(), out.toString()); return false; } catch (Throwable t) { throw new AnnotationProcessingError(t); diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 1dcbe45759f..abedc2db9b1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -827,6 +827,10 @@ compiler.misc.bad.class.file.header=\ bad class file: {0}\n\ {1}\n\ Please remove or make sure it appears in the correct subdirectory of the classpath. +compiler.misc.bad.source.file.header=\ +bad source file: {0}\n\ +{1}\n\ +Please remove or make sure it appears in the correct subdirectory of the sourcepath. ## The following are all possible strings for the second argument ({1}) of the ## above strings. diff --git a/langtools/test/tools/javac/6668794/badClass/A.java b/langtools/test/tools/javac/6668794/badClass/A.java new file mode 100644 index 00000000000..404039d2255 --- /dev/null +++ b/langtools/test/tools/javac/6668794/badClass/A.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package q; + +class A { } diff --git a/langtools/test/tools/javac/6668794/badClass/B.java b/langtools/test/tools/javac/6668794/badClass/B.java new file mode 100644 index 00000000000..4ba00da6b45 --- /dev/null +++ b/langtools/test/tools/javac/6668794/badClass/B.java @@ -0,0 +1,7 @@ +/* + * /nodynamiccopyright/ + */ + +class B { + p.A a; +} diff --git a/langtools/test/tools/javac/6668794/badClass/Test.java b/langtools/test/tools/javac/6668794/badClass/Test.java new file mode 100644 index 00000000000..40e514f89a5 --- /dev/null +++ b/langtools/test/tools/javac/6668794/badClass/Test.java @@ -0,0 +1,88 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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 6668794 6668796 + * @summary javac puts localized text in raw diagnostics + * bad diagnostic "bad class file" given for source files + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; + +public class Test { + public static void main(String[] args) throws Exception { + new Test().run(); + } + + void run() throws Exception { + + // compile q.A then move it to p.A + compile("A.java"); + + File p = new File("p"); + p.mkdirs(); + new File("q/A.class").renameTo(new File("p/A.class")); + + // compile B against p.A + String[] out = compile("B.java"); + if (out.length == 0) + throw new Error("no diagnostics generated"); + + String expected = "B.java:6:6: compiler.err.cant.access: p.A, " + + "(- compiler.misc.bad.class.file.header: A.class, " + + "(- compiler.misc.class.file.wrong.class: q.A))"; + + if (!out[0].equals(expected)) { + System.err.println("expected: " + expected); + System.err.println(" found: " + out[0]); + throw new Error("test failed"); + } + } + + String[] compile(String file) { + String[] options = { + "-XDrawDiagnostics", + "-d", ".", + "-classpath", ".", + new File(testSrc, file).getPath() + }; + + System.err.println("compile: " + Arrays.asList(options)); + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + int rc = com.sun.tools.javac.Main.compile(options, out); + out.close(); + + String outText = sw.toString(); + System.err.println(outText); + + return sw.toString().split("[\\r\\n]+"); + } + + File testSrc = new File(System.getProperty("test.src", ".")); +} diff --git a/langtools/test/tools/javac/6668794/badSource/Test.java b/langtools/test/tools/javac/6668794/badSource/Test.java new file mode 100644 index 00000000000..162493e5ab1 --- /dev/null +++ b/langtools/test/tools/javac/6668794/badSource/Test.java @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyight/ + * @bug 6668794 6668796 + * @summary javac puts localized text in raw diagnostics + * bad diagnostic "bad class file" given for source files + * @compile/fail/ref=Test.out -XDrawDiagnostics Test.java + */ + +class Test { + p.A a; +} diff --git a/langtools/test/tools/javac/6668794/badSource/Test.out b/langtools/test/tools/javac/6668794/badSource/Test.out new file mode 100644 index 00000000000..e9fbdf99bda --- /dev/null +++ b/langtools/test/tools/javac/6668794/badSource/Test.out @@ -0,0 +1 @@ +Test.java:10:6: compiler.err.cant.access: p.A, (- compiler.misc.bad.source.file.header: A.java, (- compiler.misc.file.doesnt.contain.class: p.A)) diff --git a/langtools/test/tools/javac/6668794/badSource/p/A.java b/langtools/test/tools/javac/6668794/badSource/p/A.java new file mode 100644 index 00000000000..404039d2255 --- /dev/null +++ b/langtools/test/tools/javac/6668794/badSource/p/A.java @@ -0,0 +1,28 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package q; + +class A { } From 0f1d30354af3246865a6c85a8f06ceebd02cf51e Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 12 Mar 2008 18:06:50 -0700 Subject: [PATCH 134/274] 6497639: 4/3 Profiling Swing application caused JVM crash Make RedefineClasses() interoperate better with class sharing. Reviewed-by: sspitsyn, jmasa --- hotspot/src/share/vm/classfile/dictionary.cpp | 4 +- .../share/vm/memory/compactingPermGenGen.cpp | 55 ++++++++++++++++--- hotspot/src/share/vm/oops/instanceKlass.cpp | 38 +++++++++---- hotspot/src/share/vm/oops/instanceKlass.hpp | 17 ++++-- 4 files changed, 87 insertions(+), 27 deletions(-) diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp index 6c1d1ffce61..43d1ab9030d 100644 --- a/hotspot/src/share/vm/classfile/dictionary.cpp +++ b/hotspot/src/share/vm/classfile/dictionary.cpp @@ -155,8 +155,8 @@ bool Dictionary::do_unloading(BoolObjectClosure* is_alive) { for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) { // check the previous versions array for GC'ed weak refs PreviousVersionNode * pv_node = ik->previous_versions()->at(i); - jweak cp_ref = pv_node->prev_constant_pool(); - assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); + jobject cp_ref = pv_node->prev_constant_pool(); + assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); if (cp_ref == NULL) { delete pv_node; ik->previous_versions()->remove_at(i); diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp index 990f514a739..317908b188f 100644 --- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp +++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp @@ -26,9 +26,27 @@ #include "incls/_compactingPermGenGen.cpp.incl" -// Recursively adjust all pointers in an object and all objects by -// referenced it. Clear marks on objects in order to prevent visiting -// any object twice. +// An ObjectClosure helper: Recursively adjust all pointers in an object +// and all objects by referenced it. Clear marks on objects in order to +// prevent visiting any object twice. This helper is used when the +// RedefineClasses() API has been called. + +class AdjustSharedObjectClosure : public ObjectClosure { +public: + void do_object(oop obj) { + if (obj->is_shared_readwrite()) { + if (obj->mark()->is_marked()) { + obj->init_mark(); // Don't revisit this object. + obj->adjust_pointers(); // Adjust this object's references. + } + } + } +}; + + +// An OopClosure helper: Recursively adjust all pointers in an object +// and all objects by referenced it. Clear marks on objects in order +// to prevent visiting any object twice. class RecursiveAdjustSharedObjectClosure : public OopClosure { public: @@ -274,15 +292,34 @@ CompactingPermGenGen::CompactingPermGenGen(ReservedSpace rs, // objects in the space will page in more objects than we need. // Instead, use the system dictionary as strong roots into the read // write space. +// +// If a RedefineClasses() call has been made, then we have to iterate +// over the entire shared read-write space in order to find all the +// objects that need to be forwarded. For example, it is possible for +// an nmethod to be found and marked in GC phase-1 only for the nmethod +// to be freed by the time we reach GC phase-3. The underlying method +// is still marked, but we can't (easily) find it in GC phase-3 so we +// blow up in GC phase-4. With RedefineClasses() we want replaced code +// (EMCP or obsolete) to go away (i.e., be collectible) once it is no +// longer being executed by any thread so we keep minimal attachments +// to the replaced code. However, we can't guarantee when those EMCP +// or obsolete methods will be collected so they may still be out there +// even after we've severed our minimal attachments. void CompactingPermGenGen::pre_adjust_pointers() { if (spec()->enable_shared_spaces()) { - RecursiveAdjustSharedObjectClosure blk; - Universe::oops_do(&blk); - StringTable::oops_do(&blk); - SystemDictionary::always_strong_classes_do(&blk); - TraversePlaceholdersClosure tpc; - SystemDictionary::placeholders_do(&tpc); + if (JvmtiExport::has_redefined_a_class()) { + // RedefineClasses() requires a brute force approach + AdjustSharedObjectClosure blk; + rw_space()->object_iterate(&blk); + } else { + RecursiveAdjustSharedObjectClosure blk; + Universe::oops_do(&blk); + StringTable::oops_do(&blk); + SystemDictionary::always_strong_classes_do(&blk); + TraversePlaceholdersClosure tpc; + SystemDictionary::placeholders_do(&tpc); + } } } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index a1105d49486..ea85a6c630b 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2165,12 +2165,20 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh, RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d", ikh->external_name(), _previous_versions->length(), emcp_method_count)); constantPoolHandle cp_h(ikh->constants()); - jweak cp_ref = JNIHandles::make_weak_global(cp_h); + jobject cp_ref; + if (cp_h->is_shared()) { + // a shared ConstantPool requires a regular reference; a weak + // reference would be collectible + cp_ref = JNIHandles::make_global(cp_h); + } else { + cp_ref = JNIHandles::make_weak_global(cp_h); + } PreviousVersionNode * pv_node = NULL; objArrayOop old_methods = ikh->methods(); if (emcp_method_count == 0) { - pv_node = new PreviousVersionNode(cp_ref, NULL); + // non-shared ConstantPool gets a weak reference + pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL); RC_TRACE(0x00000400, ("add: all methods are obsolete; flushing any EMCP weak refs")); } else { @@ -2190,7 +2198,8 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh, } } } - pv_node = new PreviousVersionNode(cp_ref, method_refs); + // non-shared ConstantPool gets a weak reference + pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs); } _previous_versions->append(pv_node); @@ -2208,7 +2217,7 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh, // check the previous versions array for a GC'ed weak refs pv_node = _previous_versions->at(i); cp_ref = pv_node->prev_constant_pool(); - assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); + assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); if (cp_ref == NULL) { delete pv_node; _previous_versions->remove_at(i); @@ -2281,7 +2290,7 @@ void instanceKlass::add_previous_version(instanceKlassHandle ikh, // check the previous versions array for a GC'ed weak refs pv_node = _previous_versions->at(j); cp_ref = pv_node->prev_constant_pool(); - assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); + assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); if (cp_ref == NULL) { delete pv_node; _previous_versions->remove_at(j); @@ -2379,8 +2388,8 @@ bool instanceKlass::has_previous_version() const { // been GC'ed PreviousVersionNode * pv_node = _previous_versions->at(i); - jweak cp_ref = pv_node->prev_constant_pool(); - assert(cp_ref != NULL, "weak reference was unexpectedly cleared"); + jobject cp_ref = pv_node->prev_constant_pool(); + assert(cp_ref != NULL, "cp reference was unexpectedly cleared"); if (cp_ref == NULL) { continue; // robustness } @@ -2440,10 +2449,11 @@ void instanceKlass::set_methods_annotations_of(int idnum, typeArrayOop anno, obj // Construct a PreviousVersionNode entry for the array hung off // the instanceKlass. -PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool, - GrowableArray* prev_EMCP_methods) { +PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool, + bool prev_cp_is_weak, GrowableArray* prev_EMCP_methods) { _prev_constant_pool = prev_constant_pool; + _prev_cp_is_weak = prev_cp_is_weak; _prev_EMCP_methods = prev_EMCP_methods; } @@ -2451,7 +2461,11 @@ PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool, // Destroy a PreviousVersionNode PreviousVersionNode::~PreviousVersionNode() { if (_prev_constant_pool != NULL) { - JNIHandles::destroy_weak_global(_prev_constant_pool); + if (_prev_cp_is_weak) { + JNIHandles::destroy_weak_global(_prev_constant_pool); + } else { + JNIHandles::destroy_global(_prev_constant_pool); + } } if (_prev_EMCP_methods != NULL) { @@ -2471,8 +2485,8 @@ PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { _prev_constant_pool_handle = constantPoolHandle(); // NULL handle _prev_EMCP_method_handles = NULL; - jweak cp_ref = pv_node->prev_constant_pool(); - assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared"); + jobject cp_ref = pv_node->prev_constant_pool(); + assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared"); if (cp_ref == NULL) { return; // robustness } diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 29a76dc2c3b..478e8ecc1ef 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -838,11 +838,20 @@ class BreakpointInfo; // A collection point for interesting information about the previous // version(s) of an instanceKlass. This class uses weak references to // the information so that the information may be collected as needed -// by the system. A GrowableArray of PreviousVersionNodes is attached +// by the system. If the information is shared, then a regular +// reference must be used because a weak reference would be seen as +// collectible. A GrowableArray of PreviousVersionNodes is attached // to the instanceKlass as needed. See PreviousVersionWalker below. class PreviousVersionNode : public CHeapObj { private: - jweak _prev_constant_pool; + // A shared ConstantPool is never collected so we'll always have + // a reference to it so we can update items in the cache. We'll + // have a weak reference to a non-shared ConstantPool until all + // of the methods (EMCP or obsolete) have been collected; the + // non-shared ConstantPool becomes collectible at that point. + jobject _prev_constant_pool; // regular or weak reference + bool _prev_cp_is_weak; // true if not a shared ConstantPool + // If the previous version of the instanceKlass doesn't have any // EMCP methods, then _prev_EMCP_methods will be NULL. If all the // EMCP methods have been collected, then _prev_EMCP_methods can @@ -850,10 +859,10 @@ class PreviousVersionNode : public CHeapObj { GrowableArray* _prev_EMCP_methods; public: - PreviousVersionNode(jweak prev_constant_pool, + PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak, GrowableArray* prev_EMCP_methods); ~PreviousVersionNode(); - jweak prev_constant_pool() const { + jobject prev_constant_pool() const { return _prev_constant_pool; } GrowableArray* prev_EMCP_methods() const { From f813016add7decf52ce97716f103dc14f8ed8f6b Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 12 Mar 2008 18:07:46 -0700 Subject: [PATCH 135/274] 6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure Add should_not_be_cached() to markOop and methodOop and query that status inOopMapCache::lookup() Reviewed-by: coleenp, sspitsyn, jmasa --- hotspot/src/share/vm/includeDB_core | 1 + .../src/share/vm/interpreter/oopMapCache.cpp | 26 ++++++++--------- hotspot/src/share/vm/oops/markOop.cpp | 29 +++++++++++++++++++ hotspot/src/share/vm/oops/markOop.hpp | 3 ++ hotspot/src/share/vm/oops/methodOop.cpp | 22 ++++++++++++++ hotspot/src/share/vm/oops/methodOop.hpp | 2 ++ .../vm/prims/jvmtiRedefineClassesTrace.hpp | 2 +- 7 files changed, 71 insertions(+), 14 deletions(-) diff --git a/hotspot/src/share/vm/includeDB_core b/hotspot/src/share/vm/includeDB_core index cbf8e561a73..a49e0e99ede 100644 --- a/hotspot/src/share/vm/includeDB_core +++ b/hotspot/src/share/vm/includeDB_core @@ -3068,6 +3068,7 @@ oopMap.hpp vmreg.hpp oopMapCache.cpp allocation.inline.hpp oopMapCache.cpp handles.inline.hpp +oopMapCache.cpp jvmtiRedefineClassesTrace.hpp oopMapCache.cpp oop.inline.hpp oopMapCache.cpp oopMapCache.hpp oopMapCache.cpp resourceArea.hpp diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp index 6a777dd789a..32d731ddd1c 100644 --- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp +++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp @@ -532,6 +532,10 @@ void OopMapCache::flush_obsolete_entries() { if (!_array[i].is_empty() && _array[i].method()->is_old()) { // Cache entry is occupied by an old redefined method and we don't want // to pin it down so flush the entry. + RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d", + _array[i].method()->name()->as_C_string(), + _array[i].method()->signature()->as_C_string(), i)); + _array[i].flush(); } } @@ -577,6 +581,15 @@ void OopMapCache::lookup(methodHandle method, // Entry is not in hashtable. // Compute entry and return it + if (method->should_not_be_cached()) { + // It is either not safe or not a good idea to cache this methodOop + // at this time. We give the caller of lookup() a copy of the + // interesting info via parameter entry_for, but we don't add it to + // the cache. See the gory details in methodOop.cpp. + compute_one_oop_map(method, bci, entry_for); + return; + } + // First search for an empty slot for(i = 0; i < _probe_depth; i++) { entry = entry_at(probe + i); @@ -584,12 +597,6 @@ void OopMapCache::lookup(methodHandle method, entry->fill(method, bci); entry_for->resource_copy(entry); assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); - if (method->is_old()) { - // The caller of lookup() will receive a copy of the interesting - // info via entry_for, but we don't keep an old redefined method in - // the cache to avoid pinning down the method. - entry->flush(); - } return; } } @@ -623,13 +630,6 @@ void OopMapCache::lookup(methodHandle method, } assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); - if (method->is_old()) { - // The caller of lookup() will receive a copy of the interesting - // info via entry_for, but we don't keep an old redefined method in - // the cache to avoid pinning down the method. - entry->flush(); - } - return; } diff --git a/hotspot/src/share/vm/oops/markOop.cpp b/hotspot/src/share/vm/oops/markOop.cpp index 855b525f4f7..75a2d506b46 100644 --- a/hotspot/src/share/vm/oops/markOop.cpp +++ b/hotspot/src/share/vm/oops/markOop.cpp @@ -37,3 +37,32 @@ void markOopDesc::print_on(outputStream* st) const { st->print("age %d)", age()); } } + + +// Give advice about whether the oop that contains this markOop +// should be cached or not. +bool markOopDesc::should_not_be_cached() const { + // the cast is because decode_pointer() isn't marked const + if (is_marked() && ((markOopDesc *)this)->decode_pointer() != NULL) { + // If the oop containing this markOop is being forwarded, then + // we are in the middle of GC and we do not want the containing + // oop to be added to a cache. We have no way of knowing whether + // the cache has already been visited by the current GC phase so + // we don't know whether the forwarded oop will be properly + // processed in this phase. If the forwarded oop is not properly + // processed, then we'll see strange crashes or asserts during + // the next GC run because the markOop will contain an unexpected + // value. + // + // This situation has been seen when we are GC'ing a methodOop + // because we use the methodOop while we're GC'ing it. Scary + // stuff. Some of the uses the methodOop cause the methodOop to + // be added to the OopMapCache in the instanceKlass as a side + // effect. This check lets the cache maintainer know when a + // cache addition would not be safe. + return true; + } + + // caching the containing oop should be just fine + return false; +} diff --git a/hotspot/src/share/vm/oops/markOop.hpp b/hotspot/src/share/vm/oops/markOop.hpp index def7c1844d3..155fb163895 100644 --- a/hotspot/src/share/vm/oops/markOop.hpp +++ b/hotspot/src/share/vm/oops/markOop.hpp @@ -357,4 +357,7 @@ class markOopDesc: public oopDesc { // Recover address of oop from encoded form used in mark inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); } + + // see the definition in markOop.cpp for the gory details + bool should_not_be_cached() const; }; diff --git a/hotspot/src/share/vm/oops/methodOop.cpp b/hotspot/src/share/vm/oops/methodOop.cpp index bd23bfa772e..dfe9dee8560 100644 --- a/hotspot/src/share/vm/oops/methodOop.cpp +++ b/hotspot/src/share/vm/oops/methodOop.cpp @@ -765,6 +765,28 @@ bool methodOopDesc::is_overridden_in(klassOop k) const { } +// give advice about whether this methodOop should be cached or not +bool methodOopDesc::should_not_be_cached() const { + if (is_old()) { + // This method has been redefined. It is either EMCP or obsolete + // and we don't want to cache it because that would pin the method + // down and prevent it from being collectible if and when it + // finishes executing. + return true; + } + + if (mark()->should_not_be_cached()) { + // It is either not safe or not a good idea to cache this + // method at this time because of the state of the embedded + // markOop. See markOop.cpp for the gory details. + return true; + } + + // caching this method should be just fine + return false; +} + + methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length, u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) { // Code below does not work for native methods - they should never get rewritten anyway diff --git a/hotspot/src/share/vm/oops/methodOop.hpp b/hotspot/src/share/vm/oops/methodOop.hpp index ec3d6b5e5ad..0d936e251f1 100644 --- a/hotspot/src/share/vm/oops/methodOop.hpp +++ b/hotspot/src/share/vm/oops/methodOop.hpp @@ -524,6 +524,8 @@ class methodOopDesc : public oopDesc { void set_is_old() { _access_flags.set_is_old(); } bool is_obsolete() const { return access_flags().is_obsolete(); } void set_is_obsolete() { _access_flags.set_is_obsolete(); } + // see the definition in methodOop.cpp for the gory details + bool should_not_be_cached() const; // JVMTI Native method prefixing support: bool is_prefixed_native() const { return access_flags().is_prefixed_native(); } diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp b/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp index b527a8daec1..ed0f472b3d4 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp @@ -64,7 +64,7 @@ // 0x01000000 | 16777216 - impl details: nmethod evolution info // 0x02000000 | 33554432 - impl details: annotation updates // 0x04000000 | 67108864 - impl details: StackMapTable updates -// 0x08000000 | 134217728 - unused +// 0x08000000 | 134217728 - impl details: OopMapCache updates // 0x10000000 | 268435456 - unused // 0x20000000 | 536870912 - unused // 0x40000000 | 1073741824 - unused From 454bce899397f8048e63d0519876a57293c140ad Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 12 Mar 2008 18:09:34 -0700 Subject: [PATCH 136/274] 6453355: 4/4 new No_Safepoint_Verifier uses fail during GC (for Serguei) Clean up use of No_Safepoint_Verifier in JVM TI Reviewed-by: dcubed --- hotspot/src/share/vm/oops/instanceKlass.cpp | 73 ++++++++++++--------- hotspot/src/share/vm/oops/instanceKlass.hpp | 2 + hotspot/src/share/vm/runtime/thread.cpp | 8 +-- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index ea85a6c630b..74b60274f03 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -950,7 +950,6 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan // These allocations will have to be freed if they are unused. // Allocate a new array of methods. - jmethodID* to_dealloc_jmeths = NULL; jmethodID* new_jmeths = NULL; if (length <= idnum) { // A new array will be needed (unless some other thread beats us to it) @@ -961,7 +960,6 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan } // Allocate a new method ID. - jmethodID to_dealloc_id = NULL; jmethodID new_id = NULL; if (method_h->is_old() && !method_h->is_obsolete()) { // The method passed in is old (but not obsolete), we need to use the current version @@ -975,40 +973,51 @@ jmethodID instanceKlass::jmethod_id_for_impl(instanceKlassHandle ik_h, methodHan new_id = JNIHandles::make_jmethod_id(method_h); } - { + if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { + // No need and unsafe to lock the JmethodIdCreation_lock at safepoint. + id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths); + } else { MutexLocker ml(JmethodIdCreation_lock); - - // We must not go to a safepoint while holding this lock. - debug_only(No_Safepoint_Verifier nosafepoints;) - - // Retry lookup after we got the lock - jmeths = ik_h->methods_jmethod_ids_acquire(); - if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) { - if (jmeths != NULL) { - // We have grown the array: copy the existing entries, and delete the old array - for (size_t index = 0; index < length; index++) { - new_jmeths[index+1] = jmeths[index+1]; - } - to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one - } - ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths); - } else { - id = jmeths[idnum+1]; - to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one - } - if (id == NULL) { - id = new_id; - jmeths[idnum+1] = id; // install the new method ID - } else { - to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation - } + id = get_jmethod_id(ik_h, idnum, new_id, new_jmeths); } + } + return id; +} - // Free up unneeded or no longer needed resources - FreeHeap(to_dealloc_jmeths); - if (to_dealloc_id != NULL) { - JNIHandles::destroy_jmethod_id(to_dealloc_id); + +jmethodID instanceKlass::get_jmethod_id(instanceKlassHandle ik_h, size_t idnum, + jmethodID new_id, jmethodID* new_jmeths) { + // Retry lookup after we got the lock or ensured we are at safepoint + jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire(); + jmethodID id = NULL; + jmethodID to_dealloc_id = NULL; + jmethodID* to_dealloc_jmeths = NULL; + size_t length; + + if (jmeths == NULL || (length = (size_t)jmeths[0]) <= idnum) { + if (jmeths != NULL) { + // We have grown the array: copy the existing entries, and delete the old array + for (size_t index = 0; index < length; index++) { + new_jmeths[index+1] = jmeths[index+1]; + } + to_dealloc_jmeths = jmeths; // using the new jmeths, deallocate the old one } + ik_h->release_set_methods_jmethod_ids(jmeths = new_jmeths); + } else { + id = jmeths[idnum+1]; + to_dealloc_jmeths = new_jmeths; // using the old jmeths, deallocate the new one + } + if (id == NULL) { + id = new_id; + jmeths[idnum+1] = id; // install the new method ID + } else { + to_dealloc_id = new_id; // the new id wasn't used, mark it for deallocation + } + + // Free up unneeded or no longer needed resources + FreeHeap(to_dealloc_jmeths); + if (to_dealloc_id != NULL) { + JNIHandles::destroy_jmethod_id(to_dealloc_id); } return id; } diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 478e8ecc1ef..285291dcea4 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -432,6 +432,8 @@ class instanceKlass: public Klass { _enclosing_method_method_index = method_index; } // jmethodID support + static jmethodID get_jmethod_id(instanceKlassHandle ik_h, size_t idnum, + jmethodID new_id, jmethodID* new_jmeths); static jmethodID jmethod_id_for_impl(instanceKlassHandle ik_h, methodHandle method_h); jmethodID jmethod_id_or_null(methodOop method); diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 607772a0242..3667e576d13 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -1317,10 +1317,6 @@ JavaThread::~JavaThread() { ThreadSafepointState::destroy(this); if (_thread_profiler != NULL) delete _thread_profiler; if (_thread_stat != NULL) delete _thread_stat; - - if (jvmti_thread_state() != NULL) { - JvmtiExport::cleanup_thread(this); - } } @@ -1571,6 +1567,10 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) { tlab().make_parsable(true); // retire TLAB } + if (jvmti_thread_state() != NULL) { + JvmtiExport::cleanup_thread(this); + } + // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread Threads::remove(this); } From 29278156581c79aacd48a8a4ad09c82f87648b1f Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 12 Mar 2008 18:37:03 -0700 Subject: [PATCH 137/274] 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers (for Serguei) Allow for Linux builds with Sun Studio Linux compilers Reviewed-by: sspitsyn, ohair --- hotspot/agent/src/os/linux/ps_core.c | 8 +- hotspot/agent/src/os/linux/ps_proc.c | 8 +- hotspot/build/linux/Makefile | 5 + hotspot/build/linux/makefiles/amd64.make | 4 +- hotspot/build/linux/makefiles/buildtree.make | 6 +- hotspot/build/linux/makefiles/sparcWorks.make | 93 +++++++++++++++++++ hotspot/build/linux/platform_amd64.suncc | 17 ++++ hotspot/build/linux/platform_i486.suncc | 17 ++++ hotspot/src/cpu/x86/vm/assembler_x86_64.cpp | 4 +- .../src/os/linux/vm/attachListener_linux.cpp | 2 +- .../linux_x86/vm/bytes_linux_x86.inline.hpp | 11 +++ .../src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 17 ++++ .../globalDefinitions_sparcWorks.hpp | 60 ++++++++++-- 13 files changed, 233 insertions(+), 19 deletions(-) create mode 100644 hotspot/build/linux/makefiles/sparcWorks.make create mode 100644 hotspot/build/linux/platform_amd64.suncc create mode 100644 hotspot/build/linux/platform_i486.suncc diff --git a/hotspot/agent/src/os/linux/ps_core.c b/hotspot/agent/src/os/linux/ps_core.c index b8890f15fc9..0693ffce4bb 100644 --- a/hotspot/agent/src/os/linux/ps_core.c +++ b/hotspot/agent/src/os/linux/ps_core.c @@ -518,10 +518,10 @@ static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, } static ps_prochandle_ops core_ops = { - release: core_release, - p_pread: core_read_data, - p_pwrite: core_write_data, - get_lwp_regs: core_get_lwp_regs + .release= core_release, + .p_pread= core_read_data, + .p_pwrite= core_write_data, + .get_lwp_regs= core_get_lwp_regs }; // read regs and create thread from NT_PRSTATUS entries from core file diff --git a/hotspot/agent/src/os/linux/ps_proc.c b/hotspot/agent/src/os/linux/ps_proc.c index 81ea1fb7aa0..9b226eaf00b 100644 --- a/hotspot/agent/src/os/linux/ps_proc.c +++ b/hotspot/agent/src/os/linux/ps_proc.c @@ -291,10 +291,10 @@ static void process_cleanup(struct ps_prochandle* ph) { } static ps_prochandle_ops process_ops = { - release: process_cleanup, - p_pread: process_read_data, - p_pwrite: process_write_data, - get_lwp_regs: process_get_lwp_regs + .release= process_cleanup, + .p_pread= process_read_data, + .p_pwrite= process_write_data, + .get_lwp_regs= process_get_lwp_regs }; // attach to the process. One and only one exposed stuff diff --git a/hotspot/build/linux/Makefile b/hotspot/build/linux/Makefile index 4b595a50ffc..106344f0dbe 100644 --- a/hotspot/build/linux/Makefile +++ b/hotspot/build/linux/Makefile @@ -80,6 +80,11 @@ ifneq ("$(filter $(LP64_ARCH),$(BUILDARCH))","") MFLAGS += " LP64=1 " endif +# pass USE_SUNCC further, through MFLAGS +ifdef USE_SUNCC + MFLAGS += " USE_SUNCC=1 " +endif + # The following renders pathnames in generated Makefiles valid on # machines other than the machine containing the build tree. # diff --git a/hotspot/build/linux/makefiles/amd64.make b/hotspot/build/linux/makefiles/amd64.make index 6b961fab558..d69cce70b9a 100644 --- a/hotspot/build/linux/makefiles/amd64.make +++ b/hotspot/build/linux/makefiles/amd64.make @@ -35,6 +35,8 @@ CFLAGS += -DVM_LITTLE_ENDIAN CFLAGS += -D_LP64=1 # The serviceability agent relies on frame pointer (%rbp) to walk thread stack -CFLAGS += -fno-omit-frame-pointer +ifndef USE_SUNCC + CFLAGS += -fno-omit-frame-pointer +endif OPT_CFLAGS/compactingPermGenGen.o = -O1 diff --git a/hotspot/build/linux/makefiles/buildtree.make b/hotspot/build/linux/makefiles/buildtree.make index 7e5b92df37f..a71aa64f12e 100644 --- a/hotspot/build/linux/makefiles/buildtree.make +++ b/hotspot/build/linux/makefiles/buildtree.make @@ -63,7 +63,11 @@ QUIETLY$(MAKE_VERBOSE) = @ # For now, until the compiler is less wobbly: TESTFLAGS = -Xbatch -showversion -PLATFORM_FILE = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH) +ifdef USE_SUNCC +PLATFORM_FILE = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH).suncc +else +PLATFORM_FILE = $(GAMMADIR)/build/$(OS_FAMILY)/platform_$(BUILDARCH) +endif ifdef FORCE_TIERED ifeq ($(VARIANT),tiered) diff --git a/hotspot/build/linux/makefiles/sparcWorks.make b/hotspot/build/linux/makefiles/sparcWorks.make new file mode 100644 index 00000000000..53819743beb --- /dev/null +++ b/hotspot/build/linux/makefiles/sparcWorks.make @@ -0,0 +1,93 @@ +# +# Copyright 1999-2007 Sun Microsystems, Inc. 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. +# +# + +#------------------------------------------------------------------------ +# CC, CPP & AS + +CPP = CC +CC = cc +AS = $(CC) -c + +ARCHFLAG = $(ARCHFLAG/$(BUILDARCH)) +ARCHFLAG/i486 = -m32 +ARCHFLAG/amd64 = -m64 + +CFLAGS += $(ARCHFLAG) +AOUT_FLAGS += $(ARCHFLAG) +LFLAGS += $(ARCHFLAG) +ASFLAGS += $(ARCHFLAG) + +#------------------------------------------------------------------------ +# Compiler flags + +# position-independent code +PICFLAG = -KPIC + +CFLAGS += $(PICFLAG) +# no more exceptions +CFLAGS += -features=no%except +# Reduce code bloat by reverting back to 5.0 behavior for static initializers +CFLAGS += -features=no%split_init +# allow zero sized arrays +CFLAGS += -features=zla + +# Use C++ Interpreter +ifdef CC_INTERP + CFLAGS += -DCC_INTERP +endif + +# We don't need libCstd.so and librwtools7.so, only libCrun.so +CFLAGS += -library=Crun +LIBS += -lCrun + +CFLAGS += -mt +LFLAGS += -mt + +# Compiler warnings are treated as errors +#WARNINGS_ARE_ERRORS = -errwarn=%all +CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) +# Special cases +CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) + +# The flags to use for an Optimized build +OPT_CFLAGS+=-xO4 +OPT_CFLAGS/NOOPT=-xO0 + +#------------------------------------------------------------------------ +# Linker flags + +# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file. +MAPFLAG = -Wl,--version-script=FILENAME + +# Use $(SONAMEFLAG:SONAME=soname) to specify the intrinsic name of a shared obj +SONAMEFLAG = -h SONAME + +# Build shared library +SHARED_FLAG = -G + +#------------------------------------------------------------------------ +# Debug flags +DEBUG_CFLAGS += -g +FASTDEBUG_CFLAGS = -g0 + diff --git a/hotspot/build/linux/platform_amd64.suncc b/hotspot/build/linux/platform_amd64.suncc new file mode 100644 index 00000000000..4366549571d --- /dev/null +++ b/hotspot/build/linux/platform_amd64.suncc @@ -0,0 +1,17 @@ +os_family = linux + +arch = x86 + +arch_model = x86_64 + +os_arch = linux_x86 + +os_arch_model = linux_x86_64 + +lib_arch = amd64 + +compiler = sparcWorks + +gnu_dis_arch = amd64 + +sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DAMD64 diff --git a/hotspot/build/linux/platform_i486.suncc b/hotspot/build/linux/platform_i486.suncc new file mode 100644 index 00000000000..325a3febd96 --- /dev/null +++ b/hotspot/build/linux/platform_i486.suncc @@ -0,0 +1,17 @@ +os_family = linux + +arch = x86 + +arch_model = x86_32 + +os_arch = linux_x86 + +os_arch_model = linux_x86_32 + +lib_arch = i386 + +compiler = sparcWorks + +gnu_dis_arch = i386 + +sysdefs = -DLINUX -DSPARC_WORKS -D_GNU_SOURCE -DIA32 diff --git a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp b/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp index 0c457270632..41e157eef15 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp @@ -1304,7 +1304,7 @@ void Assembler::movl(Address dst, Register src) { emit_operand(src, dst); } -void Assembler::mov64(Register dst, int64_t imm64) { +void Assembler::mov64(Register dst, intptr_t imm64) { InstructionMark im(this); int encode = prefixq_and_encode(dst->encoding()); emit_byte(0xB8 | encode); @@ -1331,7 +1331,7 @@ void Assembler::movq(Register dst, Address src) { emit_operand(dst, src); } -void Assembler::mov64(Address dst, int64_t imm32) { +void Assembler::mov64(Address dst, intptr_t imm32) { assert(is_simm32(imm32), "lost bits"); InstructionMark im(this); prefixq(dst); diff --git a/hotspot/src/os/linux/vm/attachListener_linux.cpp b/hotspot/src/os/linux/vm/attachListener_linux.cpp index f0ffe6c8d39..81ce1cc976b 100644 --- a/hotspot/src/os/linux/vm/attachListener_linux.cpp +++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp @@ -232,7 +232,7 @@ LinuxAttachOperation* LinuxAttachListener::read_request(int s) { // where is the protocol version (1), is the command // name ("load", "datadump", ...), and is an argument int expected_str_count = 2 + AttachOperation::arg_count_max; - int max_len = (strlen(ver_str) + 1) + (AttachOperation::name_length_max + 1) + + const int max_len = (sizeof(ver_str) + 1) + (AttachOperation::name_length_max + 1) + AttachOperation::arg_count_max*(AttachOperation::arg_length_max + 1); char buf[max_len]; diff --git a/hotspot/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp b/hotspot/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp index 1368a4c9c66..f0e0d5c4775 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp @@ -60,7 +60,18 @@ inline u4 Bytes::swap_u4(u4 x) { #ifdef AMD64 inline u8 Bytes::swap_u8(u8 x) { +#ifdef SPARC_WORKS + // workaround for SunStudio12 CR6615391 + __asm__ __volatile__ ( + "bswapq %0" + :"=r" (x) // output : register 0 => x + :"0" (x) // input : x => register 0 + :"0" // clobbered register + ); + return x; +#else return bswap_64(x); +#endif } #else // Helper function for swap_u8 diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index 972ee017c40..fc445ee26ca 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -62,8 +62,14 @@ #endif // AMD64 address os::current_stack_pointer() { +#ifdef SPARC_WORKS + register void *esp; + __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp)); + return (address) ((char*)esp + sizeof(long)*2); +#else register void *esp __asm__ (SPELL_REG_SP); return (address) esp; +#endif } char* os::non_memory_address_word() { @@ -139,7 +145,12 @@ frame os::get_sender_for_C_frame(frame* fr) { } intptr_t* _get_previous_fp() { +#ifdef SPARC_WORKS + register intptr_t **ebp; + __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp)); +#else register intptr_t **ebp __asm__ (SPELL_REG_FP); +#endif return (intptr_t*) *ebp; // we want what it points to. } @@ -575,7 +586,9 @@ bool os::Linux::supports_variable_stack_size() { return true; } #else size_t os::Linux::min_stack_allowed = (48 DEBUG_ONLY(+4))*K; +#ifdef __GNUC__ #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;}) +#endif // Test if pthread library can support variable thread stack size. LinuxThreads // in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads @@ -606,7 +619,11 @@ bool os::Linux::supports_variable_stack_size() { // return true and skip _thread_safety_check(), so we may not be able to // detect stack-heap collisions. But otherwise it's harmless. // +#ifdef __GNUC__ return (GET_GS() != 0); +#else + return false; +#endif } } #endif // AMD64 diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp index 16ae1ce9b12..a5629b2f826 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp @@ -37,23 +37,45 @@ # include # include # include +#ifdef SOLARIS # include +#endif # include +#ifdef LINUX +#ifndef FP_PZERO + // Linux doesn't have positive/negative zero + #define FP_PZERO FP_ZERO +#endif +#ifndef fpclass + #define fpclass fpclassify +#endif +#endif # include # include # include # include +#ifdef SOLARIS # include +#endif # include # include +#ifdef SOLARIS # include # include # include # include # include +#endif # ifdef SOLARIS_MUTATOR_LIBTHREAD # include # endif +#ifdef LINUX +# include +# include +# include +# include +#endif + // 4810578: varargs unsafe on 32-bit integer/64-bit pointer architectures // When __cplusplus is defined, NULL is defined as 0 (32-bit constant) in @@ -68,6 +90,11 @@ // pointer when it extracts the argument, then we have a problem. // // Solution: For 64-bit architectures, redefine NULL as 64-bit constant 0. +// +// Note: this fix doesn't work well on Linux because NULL will be overwritten +// whenever a system header file is included. Linux handles NULL correctly +// through a special type '__null'. +#ifdef SOLARIS #ifdef _LP64 #undef NULL #define NULL 0L @@ -76,13 +103,25 @@ #define NULL 0 #endif #endif +#endif // NULL vs NULL_WORD: // On Linux NULL is defined as a special type '__null'. Assigning __null to // integer variable will cause gcc warning. Use NULL_WORD in places where a -// pointer is stored as integer value. -#define NULL_WORD NULL +// pointer is stored as integer value. On some platforms, sizeof(intptr_t) > +// sizeof(void*), so here we want something which is integer type, but has the +// same size as a pointer. +#ifdef LINUX + #ifdef _LP64 + #define NULL_WORD 0L + #else + #define NULL_WORD 0 + #endif +#else + #define NULL_WORD NULL +#endif +#ifndef LINUX // Compiler-specific primitive types typedef unsigned short uint16_t; #ifndef _UINT32_T @@ -100,6 +139,7 @@ typedef unsigned int uintptr_t; // If this gets an error, figure out a symbol XXX that implies the // prior definition of intptr_t, and add "&& !defined(XXX)" above. #endif +#endif // Additional Java basic types @@ -128,7 +168,7 @@ inline jdouble jdouble_cast(jlong x) { return *(jdouble*)&x; } const jlong min_jlong = CONST64(0x8000000000000000); const jlong max_jlong = CONST64(0x7fffffffffffffff); - +#ifdef SOLARIS //---------------------------------------------------------------------------------------------------- // ANSI C++ fixes // NOTE:In the ANSI committee's continuing attempt to make each version @@ -162,7 +202,7 @@ extern "C" { typedef int (*int_fnP_cond_tP_i_vP)(cond_t *cv, int scope, void *arg); typedef int (*int_fnP_cond_tP)(cond_t *cv); }; - +#endif //---------------------------------------------------------------------------------------------------- // Debugging @@ -173,7 +213,7 @@ extern "C" void breakpoint(); #define BREAKPOINT ::breakpoint() // checking for nanness - +#ifdef SOLARIS #ifdef SPARC inline int g_isnan(float f) { return isnanf(f); } #else @@ -182,6 +222,12 @@ inline int g_isnan(float f) { return isnand(f); } #endif inline int g_isnan(double f) { return isnand(f); } +#elif LINUX +inline int g_isnan(float f) { return isnanf(f); } +inline int g_isnan(double f) { return isnan(f); } +#else +#error "missing platform-specific definition here" +#endif // Checking for finiteness @@ -195,9 +241,11 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } // Misc +// NOTE: This one leads to an infinite recursion on Linux +#ifndef LINUX int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr); #define vsnprintf local_vsnprintf - +#endif // Portability macros #define PRAGMA_INTERFACE From 63a8cc420e57c2b76f2b9ddfa973a31ac4cd006a Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 12 Mar 2008 18:39:05 -0700 Subject: [PATCH 138/274] 6667089: 3/3 multiple redefinitions of a class break reflection Use instanceKlass::method_with_idnum() instead of slot() to work with RedefineClasses(). Reviewed-by: sspitsyn --- hotspot/src/share/vm/runtime/reflection.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index 55cf925e6e2..b0e8a996822 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -1548,10 +1548,11 @@ oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle } instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror)); - if (!klass->methods()->is_within_bounds(slot)) { + methodOop m = klass->method_with_idnum(slot); + if (m == NULL) { THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); } - methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot))); + methodHandle method(THREAD, m); return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD); } @@ -1564,10 +1565,11 @@ oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror))); instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(mirror)); - if (!klass->methods()->is_within_bounds(slot)) { + methodOop m = klass->method_with_idnum(slot); + if (m == NULL) { THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); } - methodHandle method(THREAD, methodOop(klass->methods()->obj_at(slot))); + methodHandle method(THREAD, m); assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor"); // Make sure klass gets initialize From 2a20e69f1a25a11f9c10a6bab364adf482e0a005 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 15:36:31 +0300 Subject: [PATCH 139/274] 6595651: Focus transfers broken for applications embedding AWT across processes Now we allow cross-process focus requests if focus is in embedder's process. Reviewed-by: ant --- .../native/sun/windows/awt_Component.cpp | 9 ++-- .../windows/native/sun/windows/awt_Frame.cpp | 6 +-- .../native/sun/windows/awt_Toolkit.cpp | 51 ++++--------------- .../windows/native/sun/windows/awt_Toolkit.h | 9 +++- 4 files changed, 27 insertions(+), 48 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index cba88cdf8c4..38be8cff948 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -2190,8 +2190,11 @@ AwtComponent::AwtSetFocus() DWORD fgProcessID; ::GetWindowThreadProcessId(fgWindow, &fgProcessID); - if (fgProcessID != ::GetCurrentProcessId()) { - // fix for 6458497. we shouldn't request focus if it is out of our application. + if (fgProcessID != ::GetCurrentProcessId() + && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID)) + { + // fix for 6458497. we shouldn't request focus if it is out of both + // our and embedder process. return FALSE; } } diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 0ba89841926..55c85b4c0b3 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -221,8 +221,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent) // Update target's dimensions to reflect this embedded window. ::GetClientRect(frame->m_hwnd, &rect); - ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, - 2); + ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2); env->SetIntField(target, AwtComponent::xID, rect.left); env->SetIntField(target, AwtComponent::yID, rect.top); @@ -231,6 +230,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent) env->SetIntField(target, AwtComponent::heightID, rect.bottom-rect.top); frame->InitPeerGraphicsConfig(env, self); + AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent); } else { jint state = env->GetIntField(target, AwtFrame::stateID); DWORD exStyle; diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index 4a8e45177aa..958ca8d871d 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -354,6 +354,7 @@ AwtToolkit::AwtToolkit() { m_dllHandle = NULL; m_displayChanged = FALSE; + m_embedderProcessID = 0; // XXX: keyboard mapping should really be moved out of AwtComponent AwtComponent::InitDynamicKeyMapTable(); @@ -1442,49 +1443,17 @@ void hang_if_shutdown(void) } } -/* - * Returns a reference to the class java.awt.Component. - */ -jclass -getComponentClass(JNIEnv *env) +// for now we support only one embedder, but should be ready for future +void AwtToolkit::RegisterEmbedderProcessId(HWND embedder) { - static jclass componentCls = NULL; - - // get global reference of java/awt/Component class (run only once) - if (componentCls == NULL) { - jclass componentClsLocal = env->FindClass("java/awt/Component"); - DASSERT(componentClsLocal != NULL); - if (componentClsLocal == NULL) { - /* exception already thrown */ - return NULL; - } - componentCls = (jclass)env->NewGlobalRef(componentClsLocal); - env->DeleteLocalRef(componentClsLocal); + if (m_embedderProcessID) { + // we already set embedder process and do not expect + // two different processes to embed the same AwtToolkit + return; } - return componentCls; -} - -/* - * Returns a reference to the class java.awt.MenuComponent. - */ -jclass -getMenuComponentClass(JNIEnv *env) -{ - static jclass menuComponentCls = NULL; - - // get global reference of java/awt/MenuComponent class (run only once) - if (menuComponentCls == NULL) { - jclass menuComponentClsLocal = env->FindClass("java/awt/MenuComponent"); - DASSERT(menuComponentClsLocal != NULL); - if (menuComponentClsLocal == NULL) { - /* exception already thrown */ - return NULL; - } - menuComponentCls = (jclass)env->NewGlobalRef(menuComponentClsLocal); - env->DeleteLocalRef(menuComponentClsLocal); - } - return menuComponentCls; + embedder = ::GetAncestor(embedder, GA_ROOT); + ::GetWindowThreadProcessId(embedder, &m_embedderProcessID); } JNIEnv* AwtToolkit::m_env; diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.h b/jdk/src/windows/native/sun/windows/awt_Toolkit.h index e7ffb1d2903..fcee2d4ad5c 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -426,10 +426,17 @@ private: */ private: BOOL m_displayChanged; /* Tracks displayChanged events */ + // 0 means we are not embedded. + DWORD m_embedderProcessID; public: BOOL HasDisplayChanged() { return m_displayChanged; } void ResetDisplayChanged() { m_displayChanged = FALSE; } + void RegisterEmbedderProcessId(HWND); + BOOL IsEmbedderProcessId(const DWORD processID) const + { + return m_embedderProcessID && (processID == m_embedderProcessID); + } private: static JNIEnv *m_env; From ee0c8e43e4eb4e13825feb2619d826fc105cb89c Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:12:56 +0300 Subject: [PATCH 140/274] 6616095: AWT's WindowDisposerRecord keeps AppContext alive too long WindowDisposerRecord should not keep strong reference to AppContext. Reviewed-by: art --- jdk/src/share/classes/java/awt/Window.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index 440a65ddec3..a0841af43e4 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. 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,7 +24,6 @@ */ package java.awt; -import java.applet.Applet; import java.awt.event.*; import java.awt.im.InputContext; import java.awt.image.BufferStrategy; @@ -355,18 +354,21 @@ public class Window extends Container implements Accessible { static class WindowDisposerRecord implements sun.java2d.DisposerRecord { final WeakReference owner; final WeakReference weakThis; - final AppContext context; + final WeakReference context; WindowDisposerRecord(AppContext context, Window victim) { owner = new WeakReference(victim.getOwner()); weakThis = victim.weakThis; - this.context = context; + this.context = new WeakReference(context); } public void dispose() { Window parent = owner.get(); if (parent != null) { parent.removeOwnedWindow(weakThis); } - Window.removeFromWindowList(context, weakThis); + AppContext ac = context.get(); + if (null != ac) { + Window.removeFromWindowList(ac, weakThis); + } } } From d51ba24908cd4aac5ff3fb7c2b7da40b9400b1dc Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:19:32 +0300 Subject: [PATCH 141/274] 6632140: minor refactoring for XWM Code cleanup and generificaion for XWM Reviewed-by: anthony --- .../classes/sun/awt/X11/XFramePeer.java | 32 ++++--- .../classes/sun/awt/X11/XNETProtocol.java | 15 ++-- .../solaris/classes/sun/awt/X11/XToolkit.java | 33 +++---- jdk/src/solaris/classes/sun/awt/X11/XWM.java | 86 +++++++++---------- 4 files changed, 82 insertions(+), 84 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java index 84469bd649f..5cd03b1b062 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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,15 +24,18 @@ */ package sun.awt.X11; -import java.util.Vector; -import java.awt.*; -import java.awt.peer.*; -import java.awt.event.*; -import sun.awt.im.*; -import sun.awt.*; -import java.util.logging.*; -import java.lang.reflect.Field; -import java.util.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.MenuBar; +import java.awt.Rectangle; +import java.awt.peer.FramePeer; +import java.util.logging.Level; +import java.util.logging.Logger; class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants { private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer"); @@ -285,19 +288,20 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants { * Let's see if this is a window state protocol message, and * if it is - decode a new state in terms of java constants. */ - Integer newState = XWM.getWM().isStateChange(this, ev); - if (newState == null) { + if (!XWM.getWM().isStateChange(this, ev)) { + stateLog.finer("either not a state atom or state has not been changed"); return; } - int changed = state ^ newState.intValue(); + final int newState = XWM.getWM().getState(this); + int changed = state ^ newState; if (changed == 0) { stateLog.finer("State is the same: " + state); return; } int old_state = state; - state = newState.intValue(); + state = newState; if ((changed & Frame.ICONIFIED) != 0) { if ((state & Frame.ICONIFIED) != 0) { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java index 8ae5334cba3..f61c476e57e 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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,17 +26,15 @@ package sun.awt.X11; -import java.awt.*; +import java.awt.Frame; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.logging.LogManager; -import java.awt.*; -import java.awt.image.*; -import java.util.*; -class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol { - final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol"); +final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol +{ + private final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol"); private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol"); + private static Logger stateLog = Logger.getLogger("sun.awt.X11.states.XNETProtocol"); /** * XStateProtocol @@ -276,6 +274,7 @@ class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol { boolean doStateProtocol() { boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE); + stateLog.finer("doStateProtocol() returns " + res); return res; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index b94d01f2257..069568519d8 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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,11 +25,9 @@ package sun.awt.X11; import java.awt.*; -import java.awt.event.*; -import java.awt.peer.*; -import java.beans.PropertyChangeListener; -import sun.awt.*; -import java.util.*; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.datatransfer.Clipboard; import java.awt.dnd.DragSource; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureEvent; @@ -37,20 +35,27 @@ import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.MouseDragGestureRecognizer; import java.awt.dnd.InvalidDnDOperationException; import java.awt.dnd.peer.DragSourceContextPeer; -import java.awt.image.*; -import java.security.*; import java.awt.im.InputMethodHighlight; import java.awt.im.spi.InputMethodDescriptor; -import java.awt.datatransfer.Clipboard; +import java.awt.image.ColorModel; +import java.awt.peer.*; +import java.beans.PropertyChangeListener; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.LookAndFeel; import javax.swing.UIDefaults; -import java.util.logging.*; +import sun.awt.*; import sun.font.FontManager; import sun.misc.PerformanceLogger; import sun.print.PrintJob2D; -import java.lang.reflect.*; -public class XToolkit extends UNIXToolkit implements Runnable, XConstants { +public final class XToolkit extends UNIXToolkit implements Runnable, XConstants +{ private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit"); private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit"); private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit"); @@ -1871,9 +1876,7 @@ public class XToolkit extends UNIXToolkit implements Runnable, XConstants { } public boolean isAlwaysOnTopSupported() { - Iterator iter = XWM.getWM().getProtocols(XLayerProtocol.class).iterator(); - while (iter.hasNext()) { - XLayerProtocol proto = (XLayerProtocol)iter.next(); + for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) { if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) { return true; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWM.java b/jdk/src/solaris/classes/sun/awt/X11/XWM.java index 68d1ff73e5f..d8e0d6b031d 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -31,20 +31,23 @@ package sun.awt.X11; import sun.misc.Unsafe; -import java.util.regex.*; +import java.awt.Insets; import java.awt.Frame; import java.awt.Rectangle; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; import java.util.logging.Level; -import java.util.logging.LogManager; import java.util.logging.Logger; -import java.awt.Insets; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Class incapsulating knowledge about window managers in general * Descendants should provide some information about specific window manager. */ -class XWM implements MWMConstants, XUtilConstants { +final class XWM implements MWMConstants, XUtilConstants +{ private final static Logger log = Logger.getLogger("sun.awt.X11.XWM"); private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM"); @@ -1026,21 +1029,21 @@ class XWM implements MWMConstants, XUtilConstants { /*****************************************************************************\ * Protocols support */ - HashMap, Collection> protocolsMap = new HashMap, Collection>(); + private HashMap, Collection> protocolsMap = new HashMap, Collection>(); /** * Returns all protocols supporting given protocol interface */ - Collection getProtocols(Class protocolInterface) { - Collection res = protocolsMap.get(protocolInterface); + Collection getProtocols(Class protocolInterface) { + Collection res = (Collection) protocolsMap.get(protocolInterface); if (res != null) { - return (Collection)res; + return res; } else { - return new LinkedList(); + return new LinkedList(); } } - void addProtocol(Class protocolInterface, XProtocol protocol) { - Collection protocols = getProtocols(protocolInterface); + private void addProtocol(Class protocolInterface, T protocol) { + Collection protocols = getProtocols(protocolInterface); protocols.add(protocol); protocolsMap.put(protocolInterface, protocols); } @@ -1085,9 +1088,7 @@ class XWM implements MWMConstants, XUtilConstants { } /* FALLTROUGH */ case Frame.MAXIMIZED_BOTH: - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { if (proto.supportsState(state)) { return true; } @@ -1105,10 +1106,8 @@ class XWM implements MWMConstants, XUtilConstants { int getExtendedState(XWindowPeer window) { - Iterator iter = getProtocols(XStateProtocol.class).iterator(); int state = 0; - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { state |= proto.getState(window); } if (state != 0) { @@ -1127,18 +1126,17 @@ class XWM implements MWMConstants, XUtilConstants { /* * Check if property change is a window state protocol message. - * If it is - return the new state as Integer, otherwise return null */ - Integer isStateChange(XDecoratedPeer window, XPropertyEvent e) { + boolean isStateChange(XDecoratedPeer window, XPropertyEvent e) { if (!window.isShowing()) { stateLog.finer("Window is not showing"); - return null; + return false; } int wm_state = window.getWMState(); if (wm_state == XlibWrapper.WithdrawnState) { stateLog.finer("WithdrawnState"); - return null; + return false; } else { stateLog.finer("Window WM_STATE is " + wm_state); } @@ -1147,26 +1145,26 @@ class XWM implements MWMConstants, XUtilConstants { is_state_change = true; } - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { is_state_change |= proto.isStateChange(e); + stateLog.finest(proto + ": is state changed = " + is_state_change); } - int res = 0; + return is_state_change; + } - if (is_state_change) { - if (wm_state == XlibWrapper.IconicState) { - res = Frame.ICONIFIED; - } else { - res = Frame.NORMAL; - } - res |= getExtendedState(window); - } - if (is_state_change) { - return Integer.valueOf(res); + /* + * Returns current state (including extended) of a given window. + */ + int getState(XDecoratedPeer window) { + int res = 0; + final int wm_state = window.getWMState(); + if (wm_state == XlibWrapper.IconicState) { + res = Frame.ICONIFIED; } else { - return null; + res = Frame.NORMAL; } + res |= getExtendedState(window); + return res; } /*****************************************************************************\ @@ -1180,9 +1178,7 @@ class XWM implements MWMConstants, XUtilConstants { * in XLayerProtocol */ void setLayer(XWindowPeer window, int layer) { - Iterator iter = getProtocols(XLayerProtocol.class).iterator(); - while (iter.hasNext()) { - XLayerProtocol proto = (XLayerProtocol)iter.next(); + for (XLayerProtocol proto : getProtocols(XLayerProtocol.class)) { if (proto.supportsLayer(layer)) { proto.setLayer(window, layer); } @@ -1191,9 +1187,7 @@ class XWM implements MWMConstants, XUtilConstants { } void setExtendedState(XWindowPeer window, int state) { - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { if (proto.supportsState(state)) { proto.setState(window, state); break; @@ -1239,9 +1233,7 @@ class XWM implements MWMConstants, XUtilConstants { void unshadeKludge(XDecoratedPeer window) { assert(window.isShowing()); - Iterator iter = getProtocols(XStateProtocol.class).iterator(); - while (iter.hasNext()) { - XStateProtocol proto = (XStateProtocol)iter.next(); + for (XStateProtocol proto : getProtocols(XStateProtocol.class)) { proto.unshadeKludge(window); } XToolkit.XSync(); From 16b0d38feb29a78190e5871c7fb4c45e8d9fcf32 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:27:20 +0300 Subject: [PATCH 142/274] 6592751: EmbeddedFrame disposal is fragile and breaks clean AppContext termination AppContext.dispose() should be ready to get exceptions during disposal of toplevels. Also now we mark windows peers as destroyed when native object has been destroyed. Reviewed-by: art --- jdk/src/share/classes/sun/awt/AppContext.java | 13 ++++++++-- .../classes/sun/awt/windows/WObjectPeer.java | 10 +++++--- jdk/src/windows/native/sun/windows/awt.h | 25 +++++++++++++------ .../native/sun/windows/awt_Component.cpp | 1 + .../windows/native/sun/windows/awt_Object.cpp | 5 +++- .../windows/native/sun/windows/awt_Object.h | 3 ++- 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/jdk/src/share/classes/sun/awt/AppContext.java b/jdk/src/share/classes/sun/awt/AppContext.java index 038f5936aa5..0370f8333a3 100644 --- a/jdk/src/share/classes/sun/awt/AppContext.java +++ b/jdk/src/share/classes/sun/awt/AppContext.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems, Inc. 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 @@ -40,6 +40,8 @@ import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; @@ -126,6 +128,7 @@ import java.beans.PropertyChangeListener; * @author Fred Ecks */ public final class AppContext { + private static final Logger log = Logger.getLogger("sun.awt.AppContext"); /* Since the contents of an AppContext are unique to each Java * session, this class should never be serialized. */ @@ -385,7 +388,13 @@ public final class AppContext { public void run() { Window[] windowsToDispose = Window.getOwnerlessWindows(); for (Window w : windowsToDispose) { - w.dispose(); + try { + w.dispose(); + } catch (Throwable t) { + if (log.isLoggable(Level.FINER)) { + log.log(Level.FINER, "exception occured while disposing app context", t); + } + } } AccessController.doPrivileged(new PrivilegedAction() { public Object run() { diff --git a/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java b/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java index efe00a63950..d67329e8422 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -30,8 +30,12 @@ abstract class WObjectPeer { initIDs(); } - long pData; // The Windows handle for the native widget. - Object target; // The associated AWT object. + // The Windows handle for the native widget. + long pData; + // if the native peer has been destroyed + boolean destroyed = false; + // The associated AWT object. + Object target; private volatile boolean disposed; diff --git a/jdk/src/windows/native/sun/windows/awt.h b/jdk/src/windows/native/sun/windows/awt.h index 9043367f679..2a1d9904c9b 100644 --- a/jdk/src/windows/native/sun/windows/awt.h +++ b/jdk/src/windows/native/sun/windows/awt.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -47,7 +47,7 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_GOTO(peer, "peer", where); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ goto where; \ } \ } @@ -63,7 +63,7 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_RETURN(peer, "peer"); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return; \ } \ } @@ -96,7 +96,7 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return 0; \ } \ } @@ -105,16 +105,27 @@ typedef AwtObject* PDATA; JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \ pData = JNI_GET_PDATA(peer); \ if (pData == NULL) { \ - JNU_ThrowNullPointerException(env, "null pData"); \ + THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \ return val; \ } \ } +#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \ + jboolean destroyed = JNI_GET_DESTROYED(peer); \ + if (destroyed != JNI_TRUE) { \ + JNU_ThrowNullPointerException(env, "null pData"); \ + } \ +} + #define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID) +#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID) #define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \ - AwtObject::pDataID, \ - (jlong)data) + AwtObject::pDataID, \ + (jlong)data) +#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \ + AwtObject::destroyedID, \ + JNI_TRUE) /* /NEW JNI */ /* diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 38be8cff948..e1b3a7d1dcd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -5403,6 +5403,7 @@ void AwtComponent::UnlinkObjects() if (m_peerObject) { env->SetLongField(m_peerObject, AwtComponent::hwndID, 0); JNI_SET_PDATA(m_peerObject, static_cast(NULL)); + JNI_SET_DESTROYED(m_peerObject); env->DeleteGlobalRef(m_peerObject); m_peerObject = NULL; } diff --git a/jdk/src/windows/native/sun/windows/awt_Object.cpp b/jdk/src/windows/native/sun/windows/awt_Object.cpp index 96153f1600f..aab7e98b502 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Object.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -39,6 +39,7 @@ static BOOL reportEvents = FALSE; */ jfieldID AwtObject::pDataID; +jfieldID AwtObject::destroyedID; jfieldID AwtObject::targetID; jclass AwtObject::wObjectPeerClass; jmethodID AwtObject::getPeerForTargetMID; @@ -223,6 +224,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) { AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls); AwtObject::pDataID = env->GetFieldID(cls, "pData", "J"); + AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z"); AwtObject::targetID = env->GetFieldID(cls, "target", "Ljava/lang/Object;"); @@ -233,6 +235,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) { AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;"); DASSERT(AwtObject::pDataID != NULL); + DASSERT(AwtObject::destroyedID != NULL); DASSERT(AwtObject::targetID != NULL); DASSERT(AwtObject::getPeerForTargetMID != NULL); DASSERT(AwtObject::createErrorID != NULL); diff --git a/jdk/src/windows/native/sun/windows/awt_Object.h b/jdk/src/windows/native/sun/windows/awt_Object.h index 3e69dd89cca..bcfa6b6f555 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.h +++ b/jdk/src/windows/native/sun/windows/awt_Object.h @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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 @@ -51,6 +51,7 @@ public: /* sun.awt.windows.WObjectPeer field and method ids */ static jfieldID pDataID; + static jfieldID destroyedID; static jfieldID targetID; static jmethodID getPeerForTargetMID; From c02f0bd9b7120c911fc3fa4252265a6b6611fa9d Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:32:15 +0300 Subject: [PATCH 143/274] 6603256: Startup: Defer initialization of DropTarget's flavorMap SystemFlavorMap is lazily initialized now. Reviewed-by: uta --- .../awt/datatransfer/SystemFlavorMap.java | 115 ++++++++++++------ .../classes/java/awt/dnd/DropTarget.java | 10 +- 2 files changed, 85 insertions(+), 40 deletions(-) diff --git a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java index c84e838403a..77eb2bcec61 100644 --- a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java +++ b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. 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,6 @@ import java.util.WeakHashMap; import sun.awt.datatransfer.DataTransferer; - /** * The SystemFlavorMap is a configurable map between "natives" (Strings), which * correspond to platform-specific data formats, and "flavors" (DataFlavors), @@ -117,15 +116,50 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { /** * Maps native Strings to Lists of DataFlavors (or base type Strings for * text DataFlavors). + * Do not use the field directly, use getNativeToFlavor() instead. */ private Map nativeToFlavor = new HashMap(); + /** + * Accessor to nativeToFlavor map. Since we use lazy initialization we must + * use this accessor instead of direct access to the field which may not be + * initialized yet. This method will initialize the field if needed. + * + * @return nativeToFlavor + */ + private Map getNativeToFlavor() { + if (!isMapInitialized) { + initSystemFlavorMap(); + } + return nativeToFlavor; + } + /** * Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of * native Strings. + * Do not use the field directly, use getFlavorToNative() instead. */ private Map flavorToNative = new HashMap(); + /** + * Accessor to flavorToNative map. Since we use lazy initialization we must + * use this accessor instead of direct access to the field which may not be + * initialized yet. This method will initialize the field if needed. + * + * @return flavorToNative + */ + private synchronized Map getFlavorToNative() { + if (!isMapInitialized) { + initSystemFlavorMap(); + } + return flavorToNative; + } + + /** + * Shows if the object has been initialized. + */ + private boolean isMapInitialized = false; + /** * Caches the result of getNativesForFlavor(). Maps DataFlavors to * SoftReferences which reference Lists of String natives. @@ -169,15 +203,24 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { return fm; } - /** - * Constructs a SystemFlavorMap by reading flavormap.properties and - * AWT.DnD.flavorMapFileURL. - */ private SystemFlavorMap() { - BufferedReader flavormapDotProperties = (BufferedReader) + } + + /** + * Initializes a SystemFlavorMap by reading flavormap.properties and + * AWT.DnD.flavorMapFileURL. + * For thread-safety must be called under lock on this. + */ + private void initSystemFlavorMap() { + if (isMapInitialized) { + return; + } + + isMapInitialized = true; + BufferedReader flavormapDotProperties = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { + new java.security.PrivilegedAction() { + public BufferedReader run() { String fileName = System.getProperty("java.home") + File.separator + @@ -197,12 +240,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } }); - BufferedReader flavormapURL = (BufferedReader) + BufferedReader flavormapURL = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - String url = Toolkit.getDefaultToolkit().getProperty - ("AWT.DnD.flavorMapFileURL", null); + new java.security.PrivilegedAction() { + public BufferedReader run() { + String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null); if (url == null) { return null; @@ -237,7 +279,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } } } - /** * Copied code from java.util.Properties. Parsing the data ourselves is the * only way to handle duplicate keys and values. @@ -388,11 +429,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { // For text/* flavors, store mappings in separate maps to // enable dynamic mapping generation at a run-time. if ("text".equals(flavor.getPrimaryType())) { - store(value, key, flavorToNative); - store(key, value, nativeToFlavor); + store(value, key, getFlavorToNative()); + store(key, value, getNativeToFlavor()); } else { - store(flavor, key, flavorToNative); - store(key, flavor, nativeToFlavor); + store(flavor, key, getFlavorToNative()); + store(key, flavor, getNativeToFlavor()); } } } @@ -494,7 +535,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { * only if the specified native is encoded as a Java MIME type. */ private List nativeToFlavorLookup(String nat) { - List flavors = (List)nativeToFlavor.get(nat); + List flavors = (List)getNativeToFlavor().get(nat); if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { DataTransferer transferer = DataTransferer.getInstance(); @@ -530,15 +571,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (flavor != null) { flavors = new ArrayList(1); - nativeToFlavor.put(nat, flavors); + getNativeToFlavor().put(nat, flavors); flavors.add(flavor); getFlavorsForNativeCache.remove(nat); getFlavorsForNativeCache.remove(null); - List natives = (List)flavorToNative.get(flavor); + List natives = (List)getFlavorToNative().get(flavor); if (natives == null) { natives = new ArrayList(1); - flavorToNative.put(flavor, natives); + getFlavorToNative().put(flavor, natives); } natives.add(nat); getNativesForFlavorCache.remove(flavor); @@ -559,7 +600,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { */ private List flavorToNativeLookup(final DataFlavor flav, final boolean synthesize) { - List natives = (List)flavorToNative.get(flav); + List natives = (List)getFlavorToNative().get(flav); if (flav != null && !disabledMappingGenerationKeys.contains(flav)) { DataTransferer transferer = DataTransferer.getInstance(); @@ -584,15 +625,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { if (synthesize) { String encoded = encodeDataFlavor(flav); natives = new ArrayList(1); - flavorToNative.put(flav, natives); + getFlavorToNative().put(flav, natives); natives.add(encoded); getNativesForFlavorCache.remove(flav); getNativesForFlavorCache.remove(null); - List flavors = (List)nativeToFlavor.get(encoded); + List flavors = (List)getNativeToFlavor().get(encoded); if (flavors == null) { flavors = new ArrayList(1); - nativeToFlavor.put(encoded, flavors); + getNativeToFlavor().put(encoded, flavors); } flavors.add(flav); getFlavorsForNativeCache.remove(encoded); @@ -645,7 +686,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } if (flav == null) { - retval = new ArrayList(nativeToFlavor.keySet()); + retval = new ArrayList(getNativeToFlavor().keySet()); } else if (disabledMappingGenerationKeys.contains(flav)) { // In this case we shouldn't synthesize a native for this flavor, // since its mappings were explicitly specified. @@ -655,7 +696,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { // For text/* flavors, flavor-to-native mappings specified in // flavormap.properties are stored per flavor's base type. if ("text".equals(flav.getPrimaryType())) { - retval = (List)flavorToNative.get(flav.mimeType.getBaseType()); + retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType()); if (retval != null) { // To prevent the List stored in the map from modification. retval = new ArrayList(retval); @@ -663,7 +704,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } // Also include text/plain natives, but don't duplicate Strings - List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE); + List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE); if (textPlainList != null && !textPlainList.isEmpty()) { // To prevent the List stored in the map from modification. @@ -699,7 +740,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { } } } else if (DataTransferer.isFlavorNoncharsetTextType(flav)) { - retval = (List)flavorToNative.get(flav.mimeType.getBaseType()); + retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType()); if (retval == null || retval.isEmpty()) { retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); @@ -1025,10 +1066,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - List natives = (List)flavorToNative.get(flav); + List natives = (List)getFlavorToNative().get(flav); if (natives == null) { natives = new ArrayList(1); - flavorToNative.put(flav, natives); + getFlavorToNative().put(flav, natives); } else if (natives.contains(nat)) { return; } @@ -1071,7 +1112,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - flavorToNative.remove(flav); + getFlavorToNative().remove(flav); for (int i = 0; i < natives.length; i++) { addUnencodedNativeForFlavor(flav, natives[i]); } @@ -1105,10 +1146,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - List flavors = (List)nativeToFlavor.get(nat); + List flavors = (List)getNativeToFlavor().get(nat); if (flavors == null) { flavors = new ArrayList(1); - nativeToFlavor.put(nat, flavors); + getNativeToFlavor().put(nat, flavors); } else if (flavors.contains(flav)) { return; } @@ -1150,7 +1191,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable { throw new NullPointerException("null arguments not permitted"); } - nativeToFlavor.remove(nat); + getNativeToFlavor().remove(nat); for (int i = 0; i < flavors.length; i++) { addFlavorForUnencodedNative(nat, flavors[i]); } diff --git a/jdk/src/share/classes/java/awt/dnd/DropTarget.java b/jdk/src/share/classes/java/awt/dnd/DropTarget.java index 5995c885b2f..aa75ec71541 100644 --- a/jdk/src/share/classes/java/awt/dnd/DropTarget.java +++ b/jdk/src/share/classes/java/awt/dnd/DropTarget.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. 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 @@ -110,7 +110,11 @@ public class DropTarget implements DropTargetListener, Serializable { setActive(act); } - if (fm != null) flavorMap = fm; + if (fm != null) { + flavorMap = fm; + } else { + flavorMap = SystemFlavorMap.getDefaultFlavorMap(); + } } /** @@ -850,5 +854,5 @@ public class DropTarget implements DropTargetListener, Serializable { * The FlavorMap */ - private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap(); + private transient FlavorMap flavorMap; } From 43fd376e712261f13303c1d5461ff26c1d6e7d5d Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:42:52 +0300 Subject: [PATCH 144/274] 6607163: Linux: Cannot copy image from Java to OpenOffice TARGETS should have type ATOM Reviewed-by: denis --- jdk/src/solaris/classes/sun/awt/X11/XSelection.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java index 9759a8175ca..1d34978f8e3 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -281,8 +281,10 @@ public class XSelection { if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() && (targetsGetter.getActualType() == XAtom.XA_ATOM || targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) && - targetsGetter.getActualFormat() == 32) { - + targetsGetter.getActualFormat() == 32) + { + // we accept property with TARGETS type to be compatible with old jdks + // see 6607163 int count = (int)targetsGetter.getNumberOfItems(); if (count > 0) { long atoms = targetsGetter.getData(); @@ -687,7 +689,7 @@ public class XSelection { XToolkit.awtLock(); try { XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor, - property, format, dataFormat, + property, XAtom.XA_ATOM, dataFormat, XlibWrapper.PropModeReplace, nativeDataPtr, count); } finally { From 59d9653ecfc32e3d801f7abfb2642e48e1bd8fd5 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:47:40 +0300 Subject: [PATCH 145/274] 6636369: sun.awt.datatransfer.DataTransferer contains double-check idiom Double-check has been removed Reviewed-by: dav --- .../sun/awt/datatransfer/DataTransferer.java | 100 +++++++++--------- 1 file changed, 48 insertions(+), 52 deletions(-) diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index 5dd12441081..d96008309fb 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems, Inc. 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 @@ -270,62 +270,58 @@ public abstract class DataTransferer { * instead, null will be returned. */ public static DataTransferer getInstance() { - if (transferer == null) { - synchronized (DataTransferer.class) { - if (transferer == null) { - final String name = SunToolkit. - getDataTransfererClassName(); - if (name != null) { - PrivilegedAction action = new PrivilegedAction() { - public Object run() { - Class cls = null; - Method method = null; - Object ret = null; + synchronized (DataTransferer.class) { + if (transferer == null) { + final String name = SunToolkit.getDataTransfererClassName(); + if (name != null) { + PrivilegedAction action = new PrivilegedAction() + { + public DataTransferer run() { + Class cls = null; + Method method = null; + DataTransferer ret = null; - try { - cls = Class.forName(name); - } catch (ClassNotFoundException e) { - ClassLoader cl = ClassLoader. - getSystemClassLoader(); - if (cl != null) { - try { - cls = cl.loadClass(name); - } catch (ClassNotFoundException ee) { - ee.printStackTrace(); - throw new AWTError("DataTransferer not found: " + name); - } - } - } - if (cls != null) { + try { + cls = Class.forName(name); + } catch (ClassNotFoundException e) { + ClassLoader cl = ClassLoader. + getSystemClassLoader(); + if (cl != null) { try { - method = cls.getDeclaredMethod - ("getInstanceImpl"); - method.setAccessible(true); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - throw new AWTError("Cannot instantiate DataTransferer: " + name); - } catch (SecurityException e) { - e.printStackTrace(); - throw new AWTError("Access is denied for DataTransferer: " + name); + cls = cl.loadClass(name); + } catch (ClassNotFoundException ee) { + ee.printStackTrace(); + throw new AWTError("DataTransferer not found: " + name); } } - if (method != null) { - try { - ret = method.invoke(null); - } catch (InvocationTargetException e) { - e.printStackTrace(); - throw new AWTError("Cannot instantiate DataTransferer: " + name); - } catch (IllegalAccessException e) { - e.printStackTrace(); - throw new AWTError("Cannot access DataTransferer: " + name); - } - } - return ret; } - }; - transferer = (DataTransferer) - AccessController.doPrivileged(action); - } + if (cls != null) { + try { + method = cls.getDeclaredMethod("getInstanceImpl"); + method.setAccessible(true); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + throw new AWTError("Cannot instantiate DataTransferer: " + name); + } catch (SecurityException e) { + e.printStackTrace(); + throw new AWTError("Access is denied for DataTransferer: " + name); + } + } + if (method != null) { + try { + ret = (DataTransferer) method.invoke(null); + } catch (InvocationTargetException e) { + e.printStackTrace(); + throw new AWTError("Cannot instantiate DataTransferer: " + name); + } catch (IllegalAccessException e) { + e.printStackTrace(); + throw new AWTError("Cannot access DataTransferer: " + name); + } + } + return ret; + } + }; + transferer = AccessController.doPrivileged(action); } } } From 794142ee36e01f4e5f3daf2268ec1beeb7f80f32 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:51:04 +0300 Subject: [PATCH 146/274] 6636331: ConcurrentModificationException in AppContext code Added synchronization to AppContext.getAppContexts() Reviewed-by: art --- jdk/src/share/classes/sun/awt/AppContext.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/awt/AppContext.java b/jdk/src/share/classes/sun/awt/AppContext.java index 0370f8333a3..901be0b9a1b 100644 --- a/jdk/src/share/classes/sun/awt/AppContext.java +++ b/jdk/src/share/classes/sun/awt/AppContext.java @@ -146,7 +146,9 @@ public final class AppContext { * Returns a set containing all AppContexts. */ public static Set getAppContexts() { - return new HashSet(threadGroup2appContext.values()); + synchronized (threadGroup2appContext) { + return new HashSet(threadGroup2appContext.values()); + } } /* The main "system" AppContext, used by everything not otherwise From 9c0e7108a33a385bad3ee7c909c814c3f932202e Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:54:51 +0300 Subject: [PATCH 147/274] 6636370: minor corrections and simplification of code in AppContext MainAppContext, isDisposed, and numAppContexts has beem made volatile. mostRecentThreadAppContext has been rewritten using ThreadLocal. Reviewed-by: art --- jdk/src/share/classes/sun/awt/AppContext.java | 150 ++++++++---------- 1 file changed, 63 insertions(+), 87 deletions(-) diff --git a/jdk/src/share/classes/sun/awt/AppContext.java b/jdk/src/share/classes/sun/awt/AppContext.java index 901be0b9a1b..4bdc337970b 100644 --- a/jdk/src/share/classes/sun/awt/AppContext.java +++ b/jdk/src/share/classes/sun/awt/AppContext.java @@ -154,7 +154,7 @@ public final class AppContext { /* The main "system" AppContext, used by everything not otherwise contained in another AppContext. */ - private static AppContext mainAppContext = null; + private static volatile AppContext mainAppContext = null; /* * The hash map associated with this AppContext. A private delegate @@ -179,31 +179,30 @@ public final class AppContext { public static final String DISPOSED_PROPERTY_NAME = "disposed"; public static final String GUI_DISPOSED = "guidisposed"; - private boolean isDisposed = false; // true if AppContext is disposed + private volatile boolean isDisposed = false; // true if AppContext is disposed public boolean isDisposed() { return isDisposed; } - static { // On the main Thread, we get the ThreadGroup, make a corresponding // AppContext, and instantiate the Java EventQueue. This way, legacy // code is unaffected by the move to multiple AppContext ability. AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ThreadGroup currentThreadGroup = - Thread.currentThread().getThreadGroup(); - ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); - while (parentThreadGroup != null) { - // Find the root ThreadGroup to construct our main AppContext - currentThreadGroup = parentThreadGroup; - parentThreadGroup = currentThreadGroup.getParent(); + public Object run() { + ThreadGroup currentThreadGroup = + Thread.currentThread().getThreadGroup(); + ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); + while (parentThreadGroup != null) { + // Find the root ThreadGroup to construct our main AppContext + currentThreadGroup = parentThreadGroup; + parentThreadGroup = currentThreadGroup.getParent(); + } + mainAppContext = new AppContext(currentThreadGroup); + numAppContexts = 1; + return mainAppContext; } - mainAppContext = new AppContext(currentThreadGroup); - numAppContexts = 1; - return mainAppContext; - } }); } @@ -214,7 +213,7 @@ public final class AppContext { * number is 1. If so, it returns the sole AppContext without * checking Thread.currentThread(). */ - private static int numAppContexts; + private static volatile int numAppContexts; /* * The context ClassLoader that was used to create this AppContext. @@ -241,14 +240,15 @@ public final class AppContext { threadGroup2appContext.put(threadGroup, this); this.contextClassLoader = - (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public ClassLoader run() { return Thread.currentThread().getContextClassLoader(); } }); } - private static MostRecentThreadAppContext mostRecentThreadAppContext = null; + private static final ThreadLocal threadAppContext = + new ThreadLocal(); /** * Returns the appropriate AppContext for the caller, @@ -265,59 +265,46 @@ public final class AppContext { if (numAppContexts == 1) // If there's only one system-wide, return mainAppContext; // return the main system AppContext. - final Thread currentThread = Thread.currentThread(); + AppContext appContext = threadAppContext.get(); - AppContext appContext = null; + if (null == appContext) { + appContext = AccessController.doPrivileged(new PrivilegedAction() + { + public AppContext run() { + // Get the current ThreadGroup, and look for it and its + // parents in the hash from ThreadGroup to AppContext -- + // it should be found, because we use createNewContext() + // when new AppContext objects are created. + ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup threadGroup = currentThreadGroup; + AppContext context = threadGroup2appContext.get(threadGroup); + while (context == null) { + threadGroup = threadGroup.getParent(); + if (threadGroup == null) { + // If we get here, we're running under a ThreadGroup that + // has no AppContext associated with it. This should never + // happen, because createNewContext() should be used by the + // toolkit to create the ThreadGroup that everything runs + // under. + throw new RuntimeException("Invalid ThreadGroup"); + } + context = threadGroup2appContext.get(threadGroup); + } + // In case we did anything in the above while loop, we add + // all the intermediate ThreadGroups to threadGroup2appContext + // so we won't spin again. + for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { + threadGroup2appContext.put(tg, context); + } + // Now we're done, so we cache the latest key/value pair. + // (we do this before checking with any AWTSecurityManager, so if + // this Thread equates with the main AppContext in the cache, it + // still will) + threadAppContext.set(context); - // Note: this most recent Thread/AppContext caching is thread-hot. - // A simple test using SwingSet found that 96.8% of lookups - // were matched using the most recent Thread/AppContext. By - // instantiating a simple MostRecentThreadAppContext object on - // cache misses, the cache hits can be processed without - // synchronization. - - MostRecentThreadAppContext recent = mostRecentThreadAppContext; - if ((recent != null) && (recent.thread == currentThread)) { - appContext = recent.appContext; // Cache hit - } else { - appContext = (AppContext)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - // Get the current ThreadGroup, and look for it and its - // parents in the hash from ThreadGroup to AppContext -- - // it should be found, because we use createNewContext() - // when new AppContext objects are created. - ThreadGroup currentThreadGroup = currentThread.getThreadGroup(); - ThreadGroup threadGroup = currentThreadGroup; - AppContext context = threadGroup2appContext.get(threadGroup); - while (context == null) { - threadGroup = threadGroup.getParent(); - if (threadGroup == null) { - // If we get here, we're running under a ThreadGroup that - // has no AppContext associated with it. This should never - // happen, because createNewContext() should be used by the - // toolkit to create the ThreadGroup that everything runs - // under. - throw new RuntimeException("Invalid ThreadGroup"); + return context; } - context = threadGroup2appContext.get(threadGroup); - } - // In case we did anything in the above while loop, we add - // all the intermediate ThreadGroups to threadGroup2appContext - // so we won't spin again. - for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { - threadGroup2appContext.put(tg, context); - } - // Now we're done, so we cache the latest key/value pair. - // (we do this before checking with any AWTSecurityManager, so if - // this Thread equates with the main AppContext in the cache, it - // still will) - mostRecentThreadAppContext = - new MostRecentThreadAppContext(currentThread, context); - - return context; - } - }); + }); } if (appContext == mainAppContext) { @@ -326,9 +313,9 @@ public final class AppContext { // allow it to choose the AppContext to return. SecurityManager securityManager = System.getSecurityManager(); if ((securityManager != null) && - (securityManager instanceof AWTSecurityManager)) { - AWTSecurityManager awtSecMgr = - (AWTSecurityManager)securityManager; + (securityManager instanceof AWTSecurityManager)) + { + AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager; AppContext secAppContext = awtSecMgr.getAppContext(); if (secAppContext != null) { appContext = secAppContext; // Return what we're told @@ -455,7 +442,7 @@ public final class AppContext { // Threads in the ThreadGroup to exit. long startTime = System.currentTimeMillis(); - long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT; + long endTime = startTime + THREAD_INTERRUPT_TIMEOUT; while ((this.threadGroup.activeCount() > 0) && (System.currentTimeMillis() < endTime)) { try { @@ -470,7 +457,7 @@ public final class AppContext { // Threads in the ThreadGroup to die. startTime = System.currentTimeMillis(); - endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT; + endTime = startTime + THREAD_INTERRUPT_TIMEOUT; while ((this.threadGroup.activeCount() > 0) && (System.currentTimeMillis() < endTime)) { try { @@ -489,10 +476,7 @@ public final class AppContext { } threadGroup2appContext.remove(this.threadGroup); - MostRecentThreadAppContext recent = mostRecentThreadAppContext; - if ((recent != null) && (recent.appContext == this)) - mostRecentThreadAppContext = null; - // If the "most recent" points to this, clear it for GC + threadAppContext.set(null); // Finally, we destroy the ThreadGroup entirely. try { @@ -675,6 +659,7 @@ public final class AppContext { * Returns a string representation of this AppContext. * @since 1.2 */ + @Override public String toString() { return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]"; } @@ -780,15 +765,6 @@ public final class AppContext { } } -final class MostRecentThreadAppContext { - final Thread thread; - final AppContext appContext; - MostRecentThreadAppContext(Thread key, AppContext value) { - thread = key; - appContext = value; - } -} - final class MostRecentKeyValue { Object key; Object value; From a7dad49796f6ca97a93ebeef01a66c098f46359b Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 16:56:54 +0300 Subject: [PATCH 148/274] 6636368: XAtom contains unused code Unused code has been removed Reviewed-by: dcherepanov --- .../solaris/classes/sun/awt/X11/XAtom.java | 34 +++---------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XAtom.java b/jdk/src/solaris/classes/sun/awt/X11/XAtom.java index b98fc9b8ee9..b72e790a043 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XAtom.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XAtom.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -58,7 +58,7 @@ package sun.awt.X11; import sun.misc.Unsafe; import java.util.HashMap; -public class XAtom { +public final class XAtom { // Order of lock: XAWTLock -> XAtom.class @@ -175,7 +175,7 @@ public class XAtom { public static XAtom get(String name) { XAtom xatom = lookup(name); if (xatom == null) { - xatom = new XAtom(name); + xatom = new XAtom(XToolkit.getDisplay(), name); } return xatom; } @@ -232,10 +232,6 @@ public class XAtom { this(display, name, true); } - private XAtom(String name) { - this(XToolkit.getDisplay(), name, true); - } - public XAtom(String name, boolean autoIntern) { this(XToolkit.getDisplay(), name, autoIntern); } @@ -262,7 +258,7 @@ public class XAtom { * @since 1.5 */ - public XAtom(long display, String name, boolean autoIntern) { + private XAtom(long display, String name, boolean autoIntern) { this.name = name; this.display = display; if (autoIntern) { @@ -651,28 +647,6 @@ public class XAtom { } } - /** - * Initializes atom with name and display values - */ - public void setValues(long display, String name, boolean autoIntern) { - this.display = display; - this.name = name; - if (autoIntern) { - XToolkit.awtLock(); - try { - atom = XlibWrapper.InternAtom(display,name,0); - } finally { - XToolkit.awtUnlock(); - } - } - register(); - } - - public void setValues(long display, long atom) { - this.display = display; - this.atom = atom; - register(); - } public void setValues(long display, String name, long atom) { this.display = display; this.atom = atom; From 3c81ec385171c2b969b3d2e8b9d06624879ecea5 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 17:04:54 +0300 Subject: [PATCH 149/274] 6645885: small refactoring for XContentWindow Move createContent() method from XDecoratedPeer to XContentWindow, so only XContentWindow keep information about the way we position it. Reviewed-by: anthony --- .../classes/sun/awt/X11/XContentWindow.java | 34 ++++++++++++++----- .../classes/sun/awt/X11/XDecoratedPeer.java | 25 +++----------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java index 72737df0691..268f7f5d151 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -39,16 +39,37 @@ import sun.awt.ComponentAccessor; * This class implements window which serves as content window for decorated frames. * Its purpose to provide correct events dispatching for the complex * constructs such as decorated frames. + * + * It should always be located at (- left inset, - top inset) in the associated + * decorated window. So coordinates in it would be the same as java coordinates. */ -public class XContentWindow extends XWindow implements XConstants { +public final class XContentWindow extends XWindow implements XConstants { private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow"); - XDecoratedPeer parentFrame; + static XContentWindow createContent(XDecoratedPeer parentFrame) { + final WindowDimensions dims = parentFrame.getDimensions(); + Rectangle rec = dims.getBounds(); + // Fix for - set the location of the content window to the (-left inset, -top inset) + Insets ins = dims.getInsets(); + if (ins != null) { + rec.x = -ins.left; + rec.y = -ins.top; + } else { + rec.x = 0; + rec.y = 0; + } + final XContentWindow cw = new XContentWindow(parentFrame, rec); + cw.xSetVisible(true); + return cw; + } + + private final XDecoratedPeer parentFrame; // A list of expose events that come when the parentFrame is iconified - private java.util.List iconifiedExposeEvents = new java.util.ArrayList(); + private final java.util.List iconifiedExposeEvents = + new java.util.ArrayList(); - XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) { + private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) { super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds); this.parentFrame = parentFrame; } @@ -63,9 +84,6 @@ public class XContentWindow extends XWindow implements XConstants { } } - void initialize() { - xSetVisible(true); - } protected String getWMName() { return "Content window"; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java index a6b8c36f8f6..07b7e1cde0f 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java @@ -98,8 +98,7 @@ class XDecoratedPeer extends XWindowPeer { // happen after the X window is created. initResizability(); updateSizeHints(dimensions); - content = createContent(dimensions); - content.initialize(); + content = XContentWindow.createContent(this); if (warningWindow != null) { warningWindow.toFront(); } @@ -160,20 +159,6 @@ class XDecoratedPeer extends XWindowPeer { } } - XContentWindow createContent(WindowDimensions dims) { - Rectangle rec = dims.getBounds(); - // Fix for - set the location of the content window to the (-left inset, -top inset) - Insets ins = dims.getInsets(); - if (ins != null) { - rec.x = -ins.left; - rec.y = -ins.top; - } else { - rec.x = 0; - rec.y = 0; - } - return new XContentWindow(this, rec); - } - XFocusProxyWindow createFocusProxy() { return new XFocusProxyWindow(this); } @@ -286,7 +271,7 @@ class XDecoratedPeer extends XWindowPeer { return; } Component t = (Component)target; - if (getDecorations() == winAttr.AWT_DECOR_NONE) { + if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) { setReparented(true); insets_corrected = true; reshape(dimensions, SET_SIZE, false); @@ -651,12 +636,12 @@ class XDecoratedPeer extends XWindowPeer { } if (!isReparented() && isVisible() && runningWM != XWM.NO_WM && !XWM.isNonReparentingWM() - && getDecorations() != winAttr.AWT_DECOR_NONE) { + && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) { insLog.fine("- visible but not reparented, skipping"); return; } //Last chance to correct insets - if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) { + if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) { long parent = XlibUtil.getParentWindow(window); Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null; if (insLog.isLoggable(Level.FINER)) { @@ -870,7 +855,7 @@ class XDecoratedPeer extends XWindowPeer { return getSize().height; } - public WindowDimensions getDimensions() { + final public WindowDimensions getDimensions() { return dimensions; } From 205971fd7c14112fc9e6024ea1cbb757fef8bfbe Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 17:08:15 +0300 Subject: [PATCH 150/274] 6645856: static field XWindowPeer.defaultFont hides XWindow.defaultFont Unnedded code has been removed. Added getter for XWindow.defaultFont to initialize it lazily. Reviewed-by: dav --- .../classes/sun/awt/X11/XComponentPeer.java | 11 ++-------- .../classes/sun/awt/X11/XMenuItemPeer.java | 6 +++--- .../classes/sun/awt/X11/XPopupMenuPeer.java | 6 +++--- .../classes/sun/awt/X11/XTrayIconPeer.java | 7 ++----- .../solaris/classes/sun/awt/X11/XWindow.java | 20 +++++++++++-------- .../classes/sun/awt/X11/XWindowPeer.java | 10 ++-------- 6 files changed, 24 insertions(+), 36 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java index 4657f75c49b..fb687e36830 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -31,17 +31,13 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Cursor; -import java.awt.DefaultKeyboardFocusManager; import java.awt.Dimension; -import java.awt.Event; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.KeyboardFocusManager; -import java.awt.MenuBar; -import java.awt.Point; import java.awt.Rectangle; import java.awt.SystemColor; import java.awt.Toolkit; @@ -60,12 +56,9 @@ import java.awt.event.InvocationEvent; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; -import java.awt.peer.CanvasPeer; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.LightweightPeer; -import java.awt.peer.PanelPeer; -import java.awt.peer.WindowPeer; import java.lang.reflect.*; import java.security.*; import java.util.Collection; @@ -821,7 +814,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget public void setFont(Font f) { synchronized (getStateLock()) { if (f == null) { - f = defaultFont; + f = XWindow.getDefaultFont(); } font = f; } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java index c679dbecd5d..ec80cebcec1 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -218,7 +218,7 @@ public class XMenuItemPeer implements MenuItemPeer { Font getTargetFont() { if (target == null) { - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } try { return (Font)m_getFont.invoke(target, new Object[0]); @@ -227,7 +227,7 @@ public class XMenuItemPeer implements MenuItemPeer { } catch (InvocationTargetException e) { e.printStackTrace(); } - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } String getTargetLabel() { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java index 8523bd7fffa..55fcfb5743f 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -187,7 +187,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer { //Fix for 6267144: PIT: Popup menu label is not shown, XToolkit Font getTargetFont() { if (popupMenuTarget == null) { - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } try { return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]); @@ -196,7 +196,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer { } catch (InvocationTargetException e) { e.printStackTrace(); } - return XWindow.defaultFont; + return XWindow.getDefaultFont(); } String getTargetLabel() { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java index c9b9a1abfd3..5c8ccd02913 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -31,11 +31,8 @@ import java.awt.peer.TrayIconPeer; import sun.awt.*; import java.awt.image.*; import java.text.BreakIterator; -import java.util.Vector; -import java.lang.reflect.Field; import java.util.logging.Logger; import java.util.logging.Level; -import java.util.AbstractQueue; import java.util.concurrent.ArrayBlockingQueue; import java.security.AccessController; import java.security.PrivilegedAction; @@ -629,7 +626,7 @@ public class XTrayIconPeer implements TrayIconPeer { final static int TOOLTIP_MAX_LENGTH = 64; final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5; final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220); - final static Font TOOLTIP_TEXT_FONT = XWindow.defaultFont; + final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont(); Tooltip(XTrayIconPeer xtiPeer, Frame parent) { super(parent, Color.black); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java index 9e3c877fa11..2d55ef889fb 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -92,8 +92,16 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { SurfaceData surfaceData; XRepaintArea paintArea; + // fallback default font object - final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); + private static Font defaultFont; + + static synchronized Font getDefaultFont() { + if (null == defaultFont) { + defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); + } + return defaultFont; + } /* * Keeps all buttons which were pressed at the time of the last mouse @@ -333,7 +341,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { } Font font = afont; if (font == null) { - font = defaultFont; + font = XWindow.getDefaultFont(); } return new SunGraphics2D(surfData, fgColor, bgColor, font); } @@ -902,13 +910,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { super.handleConfigureNotifyEvent(xev); insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}", - new Object[] {xev, isEventDisabled(xev)}); + new Object[] {xev.get_xconfigure(), isEventDisabled(xev)}); if (isEventDisabled(xev)) { return; } - long eventWindow = xev.get_xany().get_window(); - // if ( Check if it's a resize, a move, or a stacking order change ) // { Rectangle bounds = getBounds(); @@ -982,7 +988,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { // called directly from this package, unlike handleKeyRelease. // un-final it if you need to override it in a subclass. final void handleKeyPress(XKeyEvent ev) { - int keycode = java.awt.event.KeyEvent.VK_UNDEFINED; long keysym[] = new long[2]; char unicodeKey = 0; keysym[0] = NoSymbol; @@ -1066,7 +1071,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { } // un-private it if you need to call it from elsewhere private void handleKeyRelease(XKeyEvent ev) { - int keycode = java.awt.event.KeyEvent.VK_UNDEFINED; long keysym[] = new long[2]; char unicodeKey = 0; keysym[0] = NoSymbol; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java index 18ccbcba8da..c69e8f3a2ba 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2008 Sun Microsystems, Inc. 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 @@ -112,9 +112,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, PARENT_WINDOW, Long.valueOf(0)})); } - // fallback default font object - static Font defaultFont; - /* * This constant defines icon size recommended for using. * Apparently, we should use XGetIconSizes which should @@ -162,10 +159,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, Font f = target.getFont(); if (f == null) { - if (defaultFont == null) { - defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); - } - f = defaultFont; + f = XWindow.getDefaultFont(); target.setFont(f); // we should not call setFont because it will call a repaint // which the peer may not be ready to do yet. From dc0d619ccb57c791b782ed577708405b4892927c Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Thu, 13 Mar 2008 17:14:44 +0300 Subject: [PATCH 151/274] 6538066: XSelection should be more passive Now only XClipboard know about XSelection, and XSelection knows nothing about XClipboard. Reviewed-by: uta, denis --- .../sun/awt/X11/MotifDnDConstants.java | 10 +- .../awt/X11/MotifDnDDropTargetProtocol.java | 6 +- .../sun/awt/X11/OwnershipListener.java | 30 ++ .../classes/sun/awt/X11/XClipboard.java | 204 +++++++--- .../classes/sun/awt/X11/XDnDConstants.java | 5 +- .../classes/sun/awt/X11/XSelection.java | 360 +++++++----------- 6 files changed, 345 insertions(+), 270 deletions(-) create mode 100644 jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java diff --git a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java index f9940eefb93..9302361b04d 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java +++ b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -39,6 +39,8 @@ import sun.misc.Unsafe; * @since 1.5 */ class MotifDnDConstants { + // utility class can not be instantiated + private MotifDnDConstants() {} // Note that offsets in all native structures below do not depend on the // architecture. private static final Unsafe unsafe = XlibWrapper.unsafe; @@ -55,8 +57,7 @@ class MotifDnDConstants { XAtom.get("XmTRANSFER_SUCCESS"); static final XAtom XA_XmTRANSFER_FAILURE = XAtom.get("XmTRANSFER_FAILURE"); - static final XSelection MotifDnDSelection = - new XSelection(XA_MOTIF_ATOM_0, null); + static final XSelection MotifDnDSelection = new XSelection(XA_MOTIF_ATOM_0); public static final byte MOTIF_DND_PROTOCOL_VERSION = 0; @@ -231,6 +232,9 @@ class MotifDnDConstants { } public static final class Swapper { + // utility class can not be instantiated + private Swapper() {} + public static short swap(short s) { return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8)); } diff --git a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java index a67a2f552a0..df348594fc5 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java +++ b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -933,7 +933,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol { XSelection selection = XSelection.getSelection(selectionAtom); if (selection == null) { - selection = new XSelection(selectionAtom, null); + selection = new XSelection(selectionAtom); } return selection.getData(format, time_stamp); @@ -1056,7 +1056,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol { // the original structure can be freed before this // SunDropTargetEvent is dispatched. if (xclient != null) { - int size = new XClientMessageEvent(nativeCtxt).getSize(); + int size = XClientMessageEvent.getSize(); nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize()); diff --git a/jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java b/jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java new file mode 100644 index 00000000000..482b9cc7597 --- /dev/null +++ b/jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java @@ -0,0 +1,30 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package sun.awt.X11; + +interface OwnershipListener { + public void ownershipChanged(final boolean isOwner); +} diff --git a/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java b/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java index 5a7faef3547..138e11d9a8c 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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,30 +26,32 @@ package sun.awt.X11; import java.awt.datatransfer.Transferable; - import java.util.SortedMap; -import java.util.Set; -import java.util.Iterator; -import java.util.HashSet; - import java.io.IOException; - import java.security.AccessController; - +import java.util.HashMap; +import java.util.Map; +import sun.awt.UNIXToolkit; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.SunClipboard; import sun.awt.datatransfer.ClipboardTransferable; - import sun.security.action.GetIntegerAction; - - /** * A class which interfaces with the X11 selection service in order to support * data transfer via Clipboard operations. */ -public class XClipboard extends SunClipboard implements Runnable { +public final class XClipboard extends SunClipboard implements OwnershipListener +{ private final XSelection selection; + // Time of calling XConvertSelection(). + private long convertSelectionTime; + // The flag used not to call XConvertSelection() if the previous SelectionNotify + // has not been processed by checkChange(). + private volatile boolean isSelectionNotifyProcessed; + // The property in which the owner should place requested targets + // when tracking changes of available data flavors (practically targets). + private volatile XAtom targetsPropertyAtom; private static final Object classLock = new Object(); @@ -57,31 +59,33 @@ public class XClipboard extends SunClipboard implements Runnable { private static int pollInterval; - private static Set listenedClipboards; - + private static Map targetsAtom2Clipboard; /** * Creates a system clipboard object. */ public XClipboard(String name, String selectionName) { super(name); - selection = new XSelection(XAtom.get(selectionName), this); + selection = new XSelection(XAtom.get(selectionName)); + selection.registerOwershipListener(this); } - /** - * The action to be run when we lose ownership + /* * NOTE: This method may be called by privileged threads. * DO NOT INVOKE CLIENT CODE ON THIS THREAD! */ - public void run() { - lostOwnershipImpl(); + public void ownershipChanged(final boolean isOwner) { + if (isOwner) { + checkChangeHere(contents); + } else { + lostOwnershipImpl(); + } } protected synchronized void setContentsNative(Transferable contents) { SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable (contents, DataTransferer.adaptFlavorMap(flavorMap)); - long[] formats = - DataTransferer.getInstance().keysToLongArray(formatMap); + long[] formats = DataTransferer.keysToLongArray(formatMap); if (!selection.setOwner(contents, formatMap, formats, XToolkit.getCurrentServerTime())) { @@ -94,6 +98,7 @@ public class XClipboard extends SunClipboard implements Runnable { return selection.getSelectionAtom().getAtom(); } + @Override public synchronized Transferable getContents(Object requestor) { if (contents != null) { return contents; @@ -115,62 +120,163 @@ public class XClipboard extends SunClipboard implements Runnable { return selection.getData(format, XToolkit.getCurrentServerTime()); } - // Called on the toolkit thread under awtLock. - public void checkChange(long[] formats) { - if (!selection.isOwner()) { - super.checkChange(formats); - } - } - - void checkChangeHere(Transferable contents) { + private void checkChangeHere(Transferable contents) { if (areFlavorListenersRegistered()) { - super.checkChange(DataTransferer.getInstance(). + checkChange(DataTransferer.getInstance(). getFormatsForTransferableAsArray(contents, flavorMap)); } } - protected void registerClipboardViewerChecked() { - if (pollInterval <= 0) { - pollInterval = ((Integer)AccessController.doPrivileged( - new GetIntegerAction("awt.datatransfer.clipboard.poll.interval", - defaultPollInterval))).intValue(); + private static int getPollInterval() { + synchronized (XClipboard.classLock) { if (pollInterval <= 0) { - pollInterval = defaultPollInterval; + pollInterval = AccessController.doPrivileged( + new GetIntegerAction("awt.datatransfer.clipboard.poll.interval", + defaultPollInterval)); + if (pollInterval <= 0) { + pollInterval = defaultPollInterval; + } } + return pollInterval; } - selection.initializeSelectionForTrackingChanges(); + } + + private XAtom getTargetsPropertyAtom() { + if (null == targetsPropertyAtom) { + targetsPropertyAtom = + XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName()); + } + return targetsPropertyAtom; + } + + protected void registerClipboardViewerChecked() { + // for XConvertSelection() to be called for the first time in getTargetsDelayed() + isSelectionNotifyProcessed = true; + boolean mustSchedule = false; synchronized (XClipboard.classLock) { - if (listenedClipboards == null) { - listenedClipboards = new HashSet(2); + if (targetsAtom2Clipboard == null) { + targetsAtom2Clipboard = new HashMap(2); + } + mustSchedule = targetsAtom2Clipboard.isEmpty(); + targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this); + if (mustSchedule) { + XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), + new SelectionNotifyHandler()); } - mustSchedule = listenedClipboards.isEmpty(); - listenedClipboards.add(this); } if (mustSchedule) { - XToolkit.schedule(new CheckChangeTimerTask(), pollInterval); + XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval()); } } private static class CheckChangeTimerTask implements Runnable { public void run() { - for (Iterator iter = listenedClipboards.iterator(); iter.hasNext();) { - XClipboard clpbrd = (XClipboard)iter.next(); - clpbrd.selection.getTargetsDelayed(); + for (XClipboard clpbrd : targetsAtom2Clipboard.values()) { + clpbrd.getTargetsDelayed(); } synchronized (XClipboard.classLock) { - if (listenedClipboards != null && !listenedClipboards.isEmpty()) { - XToolkit.schedule(this, pollInterval); + if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) { + XToolkit.schedule(this, XClipboard.getPollInterval()); + } + } + } + } + + private static class SelectionNotifyHandler implements XEventDispatcher { + public void dispatchEvent(XEvent ev) { + if (ev.get_type() == XlibWrapper.SelectionNotify) { + final XSelectionEvent xse = ev.get_xselection(); + XClipboard clipboard = null; + synchronized (XClipboard.classLock) { + if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) { + XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this); + return; + } + final long propertyAtom = xse.get_property(); + clipboard = targetsAtom2Clipboard.get(propertyAtom); + } + if (null != clipboard) { + clipboard.checkChange(xse); } } } } protected void unregisterClipboardViewerChecked() { - selection.deinitializeSelectionForTrackingChanges(); + isSelectionNotifyProcessed = false; synchronized (XClipboard.classLock) { - listenedClipboards.remove(this); + targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom()); } } + // checkChange() will be called on SelectionNotify + private void getTargetsDelayed() { + XToolkit.awtLock(); + try { + long curTime = System.currentTimeMillis(); + if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout())) + { + convertSelectionTime = curTime; + XlibWrapper.XConvertSelection(XToolkit.getDisplay(), + selection.getSelectionAtom().getAtom(), + XDataTransferer.TARGETS_ATOM.getAtom(), + getTargetsPropertyAtom().getAtom(), + XWindow.getXAWTRootWindow().getWindow(), + XlibWrapper.CurrentTime); + isSelectionNotifyProcessed = false; + } + } finally { + XToolkit.awtUnlock(); + } + } + + /* + * Tracks changes of available formats. + * NOTE: This method may be called by privileged threads. + * DO NOT INVOKE CLIENT CODE ON THIS THREAD! + */ + private void checkChange(XSelectionEvent xse) { + final long propertyAtom = xse.get_property(); + if (propertyAtom != getTargetsPropertyAtom().getAtom()) { + // wrong atom + return; + } + + final XAtom selectionAtom = XAtom.get(xse.get_selection()); + final XSelection changedSelection = XSelection.getSelection(selectionAtom); + + if (null == changedSelection || changedSelection != selection) { + // unknown selection - do nothing + return; + } + + isSelectionNotifyProcessed = true; + + if (selection.isOwner()) { + // selection is owner - do not need formats + return; + } + + long[] formats = null; + + if (propertyAtom == XlibWrapper.None) { + // We treat None property atom as "empty selection". + formats = new long[0]; + } else { + WindowPropertyGetter targetsGetter = + new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), + XAtom.get(propertyAtom), 0, + XSelection.MAX_LENGTH, true, + XlibWrapper.AnyPropertyType); + try { + targetsGetter.execute(); + formats = XSelection.getFormats(targetsGetter); + } finally { + targetsGetter.dispose(); + } + } + + checkChange(formats); + } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDnDConstants.java b/jdk/src/solaris/classes/sun/awt/X11/XDnDConstants.java index 7974d12960d..26967f76995 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDnDConstants.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDnDConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -48,8 +48,7 @@ class XDnDConstants { static final XAtom XA_XdndStatus = XAtom.get("XdndStatus"); static final XAtom XA_XdndFinished = XAtom.get("XdndFinished"); - static final XSelection XDnDSelection = - new XSelection(XA_XdndSelection, null); + static final XSelection XDnDSelection = new XSelection(XA_XdndSelection); public static final int XDND_MIN_PROTOCOL_VERSION = 3; public static final int XDND_PROTOCOL_VERSION = 5; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java index 1d34978f8e3..b472bec7646 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java @@ -32,9 +32,6 @@ import java.io.IOException; import java.util.Hashtable; import java.util.Map; -import java.util.Set; -import java.util.HashSet; -import java.util.Collections; import sun.awt.AppContext; import sun.awt.SunToolkit; @@ -45,7 +42,7 @@ import sun.awt.datatransfer.DataTransferer; /** * A class which interfaces with the X11 selection service. */ -public class XSelection { +public final class XSelection { /* Maps atoms to XSelection instances. */ private static final Hashtable table = new Hashtable(); @@ -69,8 +66,6 @@ public class XSelection { XToolkit.awtUnlock(); } } - /* The selection timeout. */ - private static long SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout(); /* The PropertyNotify event handler for incremental data transfer. */ private static final XEventDispatcher incrementalTransferHandler = @@ -84,11 +79,6 @@ public class XSelection { /* The X atom for the underlying selection. */ private final XAtom selectionAtom; - /* - * XClipboard.run() is to be called when we lose ownership. - * XClipbioard.checkChange() is to be called when tracking changes of flavors. - */ - private final XClipboard clipboard; /* * Owner-related variables - protected with synchronized (this). @@ -109,17 +99,8 @@ public class XSelection { private long ownershipTime = 0; // True if we are the owner of this selection. private boolean isOwner; - // The property in which the owner should place requested targets - // when tracking changes of available data flavors (practically targets). - private volatile XAtom targetsPropertyAtom; - // A set of these property atoms. - private static volatile Set targetsPropertyAtoms; - // The flag used not to call XConvertSelection() if the previous SelectionNotify - // has not been processed by checkChange(). - private volatile boolean isSelectionNotifyProcessed; - // Time of calling XConvertSelection(). - private long convertSelectionTime; - + private OwnershipListener ownershipListener = null; + private final Object stateLock = new Object(); static { XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), @@ -141,12 +122,11 @@ public class XSelection { * @param clpbrd the corresponding clipoboard * @exception NullPointerException if atom is null. */ - public XSelection(XAtom atom, XClipboard clpbrd) { + public XSelection(XAtom atom) { if (atom == null) { throw new NullPointerException("Null atom"); } selectionAtom = atom; - clipboard = clpbrd; table.put(selectionAtom, this); } @@ -154,25 +134,9 @@ public class XSelection { return selectionAtom; } - void initializeSelectionForTrackingChanges() { - targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selectionAtom.getName()); - if (targetsPropertyAtoms == null) { - targetsPropertyAtoms = Collections.synchronizedSet(new HashSet(2)); - } - targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom.getAtom())); - // for XConvertSelection() to be called for the first time in getTargetsDelayed() - isSelectionNotifyProcessed = true; - } - - void deinitializeSelectionForTrackingChanges() { - if (targetsPropertyAtoms != null && targetsPropertyAtom != null) { - targetsPropertyAtoms.remove(Long.valueOf(targetsPropertyAtom.getAtom())); - } - isSelectionNotifyProcessed = false; - } - public synchronized boolean setOwner(Transferable contents, Map formatMap, - long[] formats, long time) { + long[] formats, long time) + { long owner = XWindow.getXAWTRootWindow().getWindow(); long selection = selectionAtom.getAtom(); @@ -192,15 +156,12 @@ public class XSelection { XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(), selection, owner, time); if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(), - selection) != owner) { - + selection) != owner) + { reset(); return false; } - isOwner = true; - if (clipboard != null) { - clipboard.checkChangeHere(contents); - } + setOwnerProp(true); return true; } finally { XToolkit.awtUnlock(); @@ -217,7 +178,7 @@ public class XSelection { do { DataTransferer.getInstance().processDataConversionRequests(); XToolkit.awtLockWait(250); - } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + SELECTION_TIMEOUT); + } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout()); } finally { XToolkit.awtUnlock(); } @@ -232,11 +193,9 @@ public class XSelection { throw new Error("UNIMPLEMENTED"); } - long[] formats = null; + long[] targets = null; synchronized (lock) { - SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout(); - WindowPropertyGetter targetsGetter = new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), selectionPropertyAtom, 0, MAX_LENGTH, @@ -267,15 +226,15 @@ public class XSelection { } finally { XToolkit.awtUnlock(); } - formats = getFormats(targetsGetter); + targets = getFormats(targetsGetter); } finally { targetsGetter.dispose(); } } - return formats; + return targets; } - private static long[] getFormats(WindowPropertyGetter targetsGetter) { + static long[] getFormats(WindowPropertyGetter targetsGetter) { long[] formats = null; if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() && @@ -285,7 +244,7 @@ public class XSelection { { // we accept property with TARGETS type to be compatible with old jdks // see 6607163 - int count = (int)targetsGetter.getNumberOfItems(); + int count = targetsGetter.getNumberOfItems(); if (count > 0) { long atoms = targetsGetter.getData(); formats = new long[count]; @@ -299,26 +258,6 @@ public class XSelection { return formats != null ? formats : new long[0]; } - // checkChange() will be called on SelectionNotify - void getTargetsDelayed() { - XToolkit.awtLock(); - try { - long curTime = System.currentTimeMillis(); - if (isSelectionNotifyProcessed || curTime >= convertSelectionTime + SELECTION_TIMEOUT) { - convertSelectionTime = curTime; - XlibWrapper.XConvertSelection(XToolkit.getDisplay(), - getSelectionAtom().getAtom(), - XDataTransferer.TARGETS_ATOM.getAtom(), - targetsPropertyAtom.getAtom(), - XWindow.getXAWTRootWindow().getWindow(), - XlibWrapper.CurrentTime); - isSelectionNotifyProcessed = false; - } - } finally { - XToolkit.awtUnlock(); - } - } - /* * Requests the selection data in the specified format and returns * the data provided by the owner. @@ -331,8 +270,6 @@ public class XSelection { byte[] data = null; synchronized (lock) { - SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout(); - WindowPropertyGetter dataGetter = new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), selectionPropertyAtom, 0, MAX_LENGTH, @@ -381,7 +318,7 @@ public class XSelection { dataGetter.getActualFormat()); } - int count = (int)dataGetter.getNumberOfItems(); + int count = dataGetter.getNumberOfItems(); if (count <= 0) { throw new IOException("INCR data is missed."); @@ -457,7 +394,7 @@ public class XSelection { incrDataGetter.getActualFormat()); } - count = (int)incrDataGetter.getNumberOfItems(); + count = incrDataGetter.getNumberOfItems(); if (count == 0) { break; @@ -491,7 +428,7 @@ public class XSelection { dataGetter.getActualFormat()); } - int count = (int)dataGetter.getNumberOfItems(); + int count = dataGetter.getNumberOfItems(); if (count > 0) { data = new byte[count]; long ptr = dataGetter.getData(); @@ -513,11 +450,14 @@ public class XSelection { return isOwner; } - public void lostOwnership() { - isOwner = false; - if (clipboard != null) { - clipboard.run(); - } + // To be MT-safe this method should be called under awtLock. + private void setOwnerProp(boolean f) { + isOwner = f; + fireOwnershipChanges(isOwner); + } + + private void lostOwnership() { + setOwnerProp(false); } public synchronized void reset() { @@ -597,125 +537,39 @@ public class XSelection { private void handleSelectionRequest(XSelectionRequestEvent xsre) { long property = xsre.get_property(); - long requestor = xsre.get_requestor(); - long requestTime = xsre.get_time(); - long format = xsre.get_target(); - int dataFormat = 0; + final long requestor = xsre.get_requestor(); + final long requestTime = xsre.get_time(); + final long format = xsre.get_target(); boolean conversionSucceeded = false; if (ownershipTime != 0 && - (requestTime == XlibWrapper.CurrentTime || - requestTime >= ownershipTime)) { - - property = xsre.get_property(); - + (requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime)) + { // Handle MULTIPLE requests as per ICCCM. if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) { - // The property cannot be 0 for a MULTIPLE request. - if (property != 0) { - // First retrieve the list of requested targets. - WindowPropertyGetter wpg = - new WindowPropertyGetter(requestor, XAtom.get(property), 0, - MAX_LENGTH, false, - XlibWrapper.AnyPropertyType); - try { - wpg.execute(); - - if (wpg.getActualFormat() == 32 && - (wpg.getNumberOfItems() % 2) == 0) { - long count = wpg.getNumberOfItems() / 2; - long pairsPtr = wpg.getData(); - boolean writeBack = false; - for (int i = 0; i < count; i++) { - long target = Native.getLong(pairsPtr, 2*i); - long prop = Native.getLong(pairsPtr, 2*i + 1); - - if (!convertAndStore(requestor, target, prop)) { - // To report failure, we should replace the - // target atom with 0 in the MULTIPLE property. - Native.putLong(pairsPtr, 2*i, 0); - writeBack = true; - } - } - if (writeBack) { - XToolkit.awtLock(); - try { - XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor, - property, - wpg.getActualType(), - wpg.getActualFormat(), - XlibWrapper.PropModeReplace, - wpg.getData(), - wpg.getNumberOfItems()); - } finally { - XToolkit.awtUnlock(); - } - } - conversionSucceeded = true; - } - } finally { - wpg.dispose(); - } - } + conversionSucceeded = handleMultipleRequest(requestor, property); } else { - // Support for obsolete clients as per ICCCM. - if (property == 0) { + if (property == XlibWrapper.None) { property = format; } if (format == XDataTransferer.TARGETS_ATOM.getAtom()) { - long nativeDataPtr = 0; - int count = 0; - dataFormat = 32; - - // Use a local copy to avoid synchronization. - long[] formatsLocal = formats; - - if (formatsLocal == null) { - throw new IllegalStateException("Not an owner."); - } - - count = formatsLocal.length; - - try { - if (count > 0) { - nativeDataPtr = Native.allocateLongArray(count); - Native.put(nativeDataPtr, formatsLocal); - } - - conversionSucceeded = true; - - XToolkit.awtLock(); - try { - XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor, - property, XAtom.XA_ATOM, dataFormat, - XlibWrapper.PropModeReplace, - nativeDataPtr, count); - } finally { - XToolkit.awtUnlock(); - } - } finally { - if (nativeDataPtr != 0) { - XlibWrapper.unsafe.freeMemory(nativeDataPtr); - nativeDataPtr = 0; - } - } + conversionSucceeded = handleTargetsRequest(property, requestor); } else { - conversionSucceeded = convertAndStore(requestor, format, - property); + conversionSucceeded = convertAndStore(requestor, format, property); } } } if (!conversionSucceeded) { - // Zero property indicates conversion failure. - property = 0; + // None property indicates conversion failure. + property = XlibWrapper.None; } XSelectionEvent xse = new XSelectionEvent(); try { - xse.set_type((int)XlibWrapper.SelectionNotify); + xse.set_type(XlibWrapper.SelectionNotify); xse.set_send_event(true); xse.set_requestor(requestor); xse.set_selection(selectionAtom.getAtom()); @@ -735,40 +589,123 @@ public class XSelection { } } - private static void checkChange(XSelectionEvent xse) { - if (targetsPropertyAtoms == null || targetsPropertyAtoms.isEmpty()) { - // We are not tracking changes. - return; + private boolean handleMultipleRequest(final long requestor, long property) { + if (XlibWrapper.None == property) { + // The property cannot be None for a MULTIPLE request. + return false; } - long propertyAtom = xse.get_property(); - long[] formats = null; + boolean conversionSucceeded = false; - if (propertyAtom == XlibWrapper.None) { - // We threat None property atom as "empty selection". - formats = new long[0]; - } else if (!targetsPropertyAtoms.contains(Long.valueOf(propertyAtom))) { - return; - } else { - WindowPropertyGetter targetsGetter = - new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(), - XAtom.get(propertyAtom), 0, MAX_LENGTH, - true, XlibWrapper.AnyPropertyType); + // First retrieve the list of requested targets. + WindowPropertyGetter wpg = + new WindowPropertyGetter(requestor, XAtom.get(property), + 0, MAX_LENGTH, false, + XlibWrapper.AnyPropertyType); + try { + wpg.execute(); + + if (wpg.getActualFormat() == 32 && (wpg.getNumberOfItems() % 2) == 0) { + final long count = wpg.getNumberOfItems() / 2; + final long pairsPtr = wpg.getData(); + boolean writeBack = false; + + for (int i = 0; i < count; i++) { + long target = Native.getLong(pairsPtr, 2 * i); + long prop = Native.getLong(pairsPtr, 2 * i + 1); + + if (!convertAndStore(requestor, target, prop)) { + // To report failure, we should replace the + // target atom with 0 in the MULTIPLE property. + Native.putLong(pairsPtr, 2 * i, 0); + writeBack = true; + } + } + if (writeBack) { + XToolkit.awtLock(); + try { + XlibWrapper.XChangeProperty(XToolkit.getDisplay(), + requestor, + property, + wpg.getActualType(), + wpg.getActualFormat(), + XlibWrapper.PropModeReplace, + wpg.getData(), + wpg.getNumberOfItems()); + } finally { + XToolkit.awtUnlock(); + } + } + conversionSucceeded = true; + } + } finally { + wpg.dispose(); + } + + return conversionSucceeded; + } + + private boolean handleTargetsRequest(long property, long requestor) + throws IllegalStateException + { + boolean conversionSucceeded = false; + // Use a local copy to avoid synchronization. + long[] formatsLocal = formats; + + if (formatsLocal == null) { + throw new IllegalStateException("Not an owner."); + } + + long nativeDataPtr = 0; + + try { + final int count = formatsLocal.length; + final int dataFormat = 32; + + if (count > 0) { + nativeDataPtr = Native.allocateLongArray(count); + Native.put(nativeDataPtr, formatsLocal); + } + + conversionSucceeded = true; + + XToolkit.awtLock(); try { - targetsGetter.execute(); - formats = getFormats(targetsGetter); + XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor, + property, XAtom.XA_ATOM, dataFormat, + XlibWrapper.PropModeReplace, + nativeDataPtr, count); } finally { - targetsGetter.dispose(); + XToolkit.awtUnlock(); + } + } finally { + if (nativeDataPtr != 0) { + XlibWrapper.unsafe.freeMemory(nativeDataPtr); + nativeDataPtr = 0; } } + return conversionSucceeded; + } - XAtom selectionAtom = XAtom.get(xse.get_selection()); - XSelection selection = getSelection(selectionAtom); - if (selection != null) { - selection.isSelectionNotifyProcessed = true; - if (selection.clipboard != null) { - selection.clipboard.checkChange(formats); - } + private void fireOwnershipChanges(final boolean isOwner) { + OwnershipListener l = null; + synchronized (stateLock) { + l = ownershipListener; + } + if (null != l) { + l.ownershipChanged(isOwner); + } + } + + void registerOwershipListener(OwnershipListener l) { + synchronized (stateLock) { + ownershipListener = l; + } + } + + void unregisterOwnershipListener() { + synchronized (stateLock) { + ownershipListener = null; } } @@ -776,10 +713,9 @@ public class XSelection { public void dispatchEvent(XEvent ev) { switch (ev.get_type()) { case XlibWrapper.SelectionNotify: { - XSelectionEvent xse = ev.get_xselection(); - checkChange(xse); XToolkit.awtLock(); try { + XSelectionEvent xse = ev.get_xselection(); // Ignore the SelectionNotify event if it is not the response to our last request. if (propertyGetter != null && xse.get_time() == lastRequestServerTime) { // The property will be None in case of convertion failure. From cf50796ba5f6d88fbd446a1059b2ce06ff87ca0b Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Thu, 13 Mar 2008 13:29:27 -0400 Subject: [PATCH 152/274] 6611991: Add support for parsing RFC4514 DNs to X500Principal Added new test and made one code change to escape null characters. Reviewed-by: vinnie --- .../share/classes/sun/security/x509/AVA.java | 7 +- .../auth/x500/X500Principal/RFC4514.java | 92 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/security/auth/x500/X500Principal/RFC4514.java diff --git a/jdk/src/share/classes/sun/security/x509/AVA.java b/jdk/src/share/classes/sun/security/x509/AVA.java index 9a6b7a59d1a..43d914cba13 100644 --- a/jdk/src/share/classes/sun/security/x509/AVA.java +++ b/jdk/src/share/classes/sun/security/x509/AVA.java @@ -780,7 +780,8 @@ public class AVA implements DerEncoder { * Implementations MAY escape other characters. * * NOTE: this implementation also recognizes "=" and "#" as - * characters which need escaping. + * characters which need escaping, and null which is escaped as + * '\00' (see RFC 4514). * * If a character to be escaped is one of the list shown above, then * it is prefixed by a backslash ('\' ASCII 92). @@ -805,6 +806,10 @@ public class AVA implements DerEncoder { // append printable/escaped char sbuffer.append(c); + } else if (c == '\u0000') { + // escape null character + sbuffer.append("\\00"); + } else if (debug != null && Debug.isOn("ava")) { // embed non-printable/non-escaped char diff --git a/jdk/test/javax/security/auth/x500/X500Principal/RFC4514.java b/jdk/test/javax/security/auth/x500/X500Principal/RFC4514.java new file mode 100644 index 00000000000..6169314abf0 --- /dev/null +++ b/jdk/test/javax/security/auth/x500/X500Principal/RFC4514.java @@ -0,0 +1,92 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. + */ + +import javax.security.auth.x500.X500Principal; + +/** + * @test + * @bug 6611991 + * @summary Add support for parsing RFC 4514 DNs to X500Principal + * + * Ensure RFC 4514 Distinguished Name Strings can be parsed by X500Principal. + * RFC 4514 obsoleted RFC 2253 so we should make sure we can parse DNs of + * that form that contain subtle differences or clarifications in the grammar. + */ +public class RFC4514 { + + private int failed = 0; + + public static void main(String[] args) throws Exception { + new RFC4514().test(); + } + + private void test() throws Exception { + + /** + * RFC 4514 allows space to be escaped as '\ '. + */ + parse("CN=\\ Space\\ ,C=US"); + parse("CN=Sp\\ ace,C=US"); + /** + * RFC 4514 does not require escaping of '=' characters. + */ + parse("CN=Eq=uals,C=US"); + /** + * RFC 4514 requires the null character to be escaped. + */ + parse("CN=\\00,C=US"); + /** + * RFC 4514 does not require escaping of non-leading '#' characters. + */ + parse("CN=Num#ber,C=US"); + /** + * XMLDSig (http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/) + * allows implementations to escape trailing whitespace as '\20'. + */ + parse("CN=Trailing \\20,C=US"); + /** + * XMLDSig allows implementations to escape ASCII control characters + * (Unicode range \x00 - \x1f) by replacing them with "\" followed by + * a two digit hex number showing its Unicode number. + */ + parse("CN=Con\\09trol,C=US"); + + if (failed != 0) { + throw new Exception("Some RFC4514 tests FAILED"); + } + } + + public void parse(String dnString) throws Exception { + + System.out.println("Parsing " + dnString); + X500Principal dn = new X500Principal(dnString); + String dnString2 = dn.getName(); + X500Principal dn2 = new X500Principal(dnString2); + if (dn.equals(dn2)) { + System.out.println("PASSED"); + } else { + System.out.println("FAILED"); + failed++; + } + } +} From 66fa5dcf96d23c549ee037f97cac6b6721b67d57 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 13 Mar 2008 19:29:41 +0000 Subject: [PATCH 153/274] 6628575: (fc) lock/tryLock methods do not work with NFS servers that limit lock range to max file size Reviewed-by: sherman --- jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c index 897ad488e94..6110143de7b 100644 --- a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c +++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c @@ -31,6 +31,7 @@ #include #include "sun_nio_ch_FileChannelImpl.h" #include "java_lang_Integer.h" +#include "java_lang_Long.h" #include "nio.h" #include "nio_util.h" #include @@ -291,7 +292,11 @@ Java_sun_nio_ch_FileChannelImpl_lock0(JNIEnv *env, jobject this, jobject fdo, struct flock64 fl; fl.l_whence = SEEK_SET; - fl.l_len = (off64_t)size; + if (size == (jlong)java_lang_Long_MAX_VALUE) { + fl.l_len = (off64_t)0; + } else { + fl.l_len = (off64_t)size; + } fl.l_start = (off64_t)pos; if (shared == JNI_TRUE) { fl.l_type = F_RDLCK; @@ -325,7 +330,11 @@ Java_sun_nio_ch_FileChannelImpl_release0(JNIEnv *env, jobject this, int cmd = F_SETLK64; fl.l_whence = SEEK_SET; - fl.l_len = (off64_t)size; + if (size == (jlong)java_lang_Long_MAX_VALUE) { + fl.l_len = (off64_t)0; + } else { + fl.l_len = (off64_t)size; + } fl.l_start = (off64_t)pos; fl.l_type = F_UNLCK; lockResult = fcntl(fd, cmd, &fl); From eab1a9b3dfe4db15a3bb09628bef00f7fea260fa Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Thu, 13 Mar 2008 19:34:49 +0000 Subject: [PATCH 154/274] 6546113: (bf) CharSequence.slice() on wrapped CharSequence doesn't start at buffer position Reviewed-by: iris --- .../classes/java/nio/StringCharBuffer.java | 20 +++----- .../nio/Buffer/StringCharBufferSliceTest.java | 51 +++++++++++++++++++ 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/classes/java/nio/StringCharBuffer.java b/jdk/src/share/classes/java/nio/StringCharBuffer.java index d5a80f26d1c..c6ef51eb0dc 100644 --- a/jdk/src/share/classes/java/nio/StringCharBuffer.java +++ b/jdk/src/share/classes/java/nio/StringCharBuffer.java @@ -60,16 +60,9 @@ class StringCharBuffer // package-private str = s; } - private StringCharBuffer(CharSequence s, int mark, - int pos, int limit, int cap) - { - super(mark, pos, limit, cap); - str = s; - } - public CharBuffer duplicate() { return new StringCharBuffer(str, markValue(), - position(), limit(), capacity()); + position(), limit(), capacity(), offset); } public CharBuffer asReadOnlyBuffer() { @@ -77,11 +70,11 @@ class StringCharBuffer // package-private } public final char get() { - return str.charAt(nextGetIndex()); + return str.charAt(nextGetIndex() + offset); } public final char get(int index) { - return str.charAt(checkIndex(index)); + return str.charAt(checkIndex(index) + offset); } // ## Override bulk get methods for better performance @@ -103,15 +96,16 @@ class StringCharBuffer // package-private } final String toString(int start, int end) { - return str.toString().substring(start, end); + return str.toString().substring(start + offset, end + offset); } public final CharSequence subSequence(int start, int end) { try { int pos = position(); - return new StringCharBuffer(str, + return new StringCharBuffer(str, -1, pos + checkIndex(start, pos), - pos + checkIndex(end, pos)); + pos + checkIndex(end, pos), + remaining(), offset); } catch (IllegalArgumentException x) { throw new IndexOutOfBoundsException(); } diff --git a/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java b/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java index 56770025c32..82d593c5d70 100644 --- a/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java +++ b/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java @@ -53,6 +53,57 @@ public class StringCharBufferSliceTest { buff = CharBuffer.wrap(in, 3, in.length()); test(buff, buff.slice()); + System.out.println( + ">>> StringCharBufferSliceTest-main: testing slice result with get()"); + buff.position(4); + buff.limit(7); + CharBuffer slice = buff.slice(); + for (int i = 0; i < 3; i++) { + if (slice.get() != buff.get()) { + throw new RuntimeException("Wrong characters in slice result."); + } + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing slice result with get(int)"); + buff.position(4); + buff.limit(7); + slice = buff.slice(); + for (int i = 0; i < 3; i++) { + if (slice.get(i) != buff.get(4 + i)) { + throw new RuntimeException("Wrong characters in slice result."); + } + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing toString."); + buff.position(4); + buff.limit(7); + slice = buff.slice(); + if (! slice.toString().equals("tes")) { + throw new RuntimeException("bad toString() after slice(): " + slice.toString()); + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing subSequence."); + buff.position(4); + buff.limit(8); + slice = buff.slice(); + CharSequence subSeq = slice.subSequence(1, 3); + if (subSeq.charAt(0) != 'e' || subSeq.charAt(1) != 's') { + throw new RuntimeException("bad subSequence() after slice(): '" + subSeq + "'"); + } + + System.out.println( + ">>> StringCharBufferSliceTest-main: testing duplicate."); + buff.position(4); + buff.limit(8); + slice = buff.slice(); + CharBuffer dupe = slice.duplicate(); + if (dupe.charAt(0) != 't' || dupe.charAt(1) != 'e' + || dupe.charAt(2) != 's' || dupe.charAt(3) != 't') { + throw new RuntimeException("bad duplicate() after slice(): '" + dupe + "'"); + } System.out.println(">>> StringCharBufferSliceTest-main: done!"); } From d3dcc1c11528e4fefebe2c333debbbc4ce929ad0 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 13 Mar 2008 13:42:38 -0700 Subject: [PATCH 155/274] 6559315: Inconsistent non-standard Sun copyright in src/share/opensource/javac/doc/document.css Remove obsolete files Reviewed-by: mcimadamore --- langtools/src/share/opensource/javac/Makefile | 275 --------------- .../opensource/javac/README-template.html | 330 ------------------ .../share/opensource/javac/build.properties | 13 - .../src/share/opensource/javac/build.xml | 163 --------- .../share/opensource/javac/doc/document.css | 59 ---- .../javac/doc/javac_lifecycle/Context.html | 107 ------ .../javac/doc/javac_lifecycle/Enter.html | 90 ----- .../doc/javac_lifecycle/JavaCompiler.html | 79 ----- .../javac/doc/javac_lifecycle/Main.html | 69 ---- .../javac/doc/javac_lifecycle/ToDo.html | 167 --------- .../javac/doc/javac_lifecycle/contents.html | 43 --- .../javac/doc/javac_lifecycle/index.html | 40 --- .../javac/doc/javac_lifecycle/packages.html | 91 ----- .../javac/doc/javac_lifecycle/style.css | 33 -- .../opensource/javac/nbproject/project.xml | 88 ----- .../share/opensource/javac/src/bin/javac.sh | 30 -- 16 files changed, 1677 deletions(-) delete mode 100644 langtools/src/share/opensource/javac/Makefile delete mode 100644 langtools/src/share/opensource/javac/README-template.html delete mode 100644 langtools/src/share/opensource/javac/build.properties delete mode 100644 langtools/src/share/opensource/javac/build.xml delete mode 100644 langtools/src/share/opensource/javac/doc/document.css delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/Context.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/Enter.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/JavaCompiler.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/Main.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/ToDo.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/contents.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/index.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/packages.html delete mode 100644 langtools/src/share/opensource/javac/doc/javac_lifecycle/style.css delete mode 100644 langtools/src/share/opensource/javac/nbproject/project.xml delete mode 100644 langtools/src/share/opensource/javac/src/bin/javac.sh diff --git a/langtools/src/share/opensource/javac/Makefile b/langtools/src/share/opensource/javac/Makefile deleted file mode 100644 index 6dedb18e44d..00000000000 --- a/langtools/src/share/opensource/javac/Makefile +++ /dev/null @@ -1,275 +0,0 @@ -# -# Copyright 2006-2007 Sun Microsystems, Inc. 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. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the LICENSE file that accompanied this code. -# -# 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. -# - -# Simple Makefile for javac - -BUILD = build -BUILD_BOOTCLASSES = $(BUILD)/bootclasses -BUILD_CLASSES = $(BUILD)/classes -BUILD_JAVAC_SRCFILES = $(BUILD)/javac.srcfiles -GENSRCDIR = $(BUILD)/gensrc -DIST = dist -DIST_JAVAC = $(DIST) -ABS_DIST_JAVAC = $(shell cd $(DIST_JAVAC) ; pwd) -SRC_BIN = src/bin -SRC_CLASSES = src/share/classes - -#-------------------------------------------------------------------------------- -# -# version info for generated compiler - -JDK_VERSION = 1.7.0 -RELEASE=$(JDK_VERSION)-opensource -BUILD_NUMBER = b00 -USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`) -FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER) - -#-------------------------------------------------------------------------------- - -CAT = /bin/cat -CHMOD = /bin/chmod -CP = /bin/cp -MKDIR = /bin/mkdir -RM = /bin/rm -SED = /bin/sed - - -SYSTEM_UNAME := $(shell uname) - -# Platform settings specific to Solaris -ifeq ($(SYSTEM_UNAME), SunOS) - # Intrinsic unix command, with backslash-escaped character interpretation - # (not using -e will cause build failure when using /bin/bash) - # (using -e breaks something else) - ECHO = /usr/bin/echo - PLATFORM = solaris -endif - -# Platform settings specific to Linux -ifeq ($(SYSTEM_UNAME), Linux) - # Intrinsic unix command, with backslash-escaped character interpretation - ECHO = echo -e - PLATFORM = linux -endif - - -# Set BOOTDIR to specify the JDK used to build the compiler -ifdef BOOTDIR -JAR = $(BOOTDIR)/bin/jar -JAVA = $(BOOTDIR)/bin/java -JAVAC = $(BOOTDIR)/bin/javac -JAVADOC = $(BOOTDIR)/bin/javadoc -else -JAR = jar -JAVA = java -JAVAC = javac -JAVADOC = javadoc -endif - -ifndef JTREG -ifdef JTREG_HOME -JTREG = $(JTREG_HOME)/$(PLATFORM)/bin/jtreg -else -JTREG = jtreg -endif -endif - -ifndef JTREG_OPTS -JTREG_OPTS = -s -verbose:summary -endif - -ifndef JTREG_TESTS -JTREG_TESTS = test/tools/javac -endif - -# Set this to the baseline version of JDK used for the tests -# TESTJDKHOME = - -COMPILER_SOURCE_LEVEL = 1.5 - -#-------------------------------------------------------------------------------- -SCM_DIRS = -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -JAVAC_SRCS = $(shell find \ - $(SRC_CLASSES)/javax/annotation/processing \ - $(SRC_CLASSES)/javax/lang/model \ - $(SRC_CLASSES)/javax/tools \ - $(SRC_CLASSES)/com/sun/source \ - $(SRC_CLASSES)/com/sun/tools/javac \ - \( $(SCM_DIRS) -o -name \*-template.\* \) -prune -o -name \*.java -print ) - -JAVAC_RESOURCES = $(shell ls $(SRC_CLASSES)/com/sun/tools/javac/resources/*.properties | $(SED) -e 's/-template//' ) - - -#-------------------------------------------------------------------------------- - -default: build - -all: build docs - -clean: - $(RM) -rf $(BUILD) $(DIST) - -build: sanity $(DIST_JAVAC)/lib/javac.jar $(DIST_JAVAC)/bin/javac - - -# javac.jar - -$(DIST_JAVAC)/lib/javac.jar: \ - $(JAVAC_SRCS) \ - $(patsubst $(SRC_CLASSES)/%,$(BUILD_BOOTCLASSES)/%,$(JAVAC_RESOURCES)) \ - $(patsubst $(SRC_CLASSES)/%,$(BUILD_CLASSES)/%,$(JAVAC_RESOURCES)) - @$(ECHO) $(JAVAC_SRCS) > $(BUILD_JAVAC_SRCFILES) - $(JAVAC) -d $(BUILD_BOOTCLASSES) -source $(COMPILER_SOURCE_LEVEL) -g:source,lines @$(BUILD_JAVAC_SRCFILES) - $(JAVA) -cp $(BUILD_BOOTCLASSES) com.sun.tools.javac.Main \ - -d $(BUILD_CLASSES) -g:source,lines @$(BUILD_JAVAC_SRCFILES) - ( $(ECHO) "Main-Class: com.sun.tools.javac.Main" ; \ - $(ECHO) "Built-By: $$USER" ; \ - $(ECHO) "Built-At: `date`" ) > $(BUILD)/javac.MF - $(MKDIR) -p $(DIST_JAVAC)/lib - $(JAR) -cmf $(BUILD)/javac.MF $(DIST_JAVAC)/lib/javac.jar -C ${BUILD_CLASSES} . - - -# javac resources - -$(BUILD_BOOTCLASSES)/com/sun/tools/javac/resources/version.properties \ -$(BUILD_CLASSES)/com/sun/tools/javac/resources/version.properties: \ - $(SRC_CLASSES)/com/sun/tools/javac/resources/version-template.properties - $(MKDIR) -p $(@D) - $(SED) -e 's/$$(JDK_VERSION)/$(JDK_VERSION)/' \ - -e 's/$$(FULL_VERSION)/$(FULL_VERSION)/' \ - -e 's/$$(RELEASE)/$(RELEASE)/' \ - < $< > $@ - -$(BUILD_BOOTCLASSES)/com/sun/tools/javac/resources/%.properties: \ - $(SRC_CLASSES)/com/sun/tools/javac/resources/%.properties - $(MKDIR) -p $(@D) - $(CP) $^ $@ - -$(BUILD_CLASSES)/com/sun/tools/javac/resources/%.properties: \ - $(SRC_CLASSES)/com/sun/tools/javac/resources/%.properties - $(MKDIR) -p $(@D) - $(CP) $^ $@ - - -# javac wrapper script - -$(DIST_JAVAC)/bin/javac: $(SRC_BIN)/javac.sh - $(MKDIR) -p $(@D) - $(CP) $^ $@ - $(CHMOD) +x $@ - -# javadoc - -JLS3_URL = http://java.sun.com/docs/books/jls/ -JLS3_CITE = \ - The Java Language Specification, Third Edition -TAG_JLS3 = -tag 'jls3:a:See $(JLS3_CITE):' - -TAGS = $(IGNORED_TAGS:%=-tag %:X) $(TAG_JLS3) - -docs: - $(JAVADOC) -sourcepath $(SRC_CLASSES) -d $(DIST_JAVAC)/doc/api \ - $(TAGS) \ - -subpackages javax.annotation.processing:javax.lang.model:javax.tools:com.sun.source:com.sun.tools.javac - -#-------------------------------------------------------------------------------- - -test: test-sanity $(DIST_JAVAC)/lib/javac.jar - $(JTREG) $(JTREG_OPTS) -noshell \ - -jdk:$(TESTJDKHOME) \ - -Xbootclasspath/p:$(ABS_DIST_JAVAC)/lib/javac.jar \ - -w:$(BUILD)/jtreg/work \ - -r:$(BUILD)/jtreg/report \ - $(JTREG_TESTS) - -#-------------------------------------------------------------------------------- - -ifndef ERROR_FILE - ERROR_FILE = $(BUILD)/sanityCheckErrors.txt -endif - -presanity: - @$(RM) -f $(ERROR_FILE) - @$(MKDIR) -p `dirname $(ERROR_FILE)` - -###################################################### -# CLASSPATH cannot be set, unless you are insane. -###################################################### -sane-classpath: -ifdef CLASSPATH - @$(ECHO) "ERROR: Your CLASSPATH environment variable is set. This will \n" \ - " most likely cause the build to fail. Please unset it \n" \ - " and start your build again. \n" \ - "" >> $(ERROR_FILE) -endif - -###################################################### -# JAVA_HOME cannot be set, unless you are insane. -###################################################### -sane-java_home: -ifdef JAVA_HOME - @$(ECHO) "ERROR: Your JAVA_HOME environment variable is set. This will \n" \ - " most likely cause the build to fail. Please unset it \n" \ - " and start your build again. \n" \ - "" >> $(ERROR_FILE) -endif - - -###################################################### -# TESTJDKHOME needs to be set to run tests -###################################################### -sane-testjdk: -ifndef TESTJDKHOME - @$(ECHO) "ERROR: TESTJDKHOME needs to be set to the baseline version \n" \ - " version of JDK used to run the compiler tests.\n" \ - "" >> $(ERROR_FILE) -endif - - -sane-lastrule: - @if [ -r $(ERROR_FILE) ]; then \ - if [ "x$(INSANE)" = x ]; then \ - $(ECHO) "Exiting because of the above error(s). \n" \ - "">> $(ERROR_FILE); \ - fi ; \ - $(CAT) $(ERROR_FILE) ; \ - if [ "x$(INSANE)" = x ]; then \ - exit 1 ; \ - fi ; \ - fi - -sanity \ -build-sanity: presanity sane-classpath sane-java_home sane-lastrule - -test-sanity: presanity sane-classpath sane-java_home sane-testjdk sane-lastrule - - - - -#-------------------------------------------------------------------------------- - -.PHONY: all build clean default docs prep test \ - presanity sanity build-sanity test-sanity \ - sane-classpath sane-java_home sane-testjdk sane-lastrule diff --git a/langtools/src/share/opensource/javac/README-template.html b/langtools/src/share/opensource/javac/README-template.html deleted file mode 100644 index 32d210165f1..00000000000 --- a/langtools/src/share/opensource/javac/README-template.html +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - - - - - OpenJDK: javac -- README - - - - - - - - - - - - - -
     
    -

    README

    - -

    Open JDK™ Java programming language compiler (javac)
    - Version $(RELEASE) -

    -

    $(BUILD_DATE)

    -
     
    - - - - - -

    Table of Contents

    - - - -

    Introduction

    -

    This bundle contains the source code for javac, a compiler for - the Java™ programming language. - Build files are provided for use with - NetBeans, - Apache Ant or - GNU make. - The bundle also contains a set of compiler tests, for use with the - jtreg test harness. - - -

    Files and Directories

    - When you install the compiler bundle, a directory named - compiler will be created, containing the following: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDescription -
    README.htmlThis file.
    nbproject/project.xmlA NetBeans project file. -
    src/share/classes/The source files for the compiler.
    build.xmlA build file for building the compiler, suitable for - use with NetBeans and Apache Ant.
    build.propertiesBuild properties, used by build.xml.
    MakefileA Makefile for building the compiler, suitable for use - with GNU make.
    test/tools/javac/Regression tests for the compiler, for use with the JDK regression - test harness, jtreg.
    doc/Additional notes about the compiler.
    - -

    Specifications

    -

    The compiler is a program for compiling source code written in the Java - programming language into class files suitable for execution on a Java - virtual machine. It also provides API for annotation processing, - and invoking the compiler programmatically. -

    These behaviors are governed by the following specifications: -

      -
    • Java Language Specification (JLS)
    • -
    • Java Virtual Machine Specification (JVMS)
    • -
    • Java Compiler API (JSR 199)
    • -
    • Pluggable Annotation Processing API (JSR 269)
    • -
    -

    For more details on these specifications, see the - javac Guide. -

    - -

    These specifications are controlled by the Java Community Process - (JCP.) All implementations of these specifications - must pass the appropriate test suites.

    - -

    Notice regarding JSR 199 and JSR 269: - This is an implementation of an early-draft - specification developed under the Java Community Process (JCP) - and is made available for testing and evaluation purposes only. - The code is not compatible with any specification of the JCP. - -

    Building the compiler

    - -

    System Requirements

    -

    javac is written in the Java programming language. - As a general rule, it can normally be compiled using tools in the - latest released version of the JDK. - (That is, a development version of javac version 7 - can be built with JDK version 6, etc.) - To bootstrap the compiler, you should also have - a copy of the target JDK.

    - -

    You can build javac using - NetBeans, - Apache Ant, - or GNU make. -

    - -

    To run the compiler tests, you will need the - jtreg test harness. - -

    Bootstrapping the compiler

    - -

    The source for the compiler is such that it can be compiled using the latest - publicly released version of the JDK.In practice, it is typically desirable - to compile it first using the latest publicly released version of the JDK, - and then again using itself, and the target platform on which it will be run. - This not only provides a good initial test of the newly built compiler, it - also means the compiler is built with the latest compiler sources, against - the target libraries. - -

    Building with NetBeans

    -

    The installation directory for the compiler is set up as a free-form NetBeans project, - so to build the compiler using NetBeans, you just have to open the - project and build it in the normal way, for example, by using the operations - on the Build menu. -

    To run the tests, you will have to edit properties in the - build.properties file, to specify where you have installed - the jtreg harness and, possibly, a different version of - JDK to use when running the tests. - -

    Building with Apache Ant

    -

    To build the compiler, go to the compiler installation directory, and run "ant".

    -
    -        % cd install-dir
    -        % ant       
    -        
    -

    To run the tests, you will have to edit properties in the - build.properties file, to specify where you have installed - the jtreg harness and, possibly, a different version of - JDK to use when running the tests. Then, you can run the tests using the - "test" target. - -

    Building with GNU make

    -

    To build the compiler, go to the compiler installation directory, and type "make".

    - You should not have CLASSPATH and JAVAHOME environment variables set when you - do this. -
    -        % cd install-dir
    -        % make      
    -        
    -

    To run the tests, you will have to specify where you have installed - the jtreg harness and, possibly, a different version of - JDK to use when running the tests. Then, you can run the tests using the - "test" target. You can specify the values by giving them on the command - line when you run make or by editing the values into the Makefile. - -

    What gets built?

    -

    Whichever build tool you use, the results are put in the dist - subdirectory of your installation directory. The following files will be built. - - - - - - - - - - - - - -
    NameDescription -
    dist/lib/javac.jarThis is an executable jar file containing the compiler.
    dist/bin/javacThis is a simple shell script to invoke the compiler.
    - -

    Notes

    - -

    Property files: - It is possible to compile the resource property files into equivalent - class files, for a minor performance improvement. For simplicity, that - feature is not included here.

    - -

    The launcher: - JDK uses a program informally called "the launcher" which is used as - a wrapper for all JDK tools, including java, - javac, javadoc, and so on. The program is a deployed - as a platform-dependent binary, thus obviating the need for a shell - script to invoke the tools. Again for simplicity, and because that program - is not normally considered part of javac, that program is - not included here.

    Running the compiler -

    Once you have built the compiler, you can run it in a number of ways. -

      -
    • -

      Use the generated script, perhaps by putting it on your shell's - command execution path.

      -
          % install-dir/dist/bin/javac HelloWorld.java
      -

      or

      -
          % javac HelloWorld.java
      -
    • -
    • Execute javac.jar with the java command.

      -
          % java -jar install-dir/dist/lib/javac.jar HelloWorld.java
      -
    • -
    • Execute javac.jar directly. Depending on your operating system, - you may be able to execute the jar file directly.

      -
          % install-dir/dist/lib/javac.jar HelloWorld.java
      -

      See the - Jar File Overview - for details.

      -
    • -
    - -

    Testing the compiler with jtreg

    -

    This bundle contains a large test suite of unit and regression tests - used to test javac. They are part of the JDK Regression Test - Suite, which uses the - jtreg test harness. - This harness is - designed to run both API-style tests, and command-line tests, such as - found in the tests for javac.

    - -

    The simplest way to run the tests is to prepend the newly created - copy of javac.jar to the bootstrap class path of a - compatible version of JDK (meaning, it must accept the class file - versions of newly compiled classes.) To do this, you can use - the -Xbootclasspath/p:<path> option - for jtreg. This option is similar to the equivalent - option for the java command. - -

    Note:Some of the tests, written as shell tests, do not yet - support this mode of operation. You should use the - -noshell to disable these tests for the time being. - This restriction will be lifted in the near future. - -

    Note:Four additional tests are ignored, using the jtreg - @ignore tag, because of problems caused by bugs that have not yet - been addressed. - -

    You can run the compiler tests with a command such as the following:

    - -
        % jtreg -jdk:jdk -Xbootclasspath/p:my-javac.jar -verbose -noshell test/tools/javac
    - -

    Depending on the verbose options used, some amount of detail of the result - of each test is written to the console. In addition, an HTML report about the - entire test run is written to a report directory, and a results file is written for - each test, in a "work" directory. The location of these directories can be - specified on the jtreg command line; the actual locations used - are reported to the console at the conclusion of the test run. - -

    For more information on jtreg, use the - the -help option for command-line help, or - the -onlineHelp option for the built-in online help. - Both of these options may optionally be followed by search - keywords

    - -

    jtreg can also be run from Ant. See - jtreg -onlineHelp ant for details.

    - -

    Both build.xml and Makefile contain "test" targets for running the tests. - - - diff --git a/langtools/src/share/opensource/javac/build.properties b/langtools/src/share/opensource/javac/build.properties deleted file mode 100644 index e42d827508f..00000000000 --- a/langtools/src/share/opensource/javac/build.properties +++ /dev/null @@ -1,13 +0,0 @@ -build.jdk.version = 1.7.0 -build.release = ${build.jdk.version}-opensource -build.number = b00 -build.user.release.suffix = ${user.name}_${build.fullversion.time} -build.full.version = ${build.release}-${build.user.release.suffix}-${build.number} - -# Set jtreg.home to jtreg installation directory -# jtreg.home = - -# Set test.jdk.home to baseline JDK used to run the tests -# test.jdk.home = - -compiler.source.level = 1.5 diff --git a/langtools/src/share/opensource/javac/build.xml b/langtools/src/share/opensource/javac/build.xml deleted file mode 100644 index 028221f576f..00000000000 --- a/langtools/src/share/opensource/javac/build.xml +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/langtools/src/share/opensource/javac/doc/document.css b/langtools/src/share/opensource/javac/doc/document.css deleted file mode 100644 index 7d6104aaaf6..00000000000 --- a/langtools/src/share/opensource/javac/doc/document.css +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2006 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * 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. - */ - -/* - * Copyright � 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -body { background-color: #FFFFFF; font-family: Arial, Helvetica, sans-serif; - border-top-width: 0px; border-right-width: 0px; - border-bottom-width: 0px; border-left-width: 0px} -h1 { font-family: Arial, Helvetica, sans-serif} -h2 { font-family: Arial, Helvetica, sans-serif; padding-top: 25px} -h3 { font-family: Arial, Helvetica, sans-serif} -h4 { font-family: Arial, Helvetica, sans-serif} -li { font-family: Arial, Helvetica, sans-serif} -table { font-family: Arial, Helvetica, sans-serif; - background-color: #FFFFFF; - margin-top: 0px; padding-top: 0px; - border-top-width: 0px; border-right-width: 0px; - border-bottom-width: 0px; border-left-width: 0px; - margin-bottom: 10px; margin-left: 0px; - padding-bottom: 5px; padding-left: 5px} -td { vertical-align: top; font-family: Arial, Helvetica, sans-serif} -td h1 { text-align: center} -td h2 { text-align: center; padding-top: 0px} -td h4 { text-align: center} -th { font-family: Arial, Helvetica, sans-serif; text-align: left; - padding-top: 10px; padding-right: 10px; padding-bottom: 0px; - padding-left: 10px; white-space: nowrap} - -.sun-darkblue { font-family: Arial, Helvetica, sans-serif ; - color: #FFFFFF; background-color: #666699} -.sun-lightblue { background-color: #9999CC} -.nav-link { font-family: Arial, Helvetica, sans-serif; font-size: x-small} -code { font-family: Courier, serif} diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/Context.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/Context.html deleted file mode 100644 index 289a593236e..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/Context.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - com.sun.tools.javac.comp.Enter - - - -

    com.sun.tools.javac.util.Context

    - -

    Contexts provides a way to share data between the different parts of - the compiler.

    - -

    They provide support for an abstract context, modelled loosely after - ThreadLocal but using a user-provided context instead of the current - thread.

    - -

    Within the compiler, a single Context is used for each - invocation of the compiler. The context is then used to ensure a - single copy of each compiler phase exists per compiler invocation.

    - -

    The context can be used to assist in extending the compiler by - extending its components. To do that, the extended component must - be registered before the base component. We break initialization - cycles by (1) registering a factory for the component rather than - the component itself, and (2) a convention for a pattern of usage - in which each base component registers itself by calling an - instance method that is overridden in extended components. A base - phase supporting extension would look something like this:

    - -
    -   public class Phase {
    -       protected static final Context.Key<Phase> phaseKey =
    - 	   new Context.Key<Phase>();
    - 
    -       public static Phase instance(Context context) {
    - 	   Phase instance = context.get(phaseKey);
    - 	   if (instance == null)
    - 	       // the phase has not been overridden
    - 	       instance = new Phase(context);
    - 	   return instance;
    -       }
    - 
    -       protected Phase(Context context) {
    - 	   context.put(phaseKey, this);
    - 	   // other intitialization follows...
    -       }
    -   }
    -        
    - -

    In the compiler, we simply use Phase.instance(context) to get - the reference to the phase. But in extensions of the compiler, we - must register extensions of the phases to replace the base phase, - and this must be done before any reference to the phase is accessed - using Phase.instance(). An extended phase might be declared thus:

    - -
    -   public class NewPhase extends Phase {
    -       protected NewPhase(Context context) {
    - 	   super(context);
    -       }
    -       public static void preRegister(final Context context) {
    -           context.put(phaseKey, new Context.Factory<Phase>() {
    - 	       public Phase make() {
    - 		   return new NewPhase(context);
    - 	       }
    -           });
    -       }
    -   }
    -        
    - -

    And is registered early in the extended compiler like this:

    - -
    -       NewPhase.preRegister(context);
    -        
    - - - - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/Enter.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/Enter.html deleted file mode 100644 index 19f1a0785b1..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/Enter.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - com.sun.tools.javac.comp.Enter - - - -

    com.sun.tools.javac.comp.Enter

    - - This enters symbols for all encountered definitions into - the symbol table. The pass consists of two phases, organized as - follows: - -
      -
    1. In the first phase, all class symbols are entered into their - enclosing scope, descending recursively down the tree for classes - which are members of other classes. The class symbols are given a - MemberEnter object as completer.

    2. - -

      In addition, - if any package-info.java files are found, - containing package annotations, then the TopLevel tree node for - the package-info.java file is put on the "to do" as well. -

      - -
    3. In the second phase, classes are completed using - MemberEnter.complete(). Completion might occur on demand, but - any classes that are not completed that way will be eventually - completed by processing the `uncompleted' queue. Completion - entails -

      • (1) determination of a class's parameters, supertype and - interfaces, as well as
      • (2) entering all symbols defined in the - class into its scope, with the exception of class symbols which - have been entered in phase 1.
      • -
      - (2) depends on (1) having been - completed for a class and all its superclasses and enclosing - classes. That's why, after doing (1), we put classes in a - `halfcompleted' queue. Only when we have performed (1) for a class - and all it's superclasses and enclosing classes, we proceed to - (2).

    4. -
    - -

    Whereas the first phase is organized as a sweep through all - compiled syntax trees, the second phase is demand. Members of a - class are entered when the contents of a class are first - accessed. This is accomplished by installing completer objects in - class symbols for compiled classes which invoke the member-enter - phase for the corresponding class tree.

    - -

    Classes migrate from one phase to the next via queues:

    - -
    -    class enter -> (Enter.uncompleted)         --> member enter (1)
    - 		-> (MemberEnter.halfcompleted) --> member enter (2)
    - 		-> (Todo)	               --> attribute
    - 						(only for toplevel classes)
    -        
    - - - - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/JavaCompiler.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/JavaCompiler.html deleted file mode 100644 index 4ee6f0fe0f2..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/JavaCompiler.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - JavaCompiler - - - -

    com.sun.tools.javac.main.JavaCompiler

    -

    - JavaCompiler provides (and enforces) a use-once method to compile a list of source files. - It invokes the various phases of the compiler to cause those source files to be compiled. -

    -
      -
    • All the files given on the command line are parsed, to build a - list of parse trees. Lexing and parsing are done with - Scanner and - Parser. - Lexical and syntax errors will be detected here. -

      - Note: Additional files may be parsed later, if they are found on the class/source path, and if they are newer than their matching class file. -

      -
    • - -
    • For each of the parse trees, their symbols are "entered", using - Enter. This will also set up a "to do" list of additional work to be done to compile those parse trees. - (more...) -
    • - -
    • If source code or stub code will be generated, a list is made - (in rootClasses) of all the top level classes defined in the parse trees. This will be used later, to check whether a class being processed was directly provided on the command line or not. -
    • - -
    • Then, for as long as there is work on the "to do" list, - JavaCompiler processes entries from the "to do" list. - In so doing, the compiler might find additional classes that need to be - processed, which may result in additional entries being added to the - "to do" list. (more...) -
    • - -
    • Print final messages.
    • - -
    • Return a list of class symbols, perhaps just those from - final lower (may not include top level classes) -
    • -
    - - - - - - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/Main.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/Main.html deleted file mode 100644 index b434883b295..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/Main.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - Main - - - -

    com.sun.tools.javac.main.Main

    - -

    - The normal main entry point is - com.sun.tools.javac.main.Main, - with a public API entry point at - com.sun.tools.javac.Main which just calls down to com.sun.tools.javac.main.Main. -

    - -

    The various parts of the compiler share common information by means of a - Context. - Every invocation of the compiler must have its own Context. - -

    - com.sun.tools.javac.main.Main does command line processing to determine the list of files to be compiled, and any applicable options. There are four types of options: -

      -
    • standard public options, e.g. -classpath -
    • extended public options, beginning -X, e.g. -Xlint -
    • hidden options -- not public or documented, e.g. -fullversion -
    • even more hidden options -- typically for debugging the compiler, beginning -XD, e.g. -XDrawDiagnostics -
    - - If there are files to be compiled, Main invokes - JavaCompiler (more...) - After JavaCompiler completes, the list of class symbols that was returned is discarded. -

    - -

    - Any and all exceptions are caught and handled, and a return code is - determined. Finally, the compiler exits. -

    - - - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/ToDo.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/ToDo.html deleted file mode 100644 index 3d56e846636..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/ToDo.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - JavaCompiler's "to do" list - - - -

    com.sun.tools.javac.main.JavaCompiler's "to do" list

    - -

    - After the source files have been parsed, and their symbols entered - in the symbol table, the top level classes and some other items end - up on JavaCompiler's "to do" list. -

    - -

    - For each entry on the "to do" list, JavaCompiler - processes it as follows: -

    - -
      -
    • Some parts of the compilation involve modifying the parse tree, - so a copy of the root of the tree is kept prior to such manipulation. -

      -

      - Note: this copy is just used to check whether the class is one of those - found in a compilation unit on the command line (i.e. in rootClasses). -

      - -
    • The top level classes are "attributed", using - Attr, - meaning that names and other elements within the parse tree are resolved - and associated with the corresponding types and symbols. Many semantic - errors may be detected here, either by Attr, or by - Check. -

      -

      While attributing the tree, class files will be read as necessary. - In addition, if a class is required, and a source file for the class is found - that is newer than the class file, the source file will be automatically parsed - and put on the "to do" list. This is done by registering JavaCompiler as an - implementation of - Attr.SourceCompleter. -

      -

      - Note: there is a hidden option -attrparseonly which can be used to skip - the rest of the processing for this file. In so doing, it "breaks" the - protocol use to save and restore the source file used to report error - messages (Log.useSource). There is a "try finally" block which - could reasonably be used/extended to restore the source file correctly. -

      -
    • - -
    • If there are no errors so far, flow analysis will be done for the class, using - Flow. - Flow analysis is used to check for definite assignment to variables, - and unreachable statements, which may result in additional errors. -

      -

      Note: flow analysis can be suppressed with the hidden - option -relax. -

      -
    • - -
    • If the "to do" item is a TopLevel tree, it will be the contents of a - package-info.java file, containing annotations for a package. - (See notes for Enter.) -
        -
      • Syntactic sugar is processed, using - Lower. - Lower is defined to return a list of trees for the translated classes - and all the translated inner classes.
      • -
      • If Lower returns a non-empty list, there is an assertion that - the list has a single element, in which case, code is generated, using - Gen, - and the resulting code is written out using - ClassWriter. -
      • -
      • No further processing is done on this "to do" item.
        -
      • -
      -

      Note that Enter will have processed all other TopLevel - putting the individual classes that it finds there on the "to do" - (and not the TopLevel node itself.) -

      - -
    • If stub outputs have been requested, with the hidden -stubs option, -
        -
      • If the class was one of those mentioned on the command line and is in - java.lang, - pretty print the source with no method bodies.
      • -
      • No further processing is done on this "to do" item.
      • -
      - -
    • Code involving generic types is translated to code without generic types, using - TransTypes. -
    • - -
    • If source output has been requested, with the hidden -s option -
        -
      • If the original tree was from command line, pretty print the source code -
      • -
      • No further processing is done on this "to do" item.
      • -
      - -
    • Syntactic sugar is processed, using - Lower. - This takes care of inner classes, class literals, assertions, foreach - loops, etc. - Lower is defined to return a list of trees for the translated classes - and all the translated inner classes.
    • - -

      - Note: see also the use of Lower earlier in the loop, when processing - TopLevel trees.

      - -
    • For each class returned by Lower
      -
        -
      • If source has been requestion with the hidden -printflat - option, the source of the class is printed. -
      • Otherwise, code for the class is generated, using - Gen, - and the resulting code is written out using - ClassWriter. -
      - -
    - -

    Issues

    - The "to do" list is mostly organized by top level classes, and not by - compilation units. This means that if a compilation unit contains several - classes, it is possible for code to be generated for some of the classes - in the file, at which point at error may be detected for one of the - remaining classes, preventing code from being generated for that and any - subsequent classes. This means that the compilation unit will be partially - compiled, with some but not all of the class files being generated. - (Bug 5011101) - - - - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/contents.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/contents.html deleted file mode 100644 index c936c5561f3..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/contents.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - com.sun.tools.javac.comp.Enter - - - Packages
    -
    - Classes
    - Context
    - Enter
    - JavaCompiler
    - Main
    - ToDo
    - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/index.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/index.html deleted file mode 100644 index fa75dca7adf..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - javac life cycle - - - - - - <body> - <p>This page uses frames, but your browser doesn't support them.</p> - </body> - - - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/packages.html b/langtools/src/share/opensource/javac/doc/javac_lifecycle/packages.html deleted file mode 100644 index 33d3e7a0cf4..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/packages.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - Packages - - - - -

    javac Packages

    - -

    With the exception of a publicly supported entry point at - com.sun.tools.javac.Main, - javac is organized as a set of packages under - com.sun.tools.javac. -

    - - - - - - - - - - -
    Sub-packageDescription -
    code - Classes to represent the internal semantics of a Java program -- - types, symbols, etc. - -
    comp - Classes that analyse and annotate the parse tree with semantic - details, such as determining the types and symbols referred to by identifiers. - -
    jvm - Back end classes to read and write class files. - -
    main - Top-level driver classes. The standard entry point to the compiler is - com.sun.tools.javac.main.Main (more...) - -
    parser - Classes to read a Java source file and create a corresponding parse tree. - -
    resources - Resource classes for messages generated by the compiler. Two of the - three classes are automagically generated by a "property file compiler" - from a property source file; the third is automagically generated during - the build to contain build version information. - -
    tree - Classes representing an annotated syntax tree for a Java program. - The top level node, representing the contents of a source file is - Tree.TopLevel. - -
    util - Utility classes used throughout the compiler, providing support for - diagnostics, access to the file system, and javac's collection classes. - - - diff --git a/langtools/src/share/opensource/javac/doc/javac_lifecycle/style.css b/langtools/src/share/opensource/javac/doc/javac_lifecycle/style.css deleted file mode 100644 index 473824b665e..00000000000 --- a/langtools/src/share/opensource/javac/doc/javac_lifecycle/style.css +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2006 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * 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. - */ - -body { color: black; background-color: #eeffee } -body.contents { background-color: #ddffdd } - -li { margin-top:10px } -p.note { font-size:smaller } - -.code { font-family:monospace } - diff --git a/langtools/src/share/opensource/javac/nbproject/project.xml b/langtools/src/share/opensource/javac/nbproject/project.xml deleted file mode 100644 index 45e3ea949a1..00000000000 --- a/langtools/src/share/opensource/javac/nbproject/project.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - org.netbeans.modules.ant.freeform - - - - openjdk-javac - - - - - java - src/share/classes - - - - - build - - - clean - - - docs - - - clean - build - - - xtest - - - - - - - src/share/classes - - - build.properties - - - build.xml - - - - - - - - - - - - - src/share/classes - 1.5 - - - - diff --git a/langtools/src/share/opensource/javac/src/bin/javac.sh b/langtools/src/share/opensource/javac/src/bin/javac.sh deleted file mode 100644 index 0c971b93308..00000000000 --- a/langtools/src/share/opensource/javac/src/bin/javac.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -# -# Copyright 2006 Sun Microsystems, Inc. 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. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the LICENSE file that accompanied this code. -# -# 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. -# - -mydir="`dirname $0`" - -java -jar "${mydir}"/../lib/javac.jar "$@" From 000ac830a034a03ab0b3bfe1e01fcc86296544b9 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 13 Mar 2008 16:06:34 -0700 Subject: [PATCH 156/274] 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint Values of non-static fields of a scalarized object should be saved in debug info to reallocate the object during deoptimization. Reviewed-by: never --- hotspot/src/share/vm/opto/callnode.cpp | 161 ++++++++++++++++++++++--- hotspot/src/share/vm/opto/callnode.hpp | 58 ++++++++- hotspot/src/share/vm/opto/classes.hpp | 1 + hotspot/src/share/vm/opto/compile.hpp | 16 ++- hotspot/src/share/vm/opto/graphKit.cpp | 8 ++ hotspot/src/share/vm/opto/macro.cpp | 17 ++- hotspot/src/share/vm/opto/matcher.cpp | 1 + hotspot/src/share/vm/opto/node.hpp | 3 + hotspot/src/share/vm/opto/output.cpp | 83 ++++++++++++- 9 files changed, 322 insertions(+), 26 deletions(-) diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index f32562de0e4..b0bcf4ee8da 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -230,6 +230,7 @@ JVMState::JVMState(ciMethod* method, JVMState* caller) { _locoff = TypeFunc::Parms; _stkoff = _locoff + _method->max_locals(); _monoff = _stkoff + _method->max_stack(); + _scloff = _monoff; _endoff = _monoff; _sp = 0; } @@ -242,6 +243,7 @@ JVMState::JVMState(int stack_size) { _locoff = TypeFunc::Parms; _stkoff = _locoff; _monoff = _stkoff + stack_size; + _scloff = _monoff; _endoff = _monoff; _sp = 0; } @@ -297,12 +299,22 @@ uint JVMState::debug_depth() const { return total; } +#ifndef PRODUCT + //------------------------------format_helper---------------------------------- // Given an allocation (a Chaitin object) and a Node decide if the Node carries // any defined value or not. If it does, print out the register or constant. -#ifndef PRODUCT -static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i ) { +static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i, GrowableArray *scobjs ) { if (n == NULL) { st->print(" NULL"); return; } + if (n->is_SafePointScalarObject()) { + // Scalar replacement. + SafePointScalarObjectNode* spobj = n->as_SafePointScalarObject(); + scobjs->append_if_missing(spobj); + int sco_n = scobjs->find(spobj); + assert(sco_n >= 0, ""); + st->print(" %s%d]=#ScObj" INT32_FORMAT, msg, i, sco_n); + return; + } if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined char buf[50]; regalloc->dump_register(n,buf); @@ -342,10 +354,8 @@ static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, c } } } -#endif //------------------------------format----------------------------------------- -#ifndef PRODUCT void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const { st->print(" #"); if( _method ) { @@ -356,24 +366,25 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) return; } if (n->is_MachSafePoint()) { + GrowableArray scobjs; MachSafePointNode *mcall = n->as_MachSafePoint(); uint i; // Print locals for( i = 0; i < (uint)loc_size(); i++ ) - format_helper( regalloc, st, mcall->local(this, i), "L[", i ); + format_helper( regalloc, st, mcall->local(this, i), "L[", i, &scobjs ); // Print stack for (i = 0; i < (uint)stk_size(); i++) { if ((uint)(_stkoff + i) >= mcall->len()) st->print(" oob "); else - format_helper( regalloc, st, mcall->stack(this, i), "STK[", i ); + format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs ); } for (i = 0; (int)i < nof_monitors(); i++) { Node *box = mcall->monitor_box(this, i); Node *obj = mcall->monitor_obj(this, i); if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) { while( !box->is_BoxLock() ) box = box->in(1); - format_helper( regalloc, st, box, "MON-BOX[", i ); + format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs ); } else { OptoReg::Name box_reg = BoxLockNode::stack_slot(box); st->print(" MON-BOX%d=%s+%d", @@ -381,15 +392,71 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) OptoReg::regname(OptoReg::c_frame_pointer), regalloc->reg2offset(box_reg)); } - format_helper( regalloc, st, obj, "MON-OBJ[", i ); + format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs ); + } + + for (i = 0; i < (uint)scobjs.length(); i++) { + // Scalar replaced objects. + st->print_cr(""); + st->print(" # ScObj" INT32_FORMAT " ", i); + SafePointScalarObjectNode* spobj = scobjs.at(i); + ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass(); + assert(cik->is_instance_klass() || + cik->is_array_klass(), "Not supported allocation."); + ciInstanceKlass *iklass = NULL; + if (cik->is_instance_klass()) { + cik->print_name_on(st); + iklass = cik->as_instance_klass(); + } else if (cik->is_type_array_klass()) { + cik->as_array_klass()->base_element_type()->print_name_on(st); + st->print("[%d]=", spobj->n_fields()); + } else if (cik->is_obj_array_klass()) { + ciType* cie = cik->as_array_klass()->base_element_type(); + int ndim = 1; + while (cie->is_obj_array_klass()) { + ndim += 1; + cie = cie->as_array_klass()->base_element_type(); + } + cie->print_name_on(st); + while (ndim-- > 0) { + st->print("[]"); + } + st->print("[%d]=", spobj->n_fields()); + } + st->print("{"); + uint nf = spobj->n_fields(); + if (nf > 0) { + uint first_ind = spobj->first_index(); + Node* fld_node = mcall->in(first_ind); + ciField* cifield; + if (iklass != NULL) { + st->print(" ["); + cifield = iklass->nonstatic_field_at(0); + cifield->print_name_on(st); + format_helper( regalloc, st, fld_node, ":", 0, &scobjs ); + } else { + format_helper( regalloc, st, fld_node, "[", 0, &scobjs ); + } + for (uint j = 1; j < nf; j++) { + fld_node = mcall->in(first_ind+j); + if (iklass != NULL) { + st->print(", ["); + cifield = iklass->nonstatic_field_at(j); + cifield->print_name_on(st); + format_helper( regalloc, st, fld_node, ":", j, &scobjs ); + } else { + format_helper( regalloc, st, fld_node, ", [", j, &scobjs ); + } + } + } + st->print(" }"); } } st->print_cr(""); if (caller() != NULL) caller()->format(regalloc, n, st); } -#endif -#ifndef PRODUCT + void JVMState::dump_spec(outputStream *st) const { if (_method != NULL) { bool printed = false; @@ -419,9 +486,8 @@ void JVMState::dump_spec(outputStream *st) const { } if (caller() != NULL) caller()->dump_spec(st); } -#endif -#ifndef PRODUCT + void JVMState::dump_on(outputStream* st) const { if (_map && !((uintptr_t)_map & 1)) { if (_map->len() > _map->req()) { // _map->has_exceptions() @@ -434,8 +500,8 @@ void JVMState::dump_on(outputStream* st) const { } _map->dump(2); } - st->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=", - depth(), locoff(), stkoff(), monoff(), endoff(), monitor_depth(), sp(), bci()); + st->print("JVMS depth=%d loc=%d stk=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d method=", + depth(), locoff(), stkoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci()); if (_method == NULL) { st->print_cr("(none)"); } else { @@ -465,6 +531,7 @@ JVMState* JVMState::clone_shallow(Compile* C) const { n->set_locoff(_locoff); n->set_stkoff(_stkoff); n->set_monoff(_monoff); + n->set_scloff(_scloff); n->set_endoff(_endoff); n->set_sp(_sp); n->set_map(_map); @@ -765,6 +832,7 @@ const RegMask &SafePointNode::out_RegMask() const { void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) { assert((int)grow_by > 0, "sanity"); int monoff = jvms->monoff(); + int scloff = jvms->scloff(); int endoff = jvms->endoff(); assert(endoff == (int)req(), "no other states or debug info after me"); Node* top = Compile::current()->top(); @@ -772,6 +840,7 @@ void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) { ins_req(monoff, top); } jvms->set_monoff(monoff + grow_by); + jvms->set_scloff(scloff + grow_by); jvms->set_endoff(endoff + grow_by); } @@ -781,6 +850,7 @@ void SafePointNode::push_monitor(const FastLockNode *lock) { const int MonitorEdges = 2; assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges"); assert(req() == jvms()->endoff(), "correct sizing"); + int nextmon = jvms()->scloff(); if (GenerateSynchronizationCode) { add_req(lock->box_node()); add_req(lock->obj_node()); @@ -788,6 +858,7 @@ void SafePointNode::push_monitor(const FastLockNode *lock) { add_req(NULL); add_req(NULL); } + jvms()->set_scloff(nextmon+MonitorEdges); jvms()->set_endoff(req()); } @@ -795,10 +866,13 @@ void SafePointNode::pop_monitor() { // Delete last monitor from debug info debug_only(int num_before_pop = jvms()->nof_monitors()); const int MonitorEdges = (1<scloff(); int endoff = jvms()->endoff(); + int new_scloff = scloff - MonitorEdges; int new_endoff = endoff - MonitorEdges; + jvms()->set_scloff(new_scloff); jvms()->set_endoff(new_endoff); - while (endoff > new_endoff) del_req(--endoff); + while (scloff > new_scloff) del_req(--scloff); assert(jvms()->nof_monitors() == num_before_pop-1, ""); } @@ -822,6 +896,63 @@ uint SafePointNode::match_edge(uint idx) const { return (TypeFunc::Parms == idx); } +//============== SafePointScalarObjectNode ============== + +SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp, +#ifdef ASSERT + AllocateNode* alloc, +#endif + uint first_index, + uint n_fields) : + TypeNode(tp, 1), // 1 control input -- seems required. Get from root. +#ifdef ASSERT + _alloc(alloc), +#endif + _first_index(first_index), + _n_fields(n_fields) +{ + init_class_id(Class_SafePointScalarObject); +} + + +uint SafePointScalarObjectNode::ideal_reg() const { + return 0; // No matching to machine instruction +} + +const RegMask &SafePointScalarObjectNode::in_RegMask(uint idx) const { + return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]); +} + +const RegMask &SafePointScalarObjectNode::out_RegMask() const { + return RegMask::Empty; +} + +uint SafePointScalarObjectNode::match_edge(uint idx) const { + return 0; +} + +SafePointScalarObjectNode* +SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const { + void* cached = (*sosn_map)[(void*)this]; + if (cached != NULL) { + return (SafePointScalarObjectNode*)cached; + } + Compile* C = Compile::current(); + SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone(); + res->_first_index += jvms_adj; + sosn_map->Insert((void*)this, (void*)res); + return res; +} + + +#ifndef PRODUCT +void SafePointScalarObjectNode::dump_spec(outputStream *st) const { + st->print(" # fields@[%d..%d]", first_index(), + first_index() + n_fields() - 1); +} + +#endif + //============================================================================= uint AllocateNode::size_of() const { return sizeof(*this); } diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index d07a4d78d0e..179ad06b007 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -184,6 +184,7 @@ private: uint _locoff; // Offset to locals in input edge mapping uint _stkoff; // Offset to stack in input edge mapping uint _monoff; // Offset to monitors in input edge mapping + uint _scloff; // Offset to fields of scalar objs in input edge mapping uint _endoff; // Offset to end of input edge mapping uint _sp; // Jave Expression Stack Pointer for this state int _bci; // Byte Code Index of this JVM point @@ -207,16 +208,19 @@ public: uint stkoff() const { return _stkoff; } uint argoff() const { return _stkoff + _sp; } uint monoff() const { return _monoff; } + uint scloff() const { return _scloff; } uint endoff() const { return _endoff; } uint oopoff() const { return debug_end(); } int loc_size() const { return _stkoff - _locoff; } int stk_size() const { return _monoff - _stkoff; } - int mon_size() const { return _endoff - _monoff; } + int mon_size() const { return _scloff - _monoff; } + int scl_size() const { return _endoff - _scloff; } bool is_loc(uint i) const { return i >= _locoff && i < _stkoff; } bool is_stk(uint i) const { return i >= _stkoff && i < _monoff; } - bool is_mon(uint i) const { return i >= _monoff && i < _endoff; } + bool is_mon(uint i) const { return i >= _monoff && i < _scloff; } + bool is_scl(uint i) const { return i >= _scloff && i < _endoff; } uint sp() const { return _sp; } int bci() const { return _bci; } @@ -227,7 +231,9 @@ public: uint depth() const { return _depth; } uint debug_start() const; // returns locoff of root caller uint debug_end() const; // returns endoff of self - uint debug_size() const { return loc_size() + sp() + mon_size(); } + uint debug_size() const { + return loc_size() + sp() + mon_size() + scl_size(); + } uint debug_depth() const; // returns sum of debug_size values at all depths // Returns the JVM state at the desired depth (1 == root). @@ -254,8 +260,11 @@ public: void set_locoff(uint off) { _locoff = off; } void set_stkoff(uint off) { _stkoff = off; } void set_monoff(uint off) { _monoff = off; } + void set_scloff(uint off) { _scloff = off; } void set_endoff(uint off) { _endoff = off; } - void set_offsets(uint off) { _locoff = _stkoff = _monoff = _endoff = off; } + void set_offsets(uint off) { + _locoff = _stkoff = _monoff = _scloff = _endoff = off; + } void set_map(SafePointNode *map) { _map = map; } void set_sp(uint sp) { _sp = sp; } void set_bci(int bci) { _bci = bci; } @@ -399,6 +408,47 @@ public: #endif }; +//------------------------------SafePointScalarObjectNode---------------------- +// A SafePointScalarObjectNode represents the state of a scalarized object +// at a safepoint. + +class SafePointScalarObjectNode: public TypeNode { + uint _first_index; // First input edge index of a SafePoint node where + // states of the scalarized object fields are collected. + uint _n_fields; // Number of non-static fields of the scalarized object. + DEBUG_ONLY(AllocateNode* _alloc); +public: + SafePointScalarObjectNode(const TypeOopPtr* tp, +#ifdef ASSERT + AllocateNode* alloc, +#endif + uint first_index, uint n_fields); + virtual int Opcode() const; + virtual uint ideal_reg() const; + virtual const RegMask &in_RegMask(uint) const; + virtual const RegMask &out_RegMask() const; + virtual uint match_edge(uint idx) const; + + uint first_index() const { return _first_index; } + uint n_fields() const { return _n_fields; } + DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; }) + + virtual uint size_of() const { return sizeof(*this); } + + // Assumes that "this" is an argument to a safepoint node "s", and that + // "new_call" is being created to correspond to "s". But the difference + // between the start index of the jvmstates of "new_call" and "s" is + // "jvms_adj". Produce and return a SafePointScalarObjectNode that + // corresponds appropriately to "this" in "new_call". Assumes that + // "sosn_map" is a map, specific to the translation of "s" to "new_call", + // mapping old SafePointScalarObjectNodes to new, to avoid multiple copies. + SafePointScalarObjectNode* clone(int jvms_adj, Dict* sosn_map) const; + +#ifndef PRODUCT + virtual void dump_spec(outputStream *st) const; +#endif +}; + //------------------------------CallNode--------------------------------------- // Call nodes now subsume the function of debug nodes at callsites, so they // contain the functionality of a full scope chain of debug nodes. diff --git a/hotspot/src/share/vm/opto/classes.hpp b/hotspot/src/share/vm/opto/classes.hpp index 26eff2b4eb9..0c5f53ba307 100644 --- a/hotspot/src/share/vm/opto/classes.hpp +++ b/hotspot/src/share/vm/opto/classes.hpp @@ -185,6 +185,7 @@ macro(Root) macro(RoundDouble) macro(RoundFloat) macro(SafePoint) +macro(SafePointScalarObject) macro(SCMemProj) macro(SinD) macro(SqrtD) diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index a4e4c1401f3..419bc68bebe 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -606,8 +606,20 @@ class Compile : public Phase { // Build OopMaps for each GC point void BuildOopMaps(); - // Append debug info for the node to the array - void FillLocArray( int idx, Node *local, GrowableArray *array ); + + // Append debug info for the node "local" at safepoint node "sfpt" to the + // "array", May also consult and add to "objs", which describes the + // scalar-replaced objects. + void FillLocArray( int idx, MachSafePointNode* sfpt, + Node *local, GrowableArray *array, + GrowableArray *objs ); + + // If "objs" contains an ObjectValue whose id is "id", returns it, else NULL. + static ObjectValue* sv_for_node_id(GrowableArray *objs, int id); + // Requres that "objs" does not contains an ObjectValue whose id matches + // that of "sv. Appends "sv". + static void set_sv_for_object_node(GrowableArray *objs, + ObjectValue* sv ); // Process an OopMap Element while emitting nodes void Process_OopMap_Node(MachNode *mach, int code_offset); diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 45471f29fde..b7dc9e1ed73 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -857,6 +857,13 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) { for (j = 0; j < l; j++) call->set_req(p++, in_map->in(k+j)); + // Copy any scalar object fields. + k = in_jvms->scloff(); + l = in_jvms->scl_size(); + out_jvms->set_scloff(p); + for (j = 0; j < l; j++) + call->set_req(p++, in_map->in(k+j)); + // Finish the new jvms. out_jvms->set_endoff(p); @@ -864,6 +871,7 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) { assert(out_jvms->depth() == in_jvms->depth(), "depth must match"); assert(out_jvms->loc_size() == in_jvms->loc_size(), "size must match"); assert(out_jvms->mon_size() == in_jvms->mon_size(), "size must match"); + assert(out_jvms->scl_size() == in_jvms->scl_size(), "size must match"); assert(out_jvms->debug_size() == in_jvms->debug_size(), "size must match"); // Update the two tail pointers in parallel. diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 9ba4bc3d4ff..4a8ffd1076f 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -54,15 +54,30 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal uint new_dbg_start = newcall->tf()->domain()->cnt(); int jvms_adj = new_dbg_start - old_dbg_start; assert (new_dbg_start == newcall->req(), "argument count mismatch"); + + Dict* sosn_map = new Dict(cmpkey,hashkey); for (uint i = old_dbg_start; i < oldcall->req(); i++) { - newcall->add_req(oldcall->in(i)); + Node* old_in = oldcall->in(i); + // Clone old SafePointScalarObjectNodes, adjusting their field contents. + if (old_in->is_SafePointScalarObject()) { + SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); + uint old_unique = C->unique(); + Node* new_in = old_sosn->clone(jvms_adj, sosn_map); + if (old_unique != C->unique()) { + new_in = transform_later(new_in); // Register new node. + } + old_in = new_in; + } + newcall->add_req(old_in); } + newcall->set_jvms(oldcall->jvms()); for (JVMState *jvms = newcall->jvms(); jvms != NULL; jvms = jvms->caller()) { jvms->set_map(newcall); jvms->set_locoff(jvms->locoff()+jvms_adj); jvms->set_stkoff(jvms->stkoff()+jvms_adj); jvms->set_monoff(jvms->monoff()+jvms_adj); + jvms->set_scloff(jvms->scloff()+jvms_adj); jvms->set_endoff(jvms->endoff()+jvms_adj); } } diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index a8d673a7f26..7d9cd51eff6 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -1647,6 +1647,7 @@ void Matcher::find_shared( Node *n ) { case Op_Phi: // Treat Phis as shared roots case Op_Parm: case Op_Proj: // All handled specially during matching + case Op_SafePointScalarObject: set_shared(n); set_dontcare(n); break; diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 881de4d21b9..ac35f9b4f1b 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -106,6 +106,7 @@ class RegMask; class RegionNode; class RootNode; class SafePointNode; +class SafePointScalarObjectNode; class StartNode; class State; class StoreNode; @@ -575,6 +576,7 @@ public: DEFINE_CLASS_ID(ConstraintCast, Type, 1) DEFINE_CLASS_ID(CheckCastPP, Type, 2) DEFINE_CLASS_ID(CMove, Type, 3) + DEFINE_CLASS_ID(SafePointScalarObject, Type, 4) DEFINE_CLASS_ID(Mem, Node, 6) DEFINE_CLASS_ID(Load, Mem, 0) @@ -721,6 +723,7 @@ public: DEFINE_CLASS_QUERY(Region) DEFINE_CLASS_QUERY(Root) DEFINE_CLASS_QUERY(SafePoint) + DEFINE_CLASS_QUERY(SafePointScalarObject) DEFINE_CLASS_QUERY(Start) DEFINE_CLASS_QUERY(Store) DEFINE_CLASS_QUERY(Sub) diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index 690459e5f0b..3c06b135f9a 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -561,7 +561,30 @@ static LocationValue *new_loc_value( PhaseRegAlloc *ra, OptoReg::Name regnum, Lo : new LocationValue(Location::new_stk_loc(l_type, ra->reg2offset(regnum))); } -void Compile::FillLocArray( int idx, Node *local, GrowableArray *array ) { + +ObjectValue* +Compile::sv_for_node_id(GrowableArray *objs, int id) { + for (int i = 0; i < objs->length(); i++) { + assert(objs->at(i)->is_object(), "corrupt object cache"); + ObjectValue* sv = (ObjectValue*) objs->at(i); + if (sv->id() == id) { + return sv; + } + } + // Otherwise.. + return NULL; +} + +void Compile::set_sv_for_object_node(GrowableArray *objs, + ObjectValue* sv ) { + assert(sv_for_node_id(objs, sv->id()) == NULL, "Precondition"); + objs->append(sv); +} + + +void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, + GrowableArray *array, + GrowableArray *objs ) { assert( local, "use _top instead of null" ); if (array->length() != idx) { assert(array->length() == idx + 1, "Unexpected array count"); @@ -578,6 +601,29 @@ void Compile::FillLocArray( int idx, Node *local, GrowableArray *ar } const Type *t = local->bottom_type(); + // Is it a safepoint scalar object node? + if (local->is_SafePointScalarObject()) { + SafePointScalarObjectNode* spobj = local->as_SafePointScalarObject(); + + ObjectValue* sv = Compile::sv_for_node_id(objs, spobj->_idx); + if (sv == NULL) { + ciKlass* cik = t->is_oopptr()->klass(); + assert(cik->is_instance_klass() || + cik->is_array_klass(), "Not supported allocation."); + sv = new ObjectValue(spobj->_idx, + new ConstantOopWriteValue(cik->encoding())); + Compile::set_sv_for_object_node(objs, sv); + + uint first_ind = spobj->first_index(); + for (uint i = 0; i < spobj->n_fields(); i++) { + Node* fld_node = sfpt->in(first_ind+i); + (void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs); + } + } + array->append(sv); + return; + } + // Grab the register number for the local OptoReg::Name regnum = _regalloc->get_reg_first(local); if( OptoReg::is_valid(regnum) ) {// Got a register/stack? @@ -755,6 +801,11 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { JVMState* youngest_jvms = sfn->jvms(); int max_depth = youngest_jvms->depth(); + // Allocate the object pool for scalar-replaced objects -- the map from + // small-integer keys (which can be recorded in the local and ostack + // arrays) to descriptions of the object state. + GrowableArray *objs = new GrowableArray(); + // Visit scopes from oldest to youngest. for (int depth = 1; depth <= max_depth; depth++) { JVMState* jvms = youngest_jvms->of_depth(depth); @@ -773,13 +824,13 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { // Insert locals into the locarray GrowableArray *locarray = new GrowableArray(num_locs); for( idx = 0; idx < num_locs; idx++ ) { - FillLocArray( idx, sfn->local(jvms, idx), locarray ); + FillLocArray( idx, sfn, sfn->local(jvms, idx), locarray, objs ); } // Insert expression stack entries into the exparray GrowableArray *exparray = new GrowableArray(num_exps); for( idx = 0; idx < num_exps; idx++ ) { - FillLocArray( idx, sfn->stack(jvms, idx), exparray ); + FillLocArray( idx, sfn, sfn->stack(jvms, idx), exparray, objs ); } // Add in mappings of the monitors @@ -803,7 +854,27 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { // Create ScopeValue for object ScopeValue *scval = NULL; - if( !obj_node->is_Con() ) { + + if( obj_node->is_SafePointScalarObject() ) { + SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject(); + scval = Compile::sv_for_node_id(objs, spobj->_idx); + if (scval == NULL) { + const Type *t = obj_node->bottom_type(); + ciKlass* cik = t->is_oopptr()->klass(); + assert(cik->is_instance_klass() || + cik->is_array_klass(), "Not supported allocation."); + ObjectValue* sv = new ObjectValue(spobj->_idx, + new ConstantOopWriteValue(cik->encoding())); + Compile::set_sv_for_object_node(objs, sv); + + uint first_ind = spobj->first_index(); + for (uint i = 0; i < spobj->n_fields(); i++) { + Node* fld_node = sfn->in(first_ind+i); + (void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs); + } + scval = sv; + } + } else if( !obj_node->is_Con() ) { OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node); scval = new_loc_value( _regalloc, obj_reg, Location::oop ); } else { @@ -814,6 +885,9 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { monarray->append(new MonitorValue(scval, Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg)))); } + // We dump the object pool first, since deoptimization reads it in first. + debug_info()->dump_object_pool(objs); + // Build first class objects to pass to scope DebugToken *locvals = debug_info()->create_scope_values(locarray); DebugToken *expvals = debug_info()->create_scope_values(exparray); @@ -823,6 +897,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { ciMethod* scope_method = method ? method : _method; // Describe the scope here assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI"); + // Now we can describe the scope. debug_info()->describe_scope(safepoint_pc_offset,scope_method,jvms->bci(),locvals,expvals,monvals); } // End jvms loop From db98b5b071aa3dac5c92c0d77c7631a52a38c9cc Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Thu, 13 Mar 2008 16:12:15 -0700 Subject: [PATCH 157/274] 6675289: Make default production build NOT include an openjdk build SKIP_OPENJDK_BUILD now set to true. Reviewed-by: xdono --- make/Defs-internal.gmk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/make/Defs-internal.gmk b/make/Defs-internal.gmk index 7343049c61b..97c9395f068 100644 --- a/make/Defs-internal.gmk +++ b/make/Defs-internal.gmk @@ -150,7 +150,9 @@ ifdef OPENJDK SKIP_OPENJDK_BUILD = true else ifndef SKIP_OPENJDK_BUILD - SKIP_OPENJDK_BUILD = false + #SKIP_OPENJDK_BUILD = false + # Until 6675289 is resolved, or this feature is removed. + SKIP_OPENJDK_BUILD = true endif endif From 30dc0edfc877000c0ae20384f228b45ba82807b7 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 13 Mar 2008 16:31:32 -0700 Subject: [PATCH 158/274] 6673473: (Escape Analysis) Add the instance's field information to PhiNode Avoid an infinite generation of instance's field values Phi nodes. Reviewed-by: never --- hotspot/src/share/vm/opto/cfgnode.hpp | 35 +++++- hotspot/src/share/vm/opto/loopopts.cpp | 13 ++- hotspot/src/share/vm/opto/memnode.cpp | 150 +++++++++++++++++-------- hotspot/src/share/vm/opto/memnode.hpp | 3 + hotspot/src/share/vm/opto/type.cpp | 23 ++-- hotspot/src/share/vm/opto/type.hpp | 1 + 6 files changed, 166 insertions(+), 59 deletions(-) diff --git a/hotspot/src/share/vm/opto/cfgnode.hpp b/hotspot/src/share/vm/opto/cfgnode.hpp index b198a5bf7ab..79811ee6b4d 100644 --- a/hotspot/src/share/vm/opto/cfgnode.hpp +++ b/hotspot/src/share/vm/opto/cfgnode.hpp @@ -110,14 +110,15 @@ class JProjNode : public ProjNode { // input in slot 0. class PhiNode : public TypeNode { const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes. + const int _inst_id; // Instance id of the memory slice. + const int _inst_index; // Alias index of the instance memory slice. + // Array elements references have the same alias_idx but different offset. + const int _inst_offset; // Offset of the instance memory slice. // Size is bigger to hold the _adr_type field. virtual uint hash() const; // Check the type virtual uint cmp( const Node &n ) const; virtual uint size_of() const { return sizeof(*this); } - // Determine a unique non-trivial input, if any. - // Ignore casts if it helps. Return NULL on failure. - Node* unique_input(PhaseTransform *phase); // Determine if CMoveNode::is_cmove_id can be used at this join point. Node* is_cmove_id(PhaseTransform* phase, int true_path); @@ -127,8 +128,16 @@ public: Input // Input values are [1..len) }; - PhiNode( Node *r, const Type *t, const TypePtr* at = NULL ) - : TypeNode(t,r->req()), _adr_type(at) { + PhiNode( Node *r, const Type *t, const TypePtr* at = NULL, + const int iid = TypeOopPtr::UNKNOWN_INSTANCE, + const int iidx = Compile::AliasIdxTop, + const int ioffs = Type::OffsetTop ) + : TypeNode(t,r->req()), + _adr_type(at), + _inst_id(iid), + _inst_index(iidx), + _inst_offset(ioffs) + { init_class_id(Class_Phi); init_req(0, r); verify_adr_type(); @@ -152,6 +161,10 @@ public: return NULL; // not a copy! } + // Determine a unique non-trivial input, if any. + // Ignore casts if it helps. Return NULL on failure. + Node* unique_input(PhaseTransform *phase); + // Check for a simple dead loop. enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop }; LoopSafety simple_data_loop_check(Node *in) const; @@ -161,6 +174,18 @@ public: virtual int Opcode() const; virtual bool pinned() const { return in(0) != 0; } virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; } + + const int inst_id() const { return _inst_id; } + const int inst_index() const { return _inst_index; } + const int inst_offset() const { return _inst_offset; } + bool is_same_inst_field(const Type* tp, int id, int index, int offset) { + return type()->basic_type() == tp->basic_type() && + inst_id() == id && + inst_index() == index && + inst_offset() == offset && + type()->higher_equal(tp); + } + virtual const Type *Value( PhaseTransform *phase ) const; virtual Node *Identity( PhaseTransform *phase ); virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index d7b9ec89337..d0a94b4c265 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -32,7 +32,18 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) { int wins = 0; assert( !n->is_CFG(), "" ); assert( region->is_Region(), "" ); - Node *phi = new (C, region->req()) PhiNode( region, n->bottom_type() ); + + const Type* type = n->bottom_type(); + const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr(); + Node *phi; + if( t_oop != NULL && t_oop->is_instance_field() ) { + int iid = t_oop->instance_id(); + int index = C->get_alias_index(t_oop); + int offset = t_oop->offset(); + phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset); + } else { + phi = new (C,region->req()) PhiNode(region, type); + } uint old_unique = C->unique(); for( uint i = 1; i < region->req(); i++ ) { Node *x; diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index 2cfa4281c48..936a303c8d0 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -87,6 +87,58 @@ extern void print_alias_types(); #endif +static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st) { + uint alias_idx = phase->C->get_alias_index(tp); + Node *mem = mmem; +#ifdef ASSERT + { + // Check that current type is consistent with the alias index used during graph construction + assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx"); + bool consistent = adr_check == NULL || adr_check->empty() || + phase->C->must_alias(adr_check, alias_idx ); + // Sometimes dead array references collapse to a[-1], a[-2], or a[-3] + if( !consistent && adr_check != NULL && !adr_check->empty() && + tp->isa_aryptr() && tp->offset() == Type::OffsetBot && + adr_check->isa_aryptr() && adr_check->offset() != Type::OffsetBot && + ( adr_check->offset() == arrayOopDesc::length_offset_in_bytes() || + adr_check->offset() == oopDesc::klass_offset_in_bytes() || + adr_check->offset() == oopDesc::mark_offset_in_bytes() ) ) { + // don't assert if it is dead code. + consistent = true; + } + if( !consistent ) { + st->print("alias_idx==%d, adr_check==", alias_idx); + if( adr_check == NULL ) { + st->print("NULL"); + } else { + adr_check->dump(); + } + st->cr(); + print_alias_types(); + assert(consistent, "adr_check must match alias idx"); + } + } +#endif + // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally + // means an array I have not precisely typed yet. Do not do any + // alias stuff with it any time soon. + const TypeOopPtr *tinst = tp->isa_oopptr(); + if( tp->base() != Type::AnyPtr && + !(tinst && + tinst->klass()->is_java_lang_Object() && + tinst->offset() == Type::OffsetBot) ) { + // compress paths and change unreachable cycles to TOP + // If not, we can update the input infinitely along a MergeMem cycle + // Equivalent code in PhiNode::Ideal + Node* m = phase->transform(mmem); + // If tranformed to a MergeMem, get the desired slice + // Otherwise the returned node represents memory for every slice + mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; + // Update input if it is progress over what we have now + } + return mem; +} + //--------------------------Ideal_common--------------------------------------- // Look for degenerate control and memory inputs. Bypass MergeMem inputs. // Unhook non-raw memories from complete (macro-expanded) initializations. @@ -119,48 +171,8 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { if (mem->is_MergeMem()) { MergeMemNode* mmem = mem->as_MergeMem(); const TypePtr *tp = t_adr->is_ptr(); - uint alias_idx = phase->C->get_alias_index(tp); -#ifdef ASSERT - { - // Check that current type is consistent with the alias index used during graph construction - assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx"); - const TypePtr *adr_t = adr_type(); - bool consistent = adr_t == NULL || adr_t->empty() || phase->C->must_alias(adr_t, alias_idx ); - // Sometimes dead array references collapse to a[-1], a[-2], or a[-3] - if( !consistent && adr_t != NULL && !adr_t->empty() && - tp->isa_aryptr() && tp->offset() == Type::OffsetBot && - adr_t->isa_aryptr() && adr_t->offset() != Type::OffsetBot && - ( adr_t->offset() == arrayOopDesc::length_offset_in_bytes() || - adr_t->offset() == oopDesc::klass_offset_in_bytes() || - adr_t->offset() == oopDesc::mark_offset_in_bytes() ) ) { - // don't assert if it is dead code. - consistent = true; - } - if( !consistent ) { - tty->print("alias_idx==%d, adr_type()==", alias_idx); if( adr_t == NULL ) { tty->print("NULL"); } else { adr_t->dump(); } - tty->cr(); - print_alias_types(); - assert(consistent, "adr_type must match alias idx"); - } - } -#endif - // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally - // means an array I have not precisely typed yet. Do not do any - // alias stuff with it any time soon. - const TypeInstPtr *tinst = tp->isa_instptr(); - if( tp->base() != Type::AnyPtr && - !(tinst && - tinst->klass()->is_java_lang_Object() && - tinst->offset() == Type::OffsetBot) ) { - // compress paths and change unreachable cycles to TOP - // If not, we can update the input infinitely along a MergeMem cycle - // Equivalent code in PhiNode::Ideal - Node* m = phase->transform(mmem); - // If tranformed to a MergeMem, get the desired slice - // Otherwise the returned node represents memory for every slice - mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; - // Update input if it is progress over what we have now - } + + mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty); } if (mem != old_mem) { @@ -534,7 +546,10 @@ Node *MemNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { const Node* call = adr->in(0); if (call->is_CallStaticJava()) { const CallStaticJavaNode* call_java = call->as_CallStaticJava(); - assert(call_java && call_java->method() == NULL, "must be runtime call"); + const TypeTuple *r = call_java->tf()->range(); + assert(r->cnt() > TypeFunc::Parms, "must return value"); + const Type* ret_type = r->field_at(TypeFunc::Parms); + assert(ret_type && ret_type->isa_ptr(), "must return pointer"); // We further presume that this is one of // new_instance_Java, new_array_Java, or // the like, but do not assert for this. @@ -732,6 +747,21 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { return NULL; } +//----------------------is_instance_field_load_with_local_phi------------------ +bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) { + if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl && + in(MemNode::Address)->is_AddP() ) { + const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr(); + // Only instances. + if( t_oop != NULL && t_oop->is_instance_field() && + t_oop->offset() != Type::OffsetBot && + t_oop->offset() != Type::OffsetTop) { + return true; + } + } + return false; +} + //------------------------------Identity--------------------------------------- // Loads are identity if previous store is to same address Node *LoadNode::Identity( PhaseTransform *phase ) { @@ -754,6 +784,25 @@ Node *LoadNode::Identity( PhaseTransform *phase ) { // usually runs first, producing the singleton type of the Con.) return value; } + + // Search for an existing data phi which was generated before for the same + // instance's field to avoid infinite genertion of phis in a loop. + Node *region = mem->in(0); + if (is_instance_field_load_with_local_phi(region)) { + const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr(); + int this_index = phase->C->get_alias_index(addr_t); + int this_offset = addr_t->offset(); + int this_id = addr_t->is_oopptr()->instance_id(); + const Type* this_type = bottom_type(); + for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { + Node* phi = region->fast_out(i); + if (phi->is_Phi() && phi != mem && + phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) { + return phi; + } + } + } + return this; } @@ -1189,6 +1238,17 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { return value->bottom_type(); } + const TypeOopPtr *tinst = tp->isa_oopptr(); + if (tinst != NULL && tinst->is_instance_field()) { + // If we have an instance type and our memory input is the + // programs's initial memory state, there is no matching store, + // so just return a zero of the appropriate type + Node *mem = in(MemNode::Memory); + if (mem->is_Parm() && mem->in(0)->is_Start()) { + assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm"); + return Type::get_zero_type(_type->basic_type()); + } + } return _type; } @@ -1712,7 +1772,7 @@ bool StoreNode::value_never_loaded( PhaseTransform *phase) const { const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr(); if (adr_oop == NULL) return false; - if (!adr_oop->is_instance()) + if (!adr_oop->is_instance_field()) return false; // if not a distinct instance, there may be aliases of the address for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) { Node *use = adr->fast_out(i); @@ -3244,7 +3304,7 @@ Node *MergeMemNode::Ideal(PhaseGVN *phase, bool can_reshape) { } } - assert(verify_sparse(), "please, no dups of base"); + assert(progress || verify_sparse(), "please, no dups of base"); return progress; } diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp index 8c8676b4d36..bff0fd93b4b 100644 --- a/hotspot/src/share/vm/opto/memnode.hpp +++ b/hotspot/src/share/vm/opto/memnode.hpp @@ -172,6 +172,9 @@ public: // Map a load opcode to its corresponding store opcode. virtual int store_Opcode() const = 0; + // Check if the load's memory input is a Phi node with the same control. + bool is_instance_field_load_with_local_phi(Node* ctrl); + #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index e396c9732b0..333fb476b0f 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -3164,7 +3164,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { case TopPTR: // Compute new klass on demand, do not use tap->_klass xk = (tap->_klass_is_exact | this->_klass_is_exact); - return make( ptr, const_oop(), tary, lazy_klass, xk, off ); + return make( ptr, const_oop(), tary, lazy_klass, xk, off, iid ); case Constant: { ciObject* o = const_oop(); if( _ptr == Constant ) { @@ -3176,7 +3176,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { o = tap->const_oop(); } xk = true; - return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off ); + return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, iid ); } case NotNull: case BotPTR: @@ -3263,14 +3263,21 @@ void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const { break; } - st->print("*"); + if( _offset != 0 ) { + int header_size = objArrayOopDesc::header_size() * wordSize; + if( _offset == OffsetTop ) st->print("+undefined"); + else if( _offset == OffsetBot ) st->print("+any"); + else if( _offset < header_size ) st->print("+%d", _offset); + else { + BasicType basic_elem_type = elem()->basic_type(); + int array_base = arrayOopDesc::base_offset_in_bytes(basic_elem_type); + int elem_size = type2aelembytes(basic_elem_type); + st->print("[%d]", (_offset - array_base)/elem_size); + } + } + st->print(" *"); if (_instance_id != UNKNOWN_INSTANCE) st->print(",iid=%d",_instance_id); - if( !_offset ) return; - if( _offset == OffsetTop ) st->print("+undefined"); - else if( _offset == OffsetBot ) st->print("+any"); - else if( _offset < 12 ) st->print("+%d",_offset); - else st->print("[%d]", (_offset-12)/4 ); } #endif diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 4a697311f61..c68205f8880 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -686,6 +686,7 @@ public: bool klass_is_exact() const { return _klass_is_exact; } bool is_instance() const { return _instance_id != UNKNOWN_INSTANCE; } uint instance_id() const { return _instance_id; } + bool is_instance_field() const { return _instance_id != UNKNOWN_INSTANCE && _offset >= 0; } virtual intptr_t get_con() const; From 07a13673461df1e6d285fb087339bc16ee182f1b Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 14 Mar 2008 17:23:25 +0300 Subject: [PATCH 159/274] 6522731: Location of the frame changes,when the frame is resized & non-resized XMoveWindow() should use shell's location Reviewed-by: son --- jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java index 07b7e1cde0f..e0b46de2291 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java @@ -809,7 +809,7 @@ class XDecoratedPeer extends XWindowPeer { fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE); } winAttr.functions = fs; - XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false); + XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false); } } From 387f42921bf712a1a93d0be96eae7768ebdca7b4 Mon Sep 17 00:00:00 2001 From: Steve Bohne Date: Fri, 14 Mar 2008 10:43:02 -0400 Subject: [PATCH 160/274] 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file Os::attempt_reserve_memory_at() now passes an address hint to mmap Reviewed-by: kamg, dice --- hotspot/src/os/solaris/vm/os_solaris.cpp | 49 ++++++++++++++++++------ hotspot/src/os/solaris/vm/os_solaris.hpp | 1 + 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index e1fb6ff6204..8d0861c7091 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -2785,16 +2785,15 @@ char* os::Solaris::mmap_chunk(char *addr, size_t size, int flags, int prot) { return b; } -char* -os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) { - char* addr = NULL; - int flags; +char* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) { + char* addr = requested_addr; + int flags = MAP_PRIVATE | MAP_NORESERVE; - flags = MAP_PRIVATE | MAP_NORESERVE; - if (requested_addr != NULL) { - flags |= MAP_FIXED; - addr = requested_addr; - } else if (has_map_align && alignment_hint > (size_t) vm_page_size()) { + assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap"); + + if (fixed) { + flags |= MAP_FIXED; + } else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) { flags |= MAP_ALIGN; addr = (char*) alignment_hint; } @@ -2802,11 +2801,14 @@ os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) { // Map uncommitted pages PROT_NONE so we fail early if we touch an // uncommitted page. Otherwise, the read/write might succeed if we // have enough swap space to back the physical page. - addr = Solaris::mmap_chunk(addr, bytes, flags, PROT_NONE); + return mmap_chunk(addr, bytes, flags, PROT_NONE); +} + +char* os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) { + char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL)); guarantee(requested_addr == NULL || requested_addr == addr, "OS failed to return requested mmap address."); - return addr; } @@ -2832,6 +2834,31 @@ char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) { // in one of the methods further up the call chain. See bug 5044738. assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block"); + // Since snv_84, Solaris attempts to honor the address hint - see 5003415. + // Give it a try, if the kernel honors the hint we can return immediately. + char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false); + volatile int err = errno; + if (addr == requested_addr) { + return addr; + } else if (addr != NULL) { + unmap_memory(addr, bytes); + } + + if (PrintMiscellaneous && Verbose) { + char buf[256]; + buf[0] = '\0'; + if (addr == NULL) { + jio_snprintf(buf, sizeof(buf), ": %s", strerror(err)); + } + warning("attempt_reserve_memory_at: couldn't reserve %d bytes at " + PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT + "%s", bytes, requested_addr, addr, buf); + } + + // Address hint method didn't work. Fall back to the old method. + // In theory, once SNV becomes our oldest supported platform, this + // code will no longer be needed. + // // Repeatedly allocate blocks until the block is allocated at the // right spot. Give up after max_tries. int i; diff --git a/hotspot/src/os/solaris/vm/os_solaris.hpp b/hotspot/src/os/solaris/vm/os_solaris.hpp index 201730ee1a7..b66bcb2bf6f 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.hpp +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp @@ -156,6 +156,7 @@ class Solaris { static int get_dev_zero_fd() { return _dev_zero_fd; } static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; } static char* mmap_chunk(char *addr, size_t size, int flags, int prot); + static char* anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed); static bool mpss_sanity_check(bool warn, size_t * page_size); static bool ism_sanity_check (bool warn, size_t * page_size); From f97f9eb9a58a7111d14e712f3a688634060d1dae Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 14 Mar 2008 18:27:34 +0300 Subject: [PATCH 161/274] 6612497: api/java_awt/Container/index.html#isAncestorOf Container2019 hangs since JDK 7 b15 Partial rollback changes for 6567564 in the Component.getGC method Reviewed-by: art, son --- jdk/src/share/classes/java/awt/Component.java | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 38d50d5d09f..5435d9b2599 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -935,24 +935,26 @@ public abstract class Component implements ImageObserver, MenuContainer, */ public GraphicsConfiguration getGraphicsConfiguration() { synchronized(getTreeLock()) { - GraphicsConfiguration gc = graphicsConfig; - Component parent = getParent(); - while ((gc == null) && (parent != null)) { - gc = parent.getGraphicsConfiguration(); - parent = parent.getParent(); + if (graphicsConfig != null) { + return graphicsConfig; + } else if (getParent() != null) { + return getParent().getGraphicsConfiguration(); + } else { + return null; } - return gc; } } final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() { - GraphicsConfiguration gc = this.graphicsConfig; - Component par = this.parent; - while ((gc == null) && (par != null)) { - gc = par.getGraphicsConfiguration_NoClientCode(); - par = par.parent; + GraphicsConfiguration graphicsConfig = this.graphicsConfig; + Container parent = this.parent; + if (graphicsConfig != null) { + return graphicsConfig; + } else if (parent != null) { + return parent.getGraphicsConfiguration_NoClientCode(); + } else { + return null; } - return gc; } /** From 4033c902511fe8b35b556b4b1e9ee9ed97be1e1e Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 14 Mar 2008 18:50:02 +0300 Subject: [PATCH 162/274] 6603010: Out-of-process Java Plug-In non-functional or barely functional on X11 platforms AWT XEmbed shouldn't use _SUN_XEMBED_START message Reviewed-by: art, son --- .../solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java | 6 ------ .../classes/sun/awt/X11/XEmbedClientHelper.java | 11 ----------- jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java | 3 --- .../classes/sun/awt/X11/XEmbedServerTester.java | 7 ------- 4 files changed, 27 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java index 14cedf1fffa..10b71a453b4 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java @@ -647,12 +647,6 @@ public class XEmbedCanvasPeer extends XCanvasPeer implements WindowFocusListener } if (isXEmbedActive()) { switch ((int)msg.get_data(1)) { - case _SUN_XEMBED_START: - // Child has finished initialization and waits for notify - xembed.processXEmbedInfo(); - - notifyChildEmbedded(); - break; case XEMBED_REQUEST_FOCUS: requestXEmbedFocus(); break; diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java index 582c2f05578..c56883e46af 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java @@ -74,7 +74,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher XToolkit.awtUnlock(); } } - notifyReady(); } void handleClientMessage(XEvent xev) { @@ -84,7 +83,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1))); switch ((int)msg.get_data(1)) { case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start - // NOTE: May be called two times because we send _SUN_XEMBED_START active = true; server = getEmbedder(embedded, msg); // Check if window is reparented. If not - it was created with @@ -223,13 +221,4 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher long getX11Mods(AWTKeyStroke stroke) { return XWindow.getXModifiers(stroke); } - - void notifyReady() { - long wnd = server; - if (wnd == 0) { - // Server is still 0, get the parent - wnd = embedded.getParentWindowHandle(); - } - sendMessage(wnd, _SUN_XEMBED_START); - } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java index ae2fc8507a6..aab78552007 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java @@ -58,7 +58,6 @@ public class XEmbedHelper { final static int XEMBED_REGISTER_ACCELERATOR = 12; final static int XEMBED_UNREGISTER_ACCELERATOR= 13; final static int XEMBED_ACTIVATE_ACCELERATOR = 14; - final static int _SUN_XEMBED_START = 1119; final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108; final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109; @@ -151,8 +150,6 @@ public class XEmbedHelper { return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY"; case NON_STANDARD_XEMBED_GTK_GRAB_KEY: return "NON_STANDARD_XEMBED_GTK_GRAB_KEY"; - case _SUN_XEMBED_START: - return "XEMBED_START"; case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK: return "KeyPress"; case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK: diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java index 5fab6876a5e..a5ce2df7404 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java @@ -177,13 +177,6 @@ public class XEmbedServerTester implements XEventDispatcher { embedCompletely(); } - public void test3_2() { - embedCompletely(); - int res = getEventPos(); - sendMessage(XEmbedHelper._SUN_XEMBED_START); - waitEmbeddedNotify(res); - } - public void test3_3() { reparent = true; embedCompletely(); From ad051bbc3af2d732e786fd72f0bda248aac0828e Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 14 Mar 2008 20:40:09 +0300 Subject: [PATCH 163/274] 6524352: support for high-resolution mouse wheel Added support for high-resolution mouse wheel Reviewed-by: dav, son --- jdk/src/share/classes/java/awt/Component.java | 3 +- jdk/src/share/classes/java/awt/Container.java | 3 +- .../java/awt/event/MouseWheelEvent.java | 108 ++++- .../native/sun/windows/awt_Component.cpp | 25 +- .../native/sun/windows/awt_Component.h | 6 +- .../MouseEvent/SmoothWheel/SmoothWheel.java | 432 ++++++++++++++++++ 6 files changed, 560 insertions(+), 17 deletions(-) create mode 100644 jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 5435d9b2599..718cafe0614 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -4604,7 +4604,8 @@ public abstract class Component implements ImageObserver, MenuContainer, e.isPopupTrigger(), e.getScrollType(), e.getScrollAmount(), - e.getWheelRotation()); + e.getWheelRotation(), + e.getPreciseWheelRotation()); ((AWTEvent)e).copyPrivateDataInto(newMWE); // When dispatching a wheel event to // ancestor, there is no need trying to find descendant diff --git a/jdk/src/share/classes/java/awt/Container.java b/jdk/src/share/classes/java/awt/Container.java index 46164c410c6..4a347f3d5e9 100644 --- a/jdk/src/share/classes/java/awt/Container.java +++ b/jdk/src/share/classes/java/awt/Container.java @@ -4431,7 +4431,8 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener { e.isPopupTrigger(), ((MouseWheelEvent)e).getScrollType(), ((MouseWheelEvent)e).getScrollAmount(), - ((MouseWheelEvent)e).getWheelRotation()); + ((MouseWheelEvent)e).getWheelRotation(), + ((MouseWheelEvent)e).getPreciseWheelRotation()); } else { retargeted = new MouseEvent(target, diff --git a/jdk/src/share/classes/java/awt/event/MouseWheelEvent.java b/jdk/src/share/classes/java/awt/event/MouseWheelEvent.java index 40af56c4439..a1c5b2ebb91 100644 --- a/jdk/src/share/classes/java/awt/event/MouseWheelEvent.java +++ b/jdk/src/share/classes/java/awt/event/MouseWheelEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2007 Sun Microsystems, Inc. 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 @@ -74,6 +74,19 @@ import java.awt.Component; * methods for conforming to the underlying platform settings. These * platform settings can be changed at any time by the user. MouseWheelEvents * reflect the most recent settings. + *

    + * The MouseWheelEvent class includes methods for + * getting the number of "clicks" by which the mouse wheel is rotated. + * The {@link #getWheelRotation} method returns the integer number + * of "clicks" corresponding to the number of notches by which the wheel was + * rotated. In addition to this method, the MouseWheelEvent + * class provides the {@link #getPreciseWheelRotation} method which returns + * a double number of "clicks" in case a partial rotation occurred. + * The {@link #getPreciseWheelRotation} method is useful if a mouse supports + * a high-resolution wheel, such as a freely rotating wheel with no + * notches. Applications can benefit by using this method to process + * mouse wheel events more precisely, and thus, making visual perception + * smoother. * * @author Brent Christian * @see MouseWheelListener @@ -131,6 +144,13 @@ public class MouseWheelEvent extends MouseEvent { */ int wheelRotation; + /** + * Indicates how far the mouse wheel was rotated. + * + * @see #getPreciseWheelRotation + */ + double preciseWheelRotation; + /* * serialVersionUID */ @@ -165,8 +185,8 @@ public class MouseWheelEvent extends MouseEvent { * WHEEL_BLOCK_SCROLL * @param scrollAmount for scrollType WHEEL_UNIT_SCROLL, * the number of units to be scrolled - * @param wheelRotation the amount that the mouse wheel was rotated (the - * number of "clicks") + * @param wheelRotation the integer number of "clicks" by which the mouse + * wheel was rotated * * @throws IllegalArgumentException if source is null * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean) @@ -211,8 +231,8 @@ public class MouseWheelEvent extends MouseEvent { * WHEEL_BLOCK_SCROLL * @param scrollAmount for scrollType WHEEL_UNIT_SCROLL, * the number of units to be scrolled - * @param wheelRotation the amount that the mouse wheel was rotated (the - * number of "clicks") + * @param wheelRotation the integer number of "clicks" by which the mouse + * wheel was rotated * * @throws IllegalArgumentException if source is null * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean) @@ -223,12 +243,68 @@ public class MouseWheelEvent extends MouseEvent { int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger, int scrollType, int scrollAmount, int wheelRotation) { + this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger, + scrollType, scrollAmount, wheelRotation, wheelRotation); + + } + + + /** + * Constructs a MouseWheelEvent object with the specified + * source component, type, modifiers, coordinates, absolute coordinates, + * scroll type, scroll amount, and wheel rotation. + *

    Note that passing in an invalid id parameter results + * in unspecified behavior. This method throws an + * IllegalArgumentException if source equals + * null. + *

    Even if inconsistent values for relative and absolute coordinates + * are passed to the constructor, a MouseWheelEvent instance + * is still created and no exception is thrown. + * + * @param source the Component that originated the event + * @param id the integer value that identifies the event + * @param when a long value that gives the time when the event occurred + * @param modifiers the modifier keys down during event + * (shift, ctrl, alt, meta) + * @param x the horizontal x coordinate for the + * mouse location + * @param y the vertical y coordinate for the + * mouse location + * @param xAbs the absolute horizontal x coordinate for + * the mouse location + * @param yAbs the absolute vertical y coordinate for + * the mouse location + * @param clickCount the number of mouse clicks associated with the event + * @param popupTrigger a boolean value, true if this event is a trigger + * for a popup-menu + * @param scrollType the type of scrolling which should take place in + * response to this event; valid values are + * WHEEL_UNIT_SCROLL and + * WHEEL_BLOCK_SCROLL + * @param scrollAmount for scrollType WHEEL_UNIT_SCROLL, + * the number of units to be scrolled + * @param wheelRotation the integer number of "clicks" by which the mouse wheel + * was rotated + * @param preciseWheelRotation the double number of "clicks" by which the mouse wheel + * was rotated + * + * @throws IllegalArgumentException if source is null + * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean) + * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int) + * @since 1.7 + */ + public MouseWheelEvent (Component source, int id, long when, int modifiers, + int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger, + int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) { + super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger, MouseEvent.NOBUTTON); this.scrollType = scrollType; this.scrollAmount = scrollAmount; this.wheelRotation = wheelRotation; + this.preciseWheelRotation = preciseWheelRotation; + } /** @@ -267,16 +343,34 @@ public class MouseWheelEvent extends MouseEvent { } /** - * Returns the number of "clicks" the mouse wheel was rotated. + * Returns the number of "clicks" the mouse wheel was rotated, as an integer. + * A partial rotation may occur if the mouse supports a high-resolution wheel. + * In this case, the method returns zero until a full "click" has been accumulated. * * @return negative values if the mouse wheel was rotated up/away from * the user, and positive values if the mouse wheel was rotated down/ * towards the user + * @see #getPreciseWheelRotation */ public int getWheelRotation() { return wheelRotation; } + /** + * Returns the number of "clicks" the mouse wheel was rotated, as a double. + * A partial rotation may occur if the mouse supports a high-resolution wheel. + * In this case, the return value will include a fractional "click". + * + * @return negative values if the mouse wheel was rotated up or away from + * the user, and positive values if the mouse wheel was rotated down or + * towards the user + * @see #getWheelRotation + * @since 1.7 + */ + public double getPreciseWheelRotation() { + return preciseWheelRotation; + } + /** * This is a convenience method to aid in the implementation of * the common-case MouseWheelListener - to scroll a ScrollPane or @@ -348,6 +442,6 @@ public class MouseWheelEvent extends MouseEvent { } return super.paramString()+",scrollType="+scrollTypeStr+ ",scrollAmount="+getScrollAmount()+",wheelRotation="+ - getWheelRotation(); + getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation(); } } diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index e1b3a7d1dcd..9a9082b504b 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -226,6 +226,8 @@ BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE; CriticalSection windowMoveLock; BOOL windowMoveLockHeld = FALSE; +int AwtComponent::sm_wheelRotationAmount = 0; + /************************************************************************ * AwtComponent methods */ @@ -2074,6 +2076,8 @@ MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus) sm_realFocusOpposite = NULL; } + sm_wheelRotationAmount = 0; + SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus); return mrDoDefault; @@ -2105,6 +2109,7 @@ MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus) } sm_focusOwner = NULL; + sm_wheelRotationAmount = 0; SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus); return mrDoDefault; @@ -2622,9 +2627,13 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, BOOL result; UINT platformLines; + sm_wheelRotationAmount += wheelRotation; + // AWT interprets wheel rotation differently than win32, so we need to // decode wheel amount. - jint newWheelRotation = wheelRotation / (-1 * WHEEL_DELTA); + jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA); + jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA); + MSG msg; if (IS_WIN95 && !IS_WIN98) { @@ -2657,7 +2666,9 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y, SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(), eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType, - scrollLines, newWheelRotation, &msg); + scrollLines, roundedWheelRotation, preciseWheelRotation, &msg); + + sm_wheelRotationAmount %= WHEEL_DELTA; return mrConsume; } @@ -4989,8 +5000,8 @@ void AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, jint modifiers, jint clickCount, jboolean popupTrigger, jint scrollType, - jint scrollAmount, jint wheelRotation, - MSG *pMsg) + jint scrollAmount, jint roundedWheelRotation, + jdouble preciseWheelRotation, MSG *pMsg) { /* Code based not so loosely on AwtComponent::SendMouseEvent */ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); @@ -5018,7 +5029,7 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, if (mouseWheelEventConst == NULL) { mouseWheelEventConst = env->GetMethodID(mouseWheelEventCls, "", - "(Ljava/awt/Component;IJIIIIZIII)V"); + "(Ljava/awt/Component;IJIIIIIIZIIID)V"); DASSERT(mouseWheelEventConst); } if (env->EnsureLocalCapacity(2) < 0) { @@ -5026,14 +5037,16 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y, } jobject target = GetTarget(env); DTRACE_PRINTLN("creating MWE in JNI"); + jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls, mouseWheelEventConst, target, id, when, modifiers, x+insets.left, y+insets.top, + 0, 0, clickCount, popupTrigger, scrollType, scrollAmount, - wheelRotation); + roundedWheelRotation, preciseWheelRotation); if (safe_ExceptionOccurred(env)) { env->ExceptionDescribe(); env->ExceptionClear(); diff --git a/jdk/src/windows/native/sun/windows/awt_Component.h b/jdk/src/windows/native/sun/windows/awt_Component.h index cecab398305..ecc7ef5ea33 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.h +++ b/jdk/src/windows/native/sun/windows/awt_Component.h @@ -392,7 +392,7 @@ public: jint modifiers, jint clickCount, jboolean popupTrigger, jint scrollType, jint scrollAmount, jint wheelRotation, - MSG *msg = NULL); + jdouble preciseWheelRotation, MSG *msg = NULL); /* * Allocate and initialize a new java.awt.event.FocusEvent, and @@ -785,7 +785,9 @@ private: int windowMoveLockPosCX; int windowMoveLockPosCY; -private: + // 6524352: support finer-resolution + static int sm_wheelRotationAmount; + /* * The association list of children's IDs and corresponding components. * Some components like Choice or List are required their sizes while diff --git a/jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java b/jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java new file mode 100644 index 00000000000..00e07c84d3c --- /dev/null +++ b/jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java @@ -0,0 +1,432 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 %W% %E% %I%, %G% + @bug 6524352 + @summary support for high-resolution mouse wheel + @author dmitry cherepanov: area=awt.event + @run main/manual SmoothWheel +*/ + +/** + * SmoothWheel.java + * + * summary: + */ + +import java.awt.*; +import java.awt.event.*; + +public class SmoothWheel +{ + + //*** test-writer defined static variables go here *** + + + private static void init() + { + String[] instructions = + { + "1. the test is for high-resolution mouse wheel only, ", + " refer to the cr# 6524352 for more info about such devices, ", + "2. you'll see a frame, the frame contains a checkbox, ", + "3. initially, the state of the checkbox is off, ", + " use mouse wheel over the frame, ", + " and the frame will change its size gradually, ", + "4. turn on the checkbox, ", + " use mouse wheel again over the frame, ", + " now the frame will change its size smoothly, ", + "5. if the frame has always the same size or", + " if the frame changes its size equally in 3,4 cases, ", + " then the test failed. Otherwise, it passed." + }; + + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + final Frame frame = new Frame(); + final Checkbox checkbox = new Checkbox("smooth wheel?"); + checkbox.setState(false); + + frame.setLayout (new FlowLayout()); + frame.add(checkbox); + + frame.addMouseWheelListener(new MouseWheelListener() { + public void mouseWheelMoved(MouseWheelEvent e) { + Sysout.println(e.toString()); + double wheelRotation = 0; + if (checkbox.getState()) { + wheelRotation = e.getPreciseWheelRotation(); + } else { + wheelRotation = e.getWheelRotation(); + } + Dimension size = frame.getSize(); + size.width += 10 * wheelRotation; + size.height += 10 * wheelRotation; + frame.setSize(size); + } + }); + + frame.setBounds(200, 200, 200, 200); + frame.setVisible(true); + + }//End init() + + + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + if (mainThread != null){ + mainThread.interrupt(); + } + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + private static boolean numbering = false; + private static int messageNumber = 0; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + /* Enables message counting for the tester. */ + public static void enableNumbering(boolean enable){ + numbering = enable; + } + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + if (numbering) { + messageIn = "" + messageNumber + " " + messageIn; + messageNumber++; + } + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + SmoothWheel.pass(); + } + else + { + SmoothWheel.fail(); + } + } + +}// TestDialog class From 9e5bc6d8bfbc8c61cbf80008dc7d9674233c7220 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 14 Mar 2008 22:00:33 +0300 Subject: [PATCH 164/274] 6578583: Regression: Modality is broken in windows vista home premium from jdk1.7 b02 onwards WS_DISABLED style should be used to fix some modality bugs Reviewed-by: art, son --- .../native/sun/windows/awt_Component.cpp | 6 + .../windows/native/sun/windows/awt_Dialog.cpp | 7 +- .../windows/native/sun/windows/awt_Window.cpp | 18 +- .../windows/native/sun/windows/awt_Window.h | 1 - .../CloseBlocker/CloseBlocker.java | 466 ++++++++++++++++++ .../OverBlocker/OverBlocker.java | 456 +++++++++++++++++ .../Modal/WsDisabledStyle/Winkey/Winkey.java | 403 +++++++++++++++ 7 files changed, 1344 insertions(+), 13 deletions(-) create mode 100644 jdk/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java create mode 100644 jdk/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java create mode 100644 jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 9a9082b504b..f5823786110 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -5425,7 +5425,13 @@ void AwtComponent::UnlinkObjects() void AwtComponent::Enable(BOOL bEnable) { sm_suppressFocusAndActivation = TRUE; + + if (bEnable && IsTopLevel()) { + // we should not enable blocked toplevels + bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd())); + } ::EnableWindow(GetHWnd(), bEnable); + sm_suppressFocusAndActivation = FALSE; CriticalSection::Lock l(GetLock()); VerifyState(); diff --git a/jdk/src/windows/native/sun/windows/awt_Dialog.cpp b/jdk/src/windows/native/sun/windows/awt_Dialog.cpp index 072ed2ba65b..0c98fc0d9fe 100644 --- a/jdk/src/windows/native/sun/windows/awt_Dialog.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Dialog.cpp @@ -273,6 +273,10 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, { HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); HWND topMostBlocker = blocker; + HWND prevForegroundWindow = ::GetForegroundWindow(); + if (::IsWindow(blocker)) { + ::BringWindowToTop(hWnd); + } while (::IsWindow(blocker)) { topMostBlocker = blocker; ::BringWindowToTop(blocker); @@ -282,7 +286,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, // no beep/flash if the mouse was clicked in the taskbar menu // or the dialog is currently inactive if ((::WindowFromPoint(mhs->pt) == hWnd) && - (::GetForegroundWindow() == topMostBlocker)) + (prevForegroundWindow == topMostBlocker)) { ::MessageBeep(MB_OK); // some heuristics: 3 times x 64 milliseconds @@ -292,6 +296,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, ::BringWindowToTop(topMostBlocker); ::SetForegroundWindow(topMostBlocker); } + return 1; } } } diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index adc3ee6af2a..866dffaf1c7 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -180,7 +180,6 @@ void AwtWindow::Dispose() } ::RemoveProp(GetHWnd(), ModalBlockerProp); - ::RemoveProp(GetHWnd(), ModalSaveWSEXProp); if (m_grabbedWindow == this) { Ungrab(); @@ -1455,20 +1454,17 @@ void AwtWindow::SetModalBlocker(HWND window, HWND blocker) { if (!::IsWindow(window)) { return; } - DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE); + if (::IsWindow(blocker)) { - // save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles - DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW); - ::SetProp(window, ModalSaveWSEXProp, reinterpret_cast(saveStyle)); - ::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW); ::SetProp(window, ModalBlockerProp, reinterpret_cast(blocker)); + ::EnableWindow(window, FALSE); } else { - // restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles - DWORD saveStyle = reinterpret_cast(::GetProp(window, ModalSaveWSEXProp)); - ::SetWindowLong(window, GWL_EXSTYLE, - (exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle); - ::RemoveProp(window, ModalSaveWSEXProp); ::RemoveProp(window, ModalBlockerProp); + AwtComponent *comp = AwtComponent::GetComponent(window); + // we don't expect to be called with non-java HWNDs + DASSERT(comp && comp->IsTopLevel()); + // we should not unblock disabled toplevels + ::EnableWindow(window, comp->isEnabled()); } } diff --git a/jdk/src/windows/native/sun/windows/awt_Window.h b/jdk/src/windows/native/sun/windows/awt_Window.h index 1edb9b04dd7..ca3b68c3220 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.h +++ b/jdk/src/windows/native/sun/windows/awt_Window.h @@ -33,7 +33,6 @@ // property name tagging windows disabled by modality static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp"); -static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp"); static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp"); #ifndef WH_MOUSE_LL diff --git a/jdk/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java b/jdk/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java new file mode 100644 index 00000000000..ad48949b3ac --- /dev/null +++ b/jdk/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java @@ -0,0 +1,466 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 %I% %E% + @bug 4080029 + @summary Modal Dialog block input to all frame windows not just its parent. + @author dmitry.cherepanov: area=awt.modal + @run main/manual CloseBlocker +*/ + +/** + * ManualMainTest.java + * + * summary: The test opens and closes blocker dialog, the test verifies + * that active window is correct when the dialog is closed. + */ + +import java.awt.*; +import java.awt.event.*; + +public class CloseBlocker +{ + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + " the test will be run 6 times, to start next test just close all ", + " windows of previous; the instructions are the same for all tests: ", + " 1) there are two frames (one the frames has 'show modal' button), ", + " 2) press the button to show a dialog, ", + " 3) close the dialog (an alternative scenario - activate another", + " native window before closing the dialog), ", + " 4) the frame with button should become next active window, ", + " if it's true, then the test passed, otherwise, it failed. ", + " Press 'pass' button only after all of the 6 tests are completed, ", + " the number of the currently executed test is displayed on the ", + " output window. " + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + test(true, true, false); + test(true, true, true); + test(false, true, false); // 3rd parameter has no affect for ownerless + + test(true, false, false); + test(true, false, true); + test(false, false, false); // 3rd parameter has no affect for ownerless + + }//End init() + + private static final Object obj = new Object(); + private static int counter = 0; + + /* + * The ownerless parameter indicates whether the blocker dialog + * has owner. The usual parameter indicates whether the blocker + * dialog is a Java dialog (non-native dialog like file dialog). + */ + private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) { + + Sysout.print(" * test #" + (++counter) + " is running ... "); + + final Frame active = new Frame(); + final Frame nonactive = new Frame(); + Button button = new Button("show modal"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + Dialog dialog = null; + Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive); + if (usual) { + dialog = new Dialog(parent, "Sample", true); + } else { + dialog = new FileDialog(parent, "Sample", FileDialog.LOAD); + } + dialog.addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + e.getWindow().dispose(); + } + }); + dialog.setBounds(200, 200, 200, 200); + dialog.setVisible(true); + } + }); + + active.add(button); + active.setBounds(200, 400, 200, 200); + WindowAdapter adapter = new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + active.dispose(); + nonactive.dispose(); + synchronized(obj) { + obj.notify(); + } + } + }; + active.addWindowListener(adapter); + active.setVisible(true); + + nonactive.setBounds(400, 400, 200, 200); + nonactive.addWindowListener(adapter); + nonactive.setVisible(true); + + synchronized(obj) { + try{ + obj.wait(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + + Sysout.println(" completed. "); + + } + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn, true ); + } + + public static void print( String messageIn ) + { + dialog.displayMessage( messageIn, false ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn, boolean nextLine ) + { + messageText.append( messageIn + (nextLine? "\n" : "") ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + CloseBlocker.pass(); + } + else + { + CloseBlocker.fail(); + } + } + +}// TestDialog class diff --git a/jdk/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java b/jdk/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java new file mode 100644 index 00000000000..15d963baa08 --- /dev/null +++ b/jdk/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java @@ -0,0 +1,456 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 %I% %E% + @bug 4080029 + @summary Modal Dialog block input to all frame windows not just its parent. + @author dmitry.cherepanov: area=awt.modal + @run main/manual OverBlocker +*/ + +/** + * OverBlocker.java + * + * summary: The test verifies that if user tries to activate the blocked dialog + * then the blocker dialog appears over the other windows + */ + +import java.awt.*; +import java.awt.event.*; + +public class OverBlocker +{ + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + " the test will be run 4 times, to start next test just close all ", + " windows of previous; the instructions are the same for all tests: ", + " 1) there is a frame with 'show modal' button, ", + " 2) press the button to show a dialog, ", + " 3) activate any non-Java application, move the app over the dialog, ", + " 4) click on the frame by mouse, ", + " 5) make sure that the dialog comes up from the application and ", + " now the dialog overlaps the app as well as the frame, ", + " if it's true, then the test passed, otherwise, it failed. ", + " Press 'pass' button only after all of the 4 tests are completed, ", + " the number of the currently executed test is displayed on the ", + " output window. " + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + test(false, true); + test(true, true); + test(true, false); + test(false, false); + + }//End init() + + private static final Object obj = new Object(); + private static int counter = 0; + + /* + * The ownerless parameter indicates whether the blocker dialog + * has owner. The usual parameter indicates whether the blocker + * dialog is a Java dialog (non-native dialog like file dialog). + */ + private static void test(final boolean ownerless, final boolean usual) { + + Sysout.print(" * test #" + (++counter) + " is running ... "); + + final Frame frame = new Frame(); + Button button = new Button("show modal"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + Dialog dialog = null; + Frame parent = ownerless ? null : frame; + if (usual) { + dialog = new Dialog(parent, "Sample", true); + } else { + dialog = new FileDialog(parent, "Sample", FileDialog.LOAD); + } + dialog.addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + e.getWindow().dispose(); + } + }); + dialog.setBounds(200, 200, 200, 200); + dialog.setVisible(true); + } + }); + frame.add(button); + frame.setBounds(400, 400, 200, 200); + frame.addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent e){ + e.getWindow().dispose(); + synchronized(obj) { + obj.notify(); + } + } + }); + frame.setVisible(true); + + synchronized(obj) { + try{ + obj.wait(); + } catch(Exception e) { + throw new RuntimeException(e); + } + } + + Sysout.println(" completed. "); + + } + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn, true ); + } + + public static void print( String messageIn ) + { + dialog.displayMessage( messageIn, false ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn, boolean nextLine ) + { + messageText.append( messageIn + (nextLine? "\n" : "") ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + OverBlocker.pass(); + } + else + { + OverBlocker.fail(); + } + } + +}// TestDialog class diff --git a/jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java b/jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java new file mode 100644 index 00000000000..59297463a2e --- /dev/null +++ b/jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java @@ -0,0 +1,403 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 %I% %E% + @bug 6572263 6571808 + @summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList + @author dmitry.cherepanov: area=awt.modal + @run main/manual Winkey +*/ + +/** + * Winkey.java + * + * summary: the test verifies that pressing combination of Windows key + * and M key to minimize all windows doesn't break AWT modality + */ + +import java.awt.*; +import java.awt.event.*; + +public class Winkey +{ + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + " 1. there is a frame with a 'show modal' button, ", + " 2. press the button to show a modal dialog, ", + " 3. the modal dialog will be shown over the frame, ", + " 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ", + " ", + " 5.1. press combination Windows Key and M key to minimize all windows, ", + " 5.2. press combination Windows Key and D key to show desktop, ", + " 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ", + " 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)", + " ", + " 6. make sure that the dialog and the frame are visible, ", + " the bounds of the windows should be the same as before, ", + " if it's true, then the test passed; otherwise, it failed. " + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + final Frame frame = new Frame(); + Button button = new Button("show modal"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD); + dialog.setVisible(true); + } + }); + frame.add(button); + frame.setBounds(400, 400, 200, 200); + frame.setVisible(true); + + }//End init() + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test-defined + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test passed nor test failed has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + //pass was called from a different thread, so set the flag and interrupt + // the main thead. + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ManualMainTest + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// make listeners in a class defined here, and instantiate them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ManualMainTest.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ManualMainTest.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP = new Panel(); + Button passB = new Button( "pass" ); + Button failB = new Button( "fail" ); + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + passB = new Button( "pass" ); + passB.setActionCommand( "pass" ); + passB.addActionListener( this ); + buttonP.add( "East", passB ); + + failB = new Button( "fail" ); + failB.setActionCommand( "fail" ); + failB.addActionListener( this ); + buttonP.add( "West", failB ); + + add( "South", buttonP ); + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + + //catch presses of the passed and failed buttons. + //simply call the standard pass() or fail() static methods of + //ManualMainTest + public void actionPerformed( ActionEvent e ) + { + if( e.getActionCommand() == "pass" ) + { + Winkey.pass(); + } + else + { + Winkey.fail(); + } + } + +}// TestDialog class From 84360263526613225839a9755701e8ace96e789d Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Fri, 14 Mar 2008 14:21:03 -0700 Subject: [PATCH 165/274] 6514993: (prefs)prefs should use java.util.ServiceLoader to lookup service providers Reviewed-by: iris --- .../classes/java/util/prefs/Preferences.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/util/prefs/Preferences.java b/jdk/src/share/classes/java/util/prefs/Preferences.java index 1c25cfdbc13..1aad5d9f0ef 100644 --- a/jdk/src/share/classes/java/util/prefs/Preferences.java +++ b/jdk/src/share/classes/java/util/prefs/Preferences.java @@ -32,9 +32,8 @@ import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; import java.util.Iterator; -import sun.misc.Service; -import sun.misc.ServiceConfigurationError; - +import java.util.ServiceLoader; +import java.util.ServiceConfigurationError; // These imports needed only as a workaround for a JavaDoc bug import java.lang.RuntimePermission; @@ -274,12 +273,14 @@ public abstract class Preferences { private static PreferencesFactory factory1() { // 2. Try service provider interface - Iterator i = Service.providers(PreferencesFactory.class, - ClassLoader.getSystemClassLoader()); + Iterator itr = ServiceLoader + .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader()) + .iterator(); + // choose first provider instance - while (i.hasNext()) { + while (itr.hasNext()) { try { - return (PreferencesFactory) i.next(); + return itr.next(); } catch (ServiceConfigurationError sce) { if (sce.getCause() instanceof SecurityException) { // Ignore the security exception, try the next provider From fc0117cb9af9db1539415aa8a2f45d0360a755f4 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 14 Mar 2008 15:26:33 -0700 Subject: [PATCH 166/274] 6674588: (Escape Analysis) Improve Escape Analysis code Current EA code has several problems which have to be fixed. Reviewed-by: jrose, sgoldman --- hotspot/src/share/vm/includeDB_compiler2 | 4 +- hotspot/src/share/vm/opto/c2_globals.hpp | 6 + hotspot/src/share/vm/opto/callnode.cpp | 81 + hotspot/src/share/vm/opto/callnode.hpp | 20 +- hotspot/src/share/vm/opto/compile.cpp | 10 +- hotspot/src/share/vm/opto/compile.hpp | 1 - hotspot/src/share/vm/opto/escape.cpp | 1573 ++++++++++++++------ hotspot/src/share/vm/opto/escape.hpp | 158 +- hotspot/src/share/vm/opto/node.cpp | 5 +- hotspot/src/share/vm/opto/node.hpp | 1 - hotspot/src/share/vm/opto/phaseX.cpp | 13 +- hotspot/src/share/vm/runtime/arguments.cpp | 3 + 12 files changed, 1352 insertions(+), 523 deletions(-) diff --git a/hotspot/src/share/vm/includeDB_compiler2 b/hotspot/src/share/vm/includeDB_compiler2 index 514f6883b27..43233ad41dd 100644 --- a/hotspot/src/share/vm/includeDB_compiler2 +++ b/hotspot/src/share/vm/includeDB_compiler2 @@ -164,6 +164,7 @@ callGenerator.hpp deoptimization.hpp callGenerator.hpp type.hpp callnode.cpp callnode.hpp +callnode.cpp bcEscapeAnalyzer.hpp callnode.cpp escape.hpp callnode.cpp locknode.hpp callnode.cpp machnode.hpp @@ -176,7 +177,6 @@ callnode.cpp rootnode.hpp callnode.cpp runtime.hpp callnode.hpp connode.hpp -callnode.hpp escape.hpp callnode.hpp mulnode.hpp callnode.hpp multnode.hpp callnode.hpp opcodes.hpp @@ -347,7 +347,6 @@ connode.cpp addnode.hpp connode.cpp allocation.inline.hpp connode.cpp compile.hpp connode.cpp connode.hpp -connode.cpp escape.hpp connode.cpp machnode.hpp connode.cpp matcher.hpp connode.cpp memnode.hpp @@ -844,7 +843,6 @@ phaseX.cpp block.hpp phaseX.cpp callnode.hpp phaseX.cpp cfgnode.hpp phaseX.cpp connode.hpp -phaseX.cpp escape.hpp phaseX.cpp loopnode.hpp phaseX.cpp machnode.hpp phaseX.cpp opcodes.hpp diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 4cfbcca2c98..bdf07f63f48 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -382,6 +382,12 @@ product(bool, EliminateAllocations, true, \ "Use escape analysis to eliminate allocations") \ \ + notproduct(bool, PrintEliminateAllocations, false, \ + "Print out when allocations are eliminated") \ + \ + product(intx, EliminateAllocationArraySizeLimit, 64, \ + "Array size (number of elements) limit for scalar replacement") \ + \ product(intx, MaxLabelRootDepth, 1100, \ "Maximum times call Label_Root to prevent stack overflow") \ diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index b0bcf4ee8da..60a183def71 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -624,6 +624,87 @@ uint CallNode::match_edge(uint idx) const { return 0; } +// +// Determine whether the call could modify a memory value of the +// specified address type +// +bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) { + const TypeOopPtr *adrInst_t = addr_t->isa_oopptr(); + + // if not an InstPtr or not an instance type, assume the worst + if (adrInst_t == NULL || !adrInst_t->is_instance_field()) { + return true; + } + Compile *C = phase->C; + int offset = adrInst_t->offset(); + assert(offset >= 0, "should be valid offset"); + assert(addr_t->isa_instptr() || addr_t->isa_aryptr(), "only instances or arrays are expected"); + + int base_idx = C->get_alias_index(adrInst_t); + ciMethod * meth = is_CallStaticJava() ? as_CallStaticJava()->method() : NULL; + BCEscapeAnalyzer *bcea = (meth != NULL) ? meth->get_bcea() : NULL; + + const TypeTuple * d = tf()->domain(); + for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { + const Type* t = d->field_at(i); + Node *arg = in(i); + const Type *at = phase->type(arg); + if (at == TypePtr::NULL_PTR || at == Type::TOP) + continue; // null can't affect anything + + const TypeOopPtr *at_ptr = at->isa_oopptr(); + if (!arg->is_top() && (t->isa_oopptr() != NULL || + t->isa_ptr() && at_ptr != NULL)) { + assert(at_ptr != NULL, "expecting an OopPtr"); + // If we have found an argument matching adr_base_t, check if the field + // at the specified offset is modified. Since we don't know the size, + // assume 8. + int at_idx = C->get_alias_index(at_ptr->add_offset(offset)->isa_oopptr()); + if (base_idx == at_idx && + (bcea == NULL || + bcea->is_arg_modified(i - TypeFunc::Parms, offset, 8))) { + return true; + } + } + } + return false; +} + +// Does this call have a direct reference to n other than debug information? +bool CallNode::has_non_debug_use(Node *n) { + const TypeTuple * d = tf()->domain(); + for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { + Node *arg = in(i); + if (arg == n) { + return true; + } + } + return false; +} + +// Returns the unique CheckCastPP of a call +// or 'this' if there are several CheckCastPP +// or returns NULL if there is no one. +Node *CallNode::result_cast() { + Node *cast = NULL; + + Node *p = proj_out(TypeFunc::Parms); + if (p == NULL) + return NULL; + + for (DUIterator_Fast imax, i = p->fast_outs(imax); i < imax; i++) { + Node *use = p->fast_out(i); + if (use->is_CheckCastPP()) { + if (cast != NULL) { + return this; // more than 1 CheckCastPP + } + cast = use; + } + } + return cast; +} + + //============================================================================= uint CallJavaNode::size_of() const { return sizeof(*this); } uint CallJavaNode::cmp( const Node &n ) const { diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp index 179ad06b007..ccdac0a7cc9 100644 --- a/hotspot/src/share/vm/opto/callnode.hpp +++ b/hotspot/src/share/vm/opto/callnode.hpp @@ -388,6 +388,9 @@ public: void set_next_exception(SafePointNode* n); bool has_exceptions() const { return next_exception() != NULL; } + // Does this node have a use of n other than in debug information? + virtual bool has_non_debug_use(Node *n) {return false; } + // Standard Node stuff virtual int Opcode() const; virtual bool pinned() const { return true; } @@ -457,7 +460,6 @@ public: const TypeFunc *_tf; // Function type address _entry_point; // Address of method being called float _cnt; // Estimate of number of times called - PointsToNode::EscapeState _escape_state; CallNode(const TypeFunc* tf, address addr, const TypePtr* adr_type) : SafePointNode(tf->domain()->cnt(), NULL, adr_type), @@ -467,7 +469,6 @@ public: { init_class_id(Class_Call); init_flags(Flag_is_Call); - _escape_state = PointsToNode::UnknownEscape; } const TypeFunc* tf() const { return _tf; } @@ -493,6 +494,15 @@ public: // the node the JVMState must be cloned. virtual void clone_jvms() { } // default is not to clone + // Returns true if the call may modify n + virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase); + // Does this node have a use of n other than in debug information? + virtual bool has_non_debug_use(Node *n); + // Returns the unique CheckCastPP of a call + // or result projection is there are several CheckCastPP + // or returns NULL if there is no one. + Node *result_cast(); + virtual uint match_edge(uint idx) const; #ifndef PRODUCT @@ -689,6 +699,9 @@ public: virtual uint ideal_reg() const { return Op_RegP; } virtual bool guaranteed_safepoint() { return false; } + // allocations do not modify their arguments + virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase) { return false;} + // Pattern-match a possible usage of AllocateNode. // Return null if no allocation is recognized. // The operand is the pointer produced by the (possible) allocation. @@ -801,6 +814,9 @@ public: // mark node as eliminated and update the counter if there is one void set_eliminated(); + // locking does not modify its arguments + virtual bool may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;} + #ifndef PRODUCT void create_lock_counter(JVMState* s); NamedCounter* counter() const { return _counter; } diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 475b281a89a..3fe43b53095 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -407,11 +407,6 @@ uint Compile::scratch_emit_size(const Node* n) { return buf.code_size(); } -void Compile::record_for_escape_analysis(Node* n) { - if (_congraph != NULL) - _congraph->record_for_escape_analysis(n); -} - // ============================================================================ //------------------------------Compile standard------------------------------- @@ -494,9 +489,6 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr PhaseGVN gvn(node_arena(), estimated_size); set_initial_gvn(&gvn); - if (_do_escape_analysis) - _congraph = new ConnectionGraph(this); - { // Scope for timing the parser TracePhase t3("parse", &_t_parser, true); @@ -581,6 +573,8 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr NOT_PRODUCT( verify_graph_edges(); ) // Perform escape analysis + if (_do_escape_analysis) + _congraph = new ConnectionGraph(this); if (_congraph != NULL) { NOT_PRODUCT( TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, TimeCompiler); ) _congraph->compute_escape(); diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 419bc68bebe..279b448516e 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -485,7 +485,6 @@ class Compile : public Phase { PhaseGVN* initial_gvn() { return _initial_gvn; } Unique_Node_List* for_igvn() { return _for_igvn; } inline void record_for_igvn(Node* n); // Body is after class Unique_Node_List. - void record_for_escape_analysis(Node* n); void set_initial_gvn(PhaseGVN *gvn) { _initial_gvn = gvn; } void set_for_igvn(Unique_Node_List *for_igvn) { _for_igvn = for_igvn; } diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 7e2a18d8539..e587cee177f 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -60,9 +60,9 @@ static char *node_type_names[] = { static char *esc_names[] = { "UnknownEscape", - "NoEscape ", - "ArgEscape ", - "GlobalEscape " + "NoEscape", + "ArgEscape", + "GlobalEscape" }; static char *edge_type_suffix[] = { @@ -75,7 +75,7 @@ static char *edge_type_suffix[] = { void PointsToNode::dump() const { NodeType nt = node_type(); EscapeState es = escape_state(); - tty->print("%s %s [[", node_type_names[(int) nt], esc_names[(int) es]); + tty->print("%s %s %s [[", node_type_names[(int) nt], esc_names[(int) es], _scalar_replaceable ? "" : "NSR"); for (uint i = 0; i < edge_count(); i++) { tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]); } @@ -91,9 +91,11 @@ ConnectionGraph::ConnectionGraph(Compile * C) : _processed(C->comp_arena()), _no _collecting = true; this->_compile = C; const PointsToNode &dummy = PointsToNode(); - _nodes = new(C->comp_arena()) GrowableArray(C->comp_arena(), (int) INITIAL_NODE_COUNT, 0, dummy); + int sz = C->unique(); + _nodes = new(C->comp_arena()) GrowableArray(C->comp_arena(), sz, sz, dummy); _phantom_object = C->top()->_idx; PointsToNode *phn = ptnode_adr(_phantom_object); + phn->_node = C->top(); phn->set_node_type(PointsToNode::JavaObject); phn->set_escape_state(PointsToNode::GlobalEscape); } @@ -121,8 +123,20 @@ void ConnectionGraph::add_deferred_edge(uint from_i, uint to_i) { f->add_edge(to_i, PointsToNode::DeferredEdge); } -int ConnectionGraph::type_to_offset(const Type *t) { - const TypePtr *t_ptr = t->isa_ptr(); +int ConnectionGraph::address_offset(Node* adr, PhaseTransform *phase) { + const Type *adr_type = phase->type(adr); + if (adr->is_AddP() && adr_type->isa_oopptr() == NULL && + adr->in(AddPNode::Address)->is_Proj() && + adr->in(AddPNode::Address)->in(0)->is_Allocate()) { + // We are computing a raw address for a store captured by an Initialize + // compute an appropriate address type. AddP cases #3 and #5 (see below). + int offs = (int)phase->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot); + assert(offs != Type::OffsetBot || + adr->in(AddPNode::Address)->in(0)->is_AllocateArray(), + "offset must be a constant or it is initialization of array"); + return offs; + } + const TypePtr *t_ptr = adr_type->isa_ptr(); assert(t_ptr != NULL, "must be a pointer type"); return t_ptr->offset(); } @@ -147,12 +161,28 @@ void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) { npt->set_escape_state(es); } +void ConnectionGraph::add_node(Node *n, PointsToNode::NodeType nt, + PointsToNode::EscapeState es, bool done) { + PointsToNode* ptadr = ptnode_adr(n->_idx); + ptadr->_node = n; + ptadr->set_node_type(nt); + + // inline set_escape_state(idx, es); + PointsToNode::EscapeState old_es = ptadr->escape_state(); + if (es > old_es) + ptadr->set_escape_state(es); + + if (done) + _processed.set(n->_idx); +} + PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform *phase) { uint idx = n->_idx; PointsToNode::EscapeState es; - // If we are still collecting we don't know the answer yet - if (_collecting) + // If we are still collecting or there were no non-escaping allocations + // we don't know the answer yet + if (_collecting || !_has_allocations) return PointsToNode::UnknownEscape; // if the node was created after the escape computation, return @@ -169,9 +199,9 @@ PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform // compute max escape state of anything this node could point to VectorSet ptset(Thread::current()->resource_area()); PointsTo(ptset, n, phase); - for( VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i ) { + for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) { uint pt = i.elem; - PointsToNode::EscapeState pes = _nodes->at(pt).escape_state(); + PointsToNode::EscapeState pes = _nodes->adr_at(pt)->escape_state(); if (pes > es) es = pes; } @@ -185,7 +215,7 @@ void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase VectorSet visited(Thread::current()->resource_area()); GrowableArray worklist; - n = skip_casts(n); + n = n->uncast(); PointsToNode npt = _nodes->at_grow(n->_idx); // If we have a JavaObject, return just that object @@ -193,39 +223,33 @@ void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase ptset.set(n->_idx); return; } - // we may have a Phi which has not been processed - if (npt._node == NULL) { - assert(n->is_Phi(), "unprocessed node must be a Phi"); - record_for_escape_analysis(n); - npt = _nodes->at(n->_idx); - } + assert(npt._node != NULL, "unregistered node"); + worklist.push(n->_idx); while(worklist.length() > 0) { int ni = worklist.pop(); PointsToNode pn = _nodes->at_grow(ni); - if (!visited.test(ni)) { - visited.set(ni); - + if (!visited.test_set(ni)) { // ensure that all inputs of a Phi have been processed - if (_collecting && pn._node->is_Phi()) { - PhiNode *phi = pn._node->as_Phi(); - process_phi_escape(phi, phase); - } + assert(!_collecting || !pn._node->is_Phi() || _processed.test(ni),""); int edges_processed = 0; for (uint e = 0; e < pn.edge_count(); e++) { + uint etgt = pn.edge_target(e); PointsToNode::EdgeType et = pn.edge_type(e); if (et == PointsToNode::PointsToEdge) { - ptset.set(pn.edge_target(e)); + ptset.set(etgt); edges_processed++; } else if (et == PointsToNode::DeferredEdge) { - worklist.push(pn.edge_target(e)); + worklist.push(etgt); edges_processed++; + } else { + assert(false,"neither PointsToEdge or DeferredEdge"); } } if (edges_processed == 0) { - // no deferred or pointsto edges found. Assume the value was set outside - // this method. Add the phantom object to the pointsto set. + // no deferred or pointsto edges found. Assume the value was set + // outside this method. Add the phantom object to the pointsto set. ptset.set(_phantom_object); } } @@ -239,20 +263,23 @@ void ConnectionGraph::remove_deferred(uint ni) { PointsToNode *ptn = ptnode_adr(ni); while(i < ptn->edge_count()) { + uint t = ptn->edge_target(i); + PointsToNode *ptt = ptnode_adr(t); if (ptn->edge_type(i) != PointsToNode::DeferredEdge) { i++; } else { - uint t = ptn->edge_target(i); - PointsToNode *ptt = ptnode_adr(t); ptn->remove_edge(t, PointsToNode::DeferredEdge); - if(!visited.test(t)) { - visited.set(t); + if(!visited.test_set(t)) { for (uint j = 0; j < ptt->edge_count(); j++) { uint n1 = ptt->edge_target(j); PointsToNode *pt1 = ptnode_adr(n1); switch(ptt->edge_type(j)) { case PointsToNode::PointsToEdge: - add_pointsto_edge(ni, n1); + add_pointsto_edge(ni, n1); + if(n1 == _phantom_object) { + // Special case - field set outside (globally escaping). + ptn->set_escape_state(PointsToNode::GlobalEscape); + } break; case PointsToNode::DeferredEdge: add_deferred_edge(ni, n1); @@ -291,8 +318,8 @@ void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) { } } -// Add a deferred edge from node given by "from_i" to any field of adr_i whose offset -// matches "offset" +// Add a deferred edge from node given by "from_i" to any field of adr_i +// whose offset matches "offset". void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) { PointsToNode an = _nodes->at_grow(adr_i); for (uint fe = 0; fe < an.edge_count(); fe++) { @@ -310,25 +337,108 @@ void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int o } } -// -// Search memory chain of "mem" to find a MemNode whose address -// is the specified alias index. Returns the MemNode found or the -// first non-MemNode encountered. -// -Node *ConnectionGraph::find_mem(Node *mem, int alias_idx, PhaseGVN *igvn) { - if (mem == NULL) - return mem; - while (mem->is_Mem()) { - const Type *at = igvn->type(mem->in(MemNode::Address)); - if (at != Type::TOP) { - assert (at->isa_ptr() != NULL, "pointer type required."); - int idx = _compile->get_alias_index(at->is_ptr()); - if (idx == alias_idx) - break; - } - mem = mem->in(MemNode::Memory); +// Helper functions + +static Node* get_addp_base(Node *addp) { + assert(addp->is_AddP(), "must be AddP"); + // + // AddP cases for Base and Address inputs: + // case #1. Direct object's field reference: + // Allocate + // | + // Proj #5 ( oop result ) + // | + // CheckCastPP (cast to instance type) + // | | + // AddP ( base == address ) + // + // case #2. Indirect object's field reference: + // Phi + // | + // CastPP (cast to instance type) + // | | + // AddP ( base == address ) + // + // case #3. Raw object's field reference for Initialize node: + // Allocate + // | + // Proj #5 ( oop result ) + // top | + // \ | + // AddP ( base == top ) + // + // case #4. Array's element reference: + // {CheckCastPP | CastPP} + // | | | + // | AddP ( array's element offset ) + // | | + // AddP ( array's offset ) + // + // case #5. Raw object's field reference for arraycopy stub call: + // The inline_native_clone() case when the arraycopy stub is called + // after the allocation before Initialize and CheckCastPP nodes. + // Allocate + // | + // Proj #5 ( oop result ) + // | | + // AddP ( base == address ) + // + // case #6. Constant Pool or ThreadLocal or Raw object's field reference: + // ConP # Object from Constant Pool. + // top | + // \ | + // AddP ( base == top ) + // + Node *base = addp->in(AddPNode::Base)->uncast(); + if (base->is_top()) { // The AddP case #3 and #6. + base = addp->in(AddPNode::Address)->uncast(); + assert(base->Opcode() == Op_ConP || base->Opcode() == Op_ThreadLocal || + base->is_Mem() && base->bottom_type() == TypeRawPtr::NOTNULL || + base->is_Proj() && base->in(0)->is_Allocate(), "sanity"); } - return mem; + return base; +} + +static Node* find_second_addp(Node* addp, Node* n) { + assert(addp->is_AddP() && addp->outcnt() > 0, "Don't process dead nodes"); + + Node* addp2 = addp->raw_out(0); + if (addp->outcnt() == 1 && addp2->is_AddP() && + addp2->in(AddPNode::Base) == n && + addp2->in(AddPNode::Address) == addp) { + + assert(addp->in(AddPNode::Base) == n, "expecting the same base"); + // + // Find array's offset to push it on worklist first and + // as result process an array's element offset first (pushed second) + // to avoid CastPP for the array's offset. + // Otherwise the inserted CastPP (LocalVar) will point to what + // the AddP (Field) points to. Which would be wrong since + // the algorithm expects the CastPP has the same point as + // as AddP's base CheckCastPP (LocalVar). + // + // ArrayAllocation + // | + // CheckCastPP + // | + // memProj (from ArrayAllocation CheckCastPP) + // | || + // | || Int (element index) + // | || | ConI (log(element size)) + // | || | / + // | || LShift + // | || / + // | AddP (array's element offset) + // | | + // | | ConI (array's offset: #12(32-bits) or #24(64-bits)) + // | / / + // AddP (array's offset) + // | + // Load/Store (memory operation on array's element) + // + return addp2; + } + return NULL; } // @@ -336,24 +446,33 @@ Node *ConnectionGraph::find_mem(Node *mem, int alias_idx, PhaseGVN *igvn) { // address of a field of an instance // void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { - const TypeOopPtr *t = igvn->type(addp)->isa_oopptr(); const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr(); - assert(t != NULL, "expecting oopptr"); assert(base_t != NULL && base_t->is_instance(), "expecting instance oopptr"); + const TypeOopPtr *t = igvn->type(addp)->isa_oopptr(); + if (t == NULL) { + // We are computing a raw address for a store captured by an Initialize + // compute an appropriate address type. + assert(igvn->type(addp) == TypeRawPtr::NOTNULL, "must be raw pointer"); + assert(addp->in(AddPNode::Address)->is_Proj(), "base of raw address must be result projection from allocation"); + int offs = (int)igvn->find_intptr_t_con(addp->in(AddPNode::Offset), Type::OffsetBot); + assert(offs != Type::OffsetBot, "offset must be a constant"); + t = base_t->add_offset(offs)->is_oopptr(); + } uint inst_id = base_t->instance_id(); assert(!t->is_instance() || t->instance_id() == inst_id, "old type must be non-instance or match new type"); const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr(); - // ensure an alias index is allocated for the instance type + // Do NOT remove the next call: ensure an new alias index is allocated + // for the instance type int alias_idx = _compile->get_alias_index(tinst); igvn->set_type(addp, tinst); // record the allocation in the node map set_map(addp->_idx, get_map(base->_idx)); - // if the Address input is not the appropriate instance type (due to intervening - // casts,) insert a cast + // if the Address input is not the appropriate instance type + // (due to intervening casts,) insert a cast Node *adr = addp->in(AddPNode::Address); const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr(); - if (atype->instance_id() != inst_id) { + if (atype != NULL && atype->instance_id() != inst_id) { assert(!atype->is_instance(), "no conflicting instances"); const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr(); Node *acast = new (_compile, 2) CastPPNode(adr, new_atype); @@ -372,8 +491,9 @@ void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) { addp->set_req(AddPNode::Base, bcast); addp->set_req(AddPNode::Address, acast); igvn->hash_insert(addp); - record_for_optimizer(addp); } + // Put on IGVN worklist since at least addp's type was changed above. + record_for_optimizer(addp); } // @@ -386,12 +506,11 @@ PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, Gro new_created = false; int phi_alias_idx = C->get_alias_index(orig_phi->adr_type()); // nothing to do if orig_phi is bottom memory or matches alias_idx - if (phi_alias_idx == Compile::AliasIdxBot || phi_alias_idx == alias_idx) { + if (phi_alias_idx == alias_idx) { return orig_phi; } // have we already created a Phi for this alias index? PhiNode *result = get_map_phi(orig_phi->_idx); - const TypePtr *atype = C->get_adr_type(alias_idx); if (result != NULL && C->get_alias_index(result->adr_type()) == alias_idx) { return result; } @@ -404,8 +523,8 @@ PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, Gro } return NULL; } - orig_phi_worklist.append_if_missing(orig_phi); + const TypePtr *atype = C->get_adr_type(alias_idx); result = PhiNode::make(orig_phi->in(0), NULL, Type::MEMORY, atype); set_map_phi(orig_phi->_idx, result); igvn->set_type(result, result->bottom_type()); @@ -423,7 +542,7 @@ PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, Gro assert(alias_idx != Compile::AliasIdxBot, "can't split out bottom memory"); Compile *C = _compile; bool new_phi_created; - PhiNode *result = create_split_phi(orig_phi, alias_idx, orig_phi_worklist, igvn, new_phi_created); + PhiNode *result = create_split_phi(orig_phi, alias_idx, orig_phi_worklist, igvn, new_phi_created); if (!new_phi_created) { return result; } @@ -436,20 +555,20 @@ PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, Gro bool finished = false; while(!finished) { while (idx < phi->req()) { - Node *mem = find_mem(phi->in(idx), alias_idx, igvn); + Node *mem = find_inst_mem(phi->in(idx), alias_idx, orig_phi_worklist, igvn); if (mem != NULL && mem->is_Phi()) { - PhiNode *nphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, igvn, new_phi_created); + PhiNode *newphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, igvn, new_phi_created); if (new_phi_created) { // found an phi for which we created a new split, push current one on worklist and begin // processing new one phi_list.push(phi); cur_input.push(idx); phi = mem->as_Phi(); - result = nphi; + result = newphi; idx = 1; continue; } else { - mem = nphi; + mem = newphi; } } if (C->failing()) { @@ -461,23 +580,124 @@ PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, Gro // verify that the new Phi has an input for each input of the original assert( phi->req() == result->req(), "must have same number of inputs."); assert( result->in(0) != NULL && result->in(0) == phi->in(0), "regions must match"); - for (uint i = 1; i < phi->req(); i++) { - assert((phi->in(i) == NULL) == (result->in(i) == NULL), "inputs must correspond."); - } #endif + // Check if all new phi's inputs have specified alias index. + // Otherwise use old phi. + for (uint i = 1; i < phi->req(); i++) { + Node* in = result->in(i); + assert((phi->in(i) == NULL) == (in == NULL), "inputs must correspond."); + } // we have finished processing a Phi, see if there are any more to do finished = (phi_list.length() == 0 ); if (!finished) { phi = phi_list.pop(); idx = cur_input.pop(); - PhiNode *prev_phi = get_map_phi(phi->_idx); - prev_phi->set_req(idx++, result); - result = prev_phi; + PhiNode *prev_result = get_map_phi(phi->_idx); + prev_result->set_req(idx++, result); + result = prev_result; } } return result; } + +// +// The next methods are derived from methods in MemNode. +// +static Node *step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *tinst) { + Node *mem = mmem; + // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally + // means an array I have not precisely typed yet. Do not do any + // alias stuff with it any time soon. + if( tinst->base() != Type::AnyPtr && + !(tinst->klass()->is_java_lang_Object() && + tinst->offset() == Type::OffsetBot) ) { + mem = mmem->memory_at(alias_idx); + // Update input if it is progress over what we have now + } + return mem; +} + +// +// Search memory chain of "mem" to find a MemNode whose address +// is the specified alias index. +// +Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray &orig_phis, PhaseGVN *phase) { + if (orig_mem == NULL) + return orig_mem; + Compile* C = phase->C; + const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr(); + bool is_instance = (tinst != NULL) && tinst->is_instance(); + Node *prev = NULL; + Node *result = orig_mem; + while (prev != result) { + prev = result; + if (result->is_Mem()) { + MemNode *mem = result->as_Mem(); + const Type *at = phase->type(mem->in(MemNode::Address)); + if (at != Type::TOP) { + assert (at->isa_ptr() != NULL, "pointer type required."); + int idx = C->get_alias_index(at->is_ptr()); + if (idx == alias_idx) + break; + } + result = mem->in(MemNode::Memory); + } + if (!is_instance) + continue; // don't search further for non-instance types + // skip over a call which does not affect this memory slice + if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { + Node *proj_in = result->in(0); + if (proj_in->is_Call()) { + CallNode *call = proj_in->as_Call(); + if (!call->may_modify(tinst, phase)) { + result = call->in(TypeFunc::Memory); + } + } else if (proj_in->is_Initialize()) { + AllocateNode* alloc = proj_in->as_Initialize()->allocation(); + // Stop if this is the initialization for the object instance which + // which contains this memory slice, otherwise skip over it. + if (alloc == NULL || alloc->_idx != tinst->instance_id()) { + result = proj_in->in(TypeFunc::Memory); + } + } else if (proj_in->is_MemBar()) { + result = proj_in->in(TypeFunc::Memory); + } + } else if (result->is_MergeMem()) { + MergeMemNode *mmem = result->as_MergeMem(); + result = step_through_mergemem(mmem, alias_idx, tinst); + if (result == mmem->base_memory()) { + // Didn't find instance memory, search through general slice recursively. + result = mmem->memory_at(C->get_general_index(alias_idx)); + result = find_inst_mem(result, alias_idx, orig_phis, phase); + if (C->failing()) { + return NULL; + } + mmem->set_memory_at(alias_idx, result); + } + } else if (result->is_Phi() && + C->get_alias_index(result->as_Phi()->adr_type()) != alias_idx) { + Node *un = result->as_Phi()->unique_input(phase); + if (un != NULL) { + result = un; + } else { + break; + } + } + } + if (is_instance && result->is_Phi()) { + PhiNode *mphi = result->as_Phi(); + assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); + const TypePtr *t = mphi->adr_type(); + if (C->get_alias_index(t) != alias_idx) { + result = split_memory_phi(mphi, alias_idx, orig_phis, phase); + } + } + // the result is either MemNode, PhiNode, InitializeNode. + return result; +} + + // // Convert the types of unescaped object to instance types where possible, // propagate the new type information through the graph, and update memory @@ -576,56 +796,101 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) VectorSet visited(Thread::current()->resource_area()); VectorSet ptset(Thread::current()->resource_area()); - // Phase 1: Process possible allocations from alloc_worklist. Create instance - // types for the CheckCastPP for allocations where possible. + + // Phase 1: Process possible allocations from alloc_worklist. + // Create instance types for the CheckCastPP for allocations where possible. while (alloc_worklist.length() != 0) { Node *n = alloc_worklist.pop(); uint ni = n->_idx; + const TypeOopPtr* tinst = NULL; if (n->is_Call()) { CallNode *alloc = n->as_Call(); // copy escape information to call node - PointsToNode ptn = _nodes->at(alloc->_idx); + PointsToNode* ptn = _nodes->adr_at(alloc->_idx); PointsToNode::EscapeState es = escape_state(alloc, igvn); - alloc->_escape_state = es; - // find CheckCastPP of call return value - n = alloc->proj_out(TypeFunc::Parms); - if (n != NULL && n->outcnt() == 1) { - n = n->unique_out(); - if (n->Opcode() != Op_CheckCastPP) { - continue; - } - } else { + // We have an allocation or call which returns a Java object, + // see if it is unescaped. + if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable) continue; - } - // we have an allocation or call which returns a Java object, see if it is unescaped - if (es != PointsToNode::NoEscape || !ptn._unique_type) { - continue; // can't make a unique type - } if (alloc->is_Allocate()) { // Set the scalar_replaceable flag before the next check. alloc->as_Allocate()->_is_scalar_replaceable = true; } - + // find CheckCastPP of call return value + n = alloc->result_cast(); + if (n == NULL || // No uses accept Initialize or + !n->is_CheckCastPP()) // not unique CheckCastPP. + continue; + // The inline code for Object.clone() casts the allocation result to + // java.lang.Object and then to the the actual type of the allocated + // object. Detect this case and use the second cast. + if (alloc->is_Allocate() && n->as_Type()->type() == TypeInstPtr::NOTNULL + && igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT) { + Node *cast2 = NULL; + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node *use = n->fast_out(i); + if (use->is_CheckCastPP()) { + cast2 = use; + break; + } + } + if (cast2 != NULL) { + n = cast2; + } else { + continue; + } + } + set_escape_state(n->_idx, es); + // in order for an object to be stackallocatable, it must be: + // - a direct allocation (not a call returning an object) + // - non-escaping + // - eligible to be a unique type + // - not determined to be ineligible by escape analysis set_map(alloc->_idx, n); set_map(n->_idx, alloc); - const TypeInstPtr *t = igvn->type(n)->isa_instptr(); - // Unique types which are arrays are not currently supported. - // The check for AllocateArray is needed in case an array - // allocation is immediately cast to Object - if (t == NULL || alloc->is_AllocateArray()) + const TypeOopPtr *t = igvn->type(n)->isa_oopptr(); + if (t == NULL) continue; // not a TypeInstPtr - const TypeOopPtr *tinst = t->cast_to_instance(ni); + tinst = t->cast_to_instance(ni); igvn->hash_delete(n); igvn->set_type(n, tinst); n->raise_bottom_type(tinst); igvn->hash_insert(n); + record_for_optimizer(n); + if (alloc->is_Allocate() && ptn->_scalar_replaceable && + (t->isa_instptr() || t->isa_aryptr())) { + // An allocation may have an Initialize which has raw stores. Scan + // the users of the raw allocation result and push AddP users + // on alloc_worklist. + Node *raw_result = alloc->proj_out(TypeFunc::Parms); + assert (raw_result != NULL, "must have an allocation result"); + for (DUIterator_Fast imax, i = raw_result->fast_outs(imax); i < imax; i++) { + Node *use = raw_result->fast_out(i); + if (use->is_AddP() && use->outcnt() > 0) { // Don't process dead nodes + Node* addp2 = find_second_addp(use, raw_result); + if (addp2 != NULL) { + assert(alloc->is_AllocateArray(),"array allocation was expected"); + alloc_worklist.append_if_missing(addp2); + } + alloc_worklist.append_if_missing(use); + } else if (use->is_Initialize()) { + memnode_worklist.append_if_missing(use); + } + } + } } else if (n->is_AddP()) { ptset.Clear(); - PointsTo(ptset, n->in(AddPNode::Address), igvn); + PointsTo(ptset, get_addp_base(n), igvn); assert(ptset.Size() == 1, "AddP address is unique"); - Node *base = get_map(ptset.getelem()); + uint elem = ptset.getelem(); // Allocation node's index + if (elem == _phantom_object) + continue; // Assume the value was set outside this method. + Node *base = get_map(elem); // CheckCastPP node split_AddP(n, base, igvn); - } else if (n->is_Phi() || n->Opcode() == Op_CastPP || n->Opcode() == Op_CheckCastPP) { + tinst = igvn->type(base)->isa_oopptr(); + } else if (n->is_Phi() || + n->is_CheckCastPP() || + (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) { if (visited.test_set(n->_idx)) { assert(n->is_Phi(), "loops only through Phi's"); continue; // already processed @@ -633,17 +898,23 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) ptset.Clear(); PointsTo(ptset, n, igvn); if (ptset.Size() == 1) { + uint elem = ptset.getelem(); // Allocation node's index + if (elem == _phantom_object) + continue; // Assume the value was set outside this method. + Node *val = get_map(elem); // CheckCastPP node TypeNode *tn = n->as_Type(); - Node *val = get_map(ptset.getelem()); - const TypeInstPtr *val_t = igvn->type(val)->isa_instptr();; - assert(val_t != NULL && val_t->is_instance(), "instance type expected."); - const TypeInstPtr *tn_t = igvn->type(tn)->isa_instptr();; + tinst = igvn->type(val)->isa_oopptr(); + assert(tinst != NULL && tinst->is_instance() && + tinst->instance_id() == elem , "instance type expected."); + const TypeOopPtr *tn_t = igvn->type(tn)->isa_oopptr(); - if (tn_t != NULL && val_t->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) { + if (tn_t != NULL && + tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) { igvn->hash_delete(tn); - igvn->set_type(tn, val_t); - tn->set_type(val_t); + igvn->set_type(tn, tinst); + tn->set_type(tinst); igvn->hash_insert(tn); + record_for_optimizer(n); } } } else { @@ -653,13 +924,38 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node *use = n->fast_out(i); if(use->is_Mem() && use->in(MemNode::Address) == n) { - memnode_worklist.push(use); - } else if (use->is_AddP() || use->is_Phi() || use->Opcode() == Op_CastPP || use->Opcode() == Op_CheckCastPP) { - alloc_worklist.push(use); + memnode_worklist.append_if_missing(use); + } else if (use->is_Initialize()) { + memnode_worklist.append_if_missing(use); + } else if (use->is_MergeMem()) { + mergemem_worklist.append_if_missing(use); + } else if (use->is_Call() && tinst != NULL) { + // Look for MergeMem nodes for calls which reference unique allocation + // (through CheckCastPP nodes) even for debug info. + Node* m = use->in(TypeFunc::Memory); + uint iid = tinst->instance_id(); + while (m->is_Proj() && m->in(0)->is_Call() && + m->in(0) != use && !m->in(0)->_idx != iid) { + m = m->in(0)->in(TypeFunc::Memory); + } + if (m->is_MergeMem()) { + mergemem_worklist.append_if_missing(m); + } + } else if (use->is_AddP() && use->outcnt() > 0) { // No dead nodes + Node* addp2 = find_second_addp(use, n); + if (addp2 != NULL) { + alloc_worklist.append_if_missing(addp2); + } + alloc_worklist.append_if_missing(use); + } else if (use->is_Phi() || + use->is_CheckCastPP() || + (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) { + alloc_worklist.append_if_missing(use); } } } + // New alias types were created in split_AddP(). uint new_index_end = (uint) _compile->num_alias_types(); // Phase 2: Process MemNode's from memnode_worklist. compute new address type and @@ -668,32 +964,37 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) if (memnode_worklist.length() == 0) return; // nothing to do - while (memnode_worklist.length() != 0) { Node *n = memnode_worklist.pop(); + if (visited.test_set(n->_idx)) + continue; if (n->is_Phi()) { assert(n->as_Phi()->adr_type() != TypePtr::BOTTOM, "narrow memory slice required"); // we don't need to do anything, but the users must be pushed if we haven't processed // this Phi before - if (visited.test_set(n->_idx)) + } else if (n->is_Initialize()) { + // we don't need to do anything, but the users of the memory projection must be pushed + n = n->as_Initialize()->proj_out(TypeFunc::Memory); + if (n == NULL) continue; } else { assert(n->is_Mem(), "memory node required."); Node *addr = n->in(MemNode::Address); + assert(addr->is_AddP(), "AddP required"); const Type *addr_t = igvn->type(addr); if (addr_t == Type::TOP) continue; assert (addr_t->isa_ptr() != NULL, "pointer type required."); int alias_idx = _compile->get_alias_index(addr_t->is_ptr()); - Node *mem = find_mem(n->in(MemNode::Memory), alias_idx, igvn); - if (mem->is_Phi()) { - mem = split_memory_phi(mem->as_Phi(), alias_idx, orig_phis, igvn); - } + assert ((uint)alias_idx < new_index_end, "wrong alias index"); + Node *mem = find_inst_mem(n->in(MemNode::Memory), alias_idx, orig_phis, igvn); if (_compile->failing()) { return; } - if (mem != n->in(MemNode::Memory)) + if (mem != n->in(MemNode::Memory)) { set_map(n->_idx, mem); + _nodes->adr_at(n->_idx)->_node = n; + } if (n->is_Load()) { continue; // don't push users } else if (n->is_LoadStore()) { @@ -712,29 +1013,33 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { Node *use = n->fast_out(i); if (use->is_Phi()) { - memnode_worklist.push(use); + memnode_worklist.append_if_missing(use); } else if(use->is_Mem() && use->in(MemNode::Memory) == n) { - memnode_worklist.push(use); + memnode_worklist.append_if_missing(use); + } else if (use->is_Initialize()) { + memnode_worklist.append_if_missing(use); } else if (use->is_MergeMem()) { - mergemem_worklist.push(use); + mergemem_worklist.append_if_missing(use); } } } - // Phase 3: Process MergeMem nodes from mergemem_worklist. Walk each memory slice - // moving the first node encountered of each instance type to the - // the input corresponding to its alias index. + // Phase 3: Process MergeMem nodes from mergemem_worklist. + // Walk each memory moving the first node encountered of each + // instance type to the the input corresponding to its alias index. while (mergemem_worklist.length() != 0) { Node *n = mergemem_worklist.pop(); assert(n->is_MergeMem(), "MergeMem node required."); + if (visited.test_set(n->_idx)) + continue; MergeMemNode *nmm = n->as_MergeMem(); // Note: we don't want to use MergeMemStream here because we only want to - // scan inputs which exist at the start, not ones we add during processing + // scan inputs which exist at the start, not ones we add during processing. uint nslices = nmm->req(); igvn->hash_delete(nmm); for (uint i = Compile::AliasIdxRaw+1; i < nslices; i++) { - Node * mem = nmm->in(i); - Node * cur = NULL; + Node* mem = nmm->in(i); + Node* cur = NULL; if (mem == NULL || mem->is_top()) continue; while (mem->is_Mem()) { @@ -754,30 +1059,76 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) mem = mem->in(MemNode::Memory); } nmm->set_memory_at(i, (cur != NULL) ? cur : mem); - if (mem->is_Phi()) { - // We have encountered a Phi, we need to split the Phi for - // any instance of the current type if we haven't encountered - // a value of the instance along the chain. - for (uint ni = new_index_start; ni < new_index_end; ni++) { - if((uint)_compile->get_general_index(ni) == i) { - Node *m = (ni >= nmm->req()) ? nmm->empty_memory() : nmm->in(ni); - if (nmm->is_empty_memory(m)) { - m = split_memory_phi(mem->as_Phi(), ni, orig_phis, igvn); - if (_compile->failing()) { - return; - } - nmm->set_memory_at(ni, m); + // Find any instance of the current type if we haven't encountered + // a value of the instance along the chain. + for (uint ni = new_index_start; ni < new_index_end; ni++) { + if((uint)_compile->get_general_index(ni) == i) { + Node *m = (ni >= nmm->req()) ? nmm->empty_memory() : nmm->in(ni); + if (nmm->is_empty_memory(m)) { + Node* result = find_inst_mem(mem, ni, orig_phis, igvn); + if (_compile->failing()) { + return; + } + nmm->set_memory_at(ni, result); + } + } + } + } + // Find the rest of instances values + for (uint ni = new_index_start; ni < new_index_end; ni++) { + const TypeOopPtr *tinst = igvn->C->get_adr_type(ni)->isa_oopptr(); + Node* result = step_through_mergemem(nmm, ni, tinst); + if (result == nmm->base_memory()) { + // Didn't find instance memory, search through general slice recursively. + result = nmm->memory_at(igvn->C->get_general_index(ni)); + result = find_inst_mem(result, ni, orig_phis, igvn); + if (_compile->failing()) { + return; + } + nmm->set_memory_at(ni, result); + } + } + igvn->hash_insert(nmm); + record_for_optimizer(nmm); + + // Propagate new memory slices to following MergeMem nodes. + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node *use = n->fast_out(i); + if (use->is_Call()) { + CallNode* in = use->as_Call(); + if (in->proj_out(TypeFunc::Memory) != NULL) { + Node* m = in->proj_out(TypeFunc::Memory); + for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) { + Node* mm = m->fast_out(j); + if (mm->is_MergeMem()) { + mergemem_worklist.append_if_missing(mm); + } + } + } + if (use->is_Allocate()) { + use = use->as_Allocate()->initialization(); + if (use == NULL) { + continue; + } + } + } + if (use->is_Initialize()) { + InitializeNode* in = use->as_Initialize(); + if (in->proj_out(TypeFunc::Memory) != NULL) { + Node* m = in->proj_out(TypeFunc::Memory); + for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) { + Node* mm = m->fast_out(j); + if (mm->is_MergeMem()) { + mergemem_worklist.append_if_missing(mm); } } } } } - igvn->hash_insert(nmm); - record_for_optimizer(nmm); } - // Phase 4: Update the inputs of non-instance memory Phis and the Memory input of memnodes - // + // Phase 4: Update the inputs of non-instance memory Phis and + // the Memory input of memnodes // First update the inputs of any non-instance Phi's from // which we split out an instance Phi. Note we don't have // to recursively process Phi's encounted on the input memory @@ -789,7 +1140,10 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) igvn->hash_delete(phi); for (uint i = 1; i < phi->req(); i++) { Node *mem = phi->in(i); - Node *new_mem = find_mem(mem, alias_idx, igvn); + Node *new_mem = find_inst_mem(mem, alias_idx, orig_phis, igvn); + if (_compile->failing()) { + return; + } if (mem != new_mem) { phi->set_req(i, new_mem); } @@ -803,7 +1157,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) for (int i = 0; i < _nodes->length(); i++) { Node *nmem = get_map(i); if (nmem != NULL) { - Node *n = _nodes->at(i)._node; + Node *n = _nodes->adr_at(i)->_node; if (n != NULL && n->is_Mem()) { igvn->hash_delete(n); n->set_req(MemNode::Memory, nmem); @@ -815,59 +1169,110 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } void ConnectionGraph::compute_escape() { - GrowableArray worklist; - GrowableArray alloc_worklist; - VectorSet visited(Thread::current()->resource_area()); - PhaseGVN *igvn = _compile->initial_gvn(); - // process Phi nodes from the deferred list, they may not have - while(_deferred.size() > 0) { - Node * n = _deferred.pop(); - PhiNode * phi = n->as_Phi(); + // 1. Populate Connection Graph with Ideal nodes. - process_phi_escape(phi, igvn); + Unique_Node_List worklist_init; + worklist_init.map(_compile->unique(), NULL); // preallocate space + + // Initialize worklist + if (_compile->root() != NULL) { + worklist_init.push(_compile->root()); + } + + GrowableArray cg_worklist; + PhaseGVN* igvn = _compile->initial_gvn(); + bool has_allocations = false; + + // Push all useful nodes onto CG list and set their type. + for( uint next = 0; next < worklist_init.size(); ++next ) { + Node* n = worklist_init.at(next); + record_for_escape_analysis(n, igvn); + if (n->is_Call() && + _nodes->adr_at(n->_idx)->node_type() == PointsToNode::JavaObject) { + has_allocations = true; + } + if(n->is_AddP()) + cg_worklist.append(n->_idx); + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* m = n->fast_out(i); // Get user + worklist_init.push(m); + } + } + + if (has_allocations) { + _has_allocations = true; + } else { + _has_allocations = false; + _collecting = false; + return; // Nothing to do. + } + + // 2. First pass to create simple CG edges (doesn't require to walk CG). + for( uint next = 0; next < _delayed_worklist.size(); ++next ) { + Node* n = _delayed_worklist.at(next); + build_connection_graph(n, igvn); + } + + // 3. Pass to create fields edges (Allocate -F-> AddP). + for( int next = 0; next < cg_worklist.length(); ++next ) { + int ni = cg_worklist.at(next); + build_connection_graph(_nodes->adr_at(ni)->_node, igvn); + } + + cg_worklist.clear(); + cg_worklist.append(_phantom_object); + + // 4. Build Connection Graph which need + // to walk the connection graph. + for (uint ni = 0; ni < (uint)_nodes->length(); ni++) { + PointsToNode* ptn = _nodes->adr_at(ni); + Node *n = ptn->_node; + if (n != NULL) { // Call, AddP, LoadP, StoreP + build_connection_graph(n, igvn); + if (ptn->node_type() != PointsToNode::UnknownType) + cg_worklist.append(n->_idx); // Collect CG nodes + } } VectorSet ptset(Thread::current()->resource_area()); + GrowableArray alloc_worklist; + GrowableArray worklist; // remove deferred edges from the graph and collect // information we will need for type splitting - for (uint ni = 0; ni < (uint)_nodes->length(); ni++) { - PointsToNode * ptn = _nodes->adr_at(ni); + for( int next = 0; next < cg_worklist.length(); ++next ) { + int ni = cg_worklist.at(next); + PointsToNode* ptn = _nodes->adr_at(ni); PointsToNode::NodeType nt = ptn->node_type(); - - if (nt == PointsToNode::UnknownType) { - continue; // not a node we are interested in - } Node *n = ptn->_node; if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { remove_deferred(ni); if (n->is_AddP()) { - // if this AddP computes an address which may point to more that one - // object, nothing the address points to can be a unique type. - Node *base = n->in(AddPNode::Base); + // If this AddP computes an address which may point to more that one + // object, nothing the address points to can be scalar replaceable. + Node *base = get_addp_base(n); ptset.Clear(); PointsTo(ptset, base, igvn); if (ptset.Size() > 1) { for( VectorSetI j(&ptset); j.test(); ++j ) { - PointsToNode *ptaddr = _nodes->adr_at(j.elem); - ptaddr->_unique_type = false; + uint pt = j.elem; + ptnode_adr(pt)->_scalar_replaceable = false; } } } - } else if (n->is_Call()) { - // initialize _escape_state of calls to GlobalEscape - n->as_Call()->_escape_state = PointsToNode::GlobalEscape; - // push call on alloc_worlist (alocations are calls) - // for processing by split_unique_types() - alloc_worklist.push(n); + } else if (nt == PointsToNode::JavaObject && n->is_Call()) { + // Push call on alloc_worlist (alocations are calls) + // for processing by split_unique_types(). + alloc_worklist.append(n); } } + // push all GlobalEscape nodes on the worklist - for (uint nj = 0; nj < (uint)_nodes->length(); nj++) { - if (_nodes->at(nj).escape_state() == PointsToNode::GlobalEscape) { - worklist.append(nj); - } + for( int next = 0; next < cg_worklist.length(); ++next ) { + int nk = cg_worklist.at(next); + if (_nodes->adr_at(nk)->escape_state() == PointsToNode::GlobalEscape) + worklist.append(nk); } // mark all node reachable from GlobalEscape nodes while(worklist.length() > 0) { @@ -875,7 +1280,7 @@ void ConnectionGraph::compute_escape() { for (uint ei = 0; ei < n.edge_count(); ei++) { uint npi = n.edge_target(ei); PointsToNode *np = ptnode_adr(npi); - if (np->escape_state() != PointsToNode::GlobalEscape) { + if (np->escape_state() < PointsToNode::GlobalEscape) { np->set_escape_state(PointsToNode::GlobalEscape); worklist.append_if_missing(npi); } @@ -883,133 +1288,191 @@ void ConnectionGraph::compute_escape() { } // push all ArgEscape nodes on the worklist - for (uint nk = 0; nk < (uint)_nodes->length(); nk++) { - if (_nodes->at(nk).escape_state() == PointsToNode::ArgEscape) + for( int next = 0; next < cg_worklist.length(); ++next ) { + int nk = cg_worklist.at(next); + if (_nodes->adr_at(nk)->escape_state() == PointsToNode::ArgEscape) worklist.push(nk); } // mark all node reachable from ArgEscape nodes while(worklist.length() > 0) { PointsToNode n = _nodes->at(worklist.pop()); - for (uint ei = 0; ei < n.edge_count(); ei++) { uint npi = n.edge_target(ei); PointsToNode *np = ptnode_adr(npi); - if (np->escape_state() != PointsToNode::ArgEscape) { + if (np->escape_state() < PointsToNode::ArgEscape) { np->set_escape_state(PointsToNode::ArgEscape); worklist.append_if_missing(npi); } } } + + // push all NoEscape nodes on the worklist + for( int next = 0; next < cg_worklist.length(); ++next ) { + int nk = cg_worklist.at(next); + if (_nodes->adr_at(nk)->escape_state() == PointsToNode::NoEscape) + worklist.push(nk); + } + // mark all node reachable from NoEscape nodes + while(worklist.length() > 0) { + PointsToNode n = _nodes->at(worklist.pop()); + for (uint ei = 0; ei < n.edge_count(); ei++) { + uint npi = n.edge_target(ei); + PointsToNode *np = ptnode_adr(npi); + if (np->escape_state() < PointsToNode::NoEscape) { + np->set_escape_state(PointsToNode::NoEscape); + worklist.append_if_missing(npi); + } + } + } + _collecting = false; - // Now use the escape information to create unique types for - // unescaped objects - split_unique_types(alloc_worklist); - if (_compile->failing()) return; + has_allocations = false; // Are there scalar replaceable allocations? - // Clean up after split unique types. - ResourceMark rm; - PhaseRemoveUseless pru(_compile->initial_gvn(), _compile->for_igvn()); -} - -Node * ConnectionGraph::skip_casts(Node *n) { - while(n->Opcode() == Op_CastPP || n->Opcode() == Op_CheckCastPP) { - n = n->in(1); - } - return n; -} - -void ConnectionGraph::process_phi_escape(PhiNode *phi, PhaseTransform *phase) { - - if (phi->type()->isa_oopptr() == NULL) - return; // nothing to do if not an oop - - PointsToNode *ptadr = ptnode_adr(phi->_idx); - int incount = phi->req(); - int non_null_inputs = 0; - - for (int i = 1; i < incount ; i++) { - if (phi->in(i) != NULL) - non_null_inputs++; - } - if (non_null_inputs == ptadr->_inputs_processed) - return; // no new inputs since the last time this node was processed, - // the current information is valid - - ptadr->_inputs_processed = non_null_inputs; // prevent recursive processing of this node - for (int j = 1; j < incount ; j++) { - Node * n = phi->in(j); - if (n == NULL) - continue; // ignore NULL - n = skip_casts(n); - if (n->is_top() || n == phi) - continue; // ignore top or inputs which go back this node - int nopc = n->Opcode(); - PointsToNode npt = _nodes->at(n->_idx); - if (_nodes->at(n->_idx).node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(phi->_idx, n->_idx); - } else { - add_deferred_edge(phi->_idx, n->_idx); + for( int next = 0; next < alloc_worklist.length(); ++next ) { + Node* n = alloc_worklist.at(next); + uint ni = n->_idx; + PointsToNode* ptn = _nodes->adr_at(ni); + PointsToNode::EscapeState es = ptn->escape_state(); + if (ptn->escape_state() == PointsToNode::NoEscape && + ptn->_scalar_replaceable) { + has_allocations = true; + break; } } + if (!has_allocations) { + return; // Nothing to do. + } + + if(_compile->AliasLevel() >= 3 && EliminateAllocations) { + // Now use the escape information to create unique types for + // unescaped objects + split_unique_types(alloc_worklist); + if (_compile->failing()) return; + + // Clean up after split unique types. + ResourceMark rm; + PhaseRemoveUseless pru(_compile->initial_gvn(), _compile->for_igvn()); + +#ifdef ASSERT + } else if (PrintEscapeAnalysis || PrintEliminateAllocations) { + tty->print("=== No allocations eliminated for "); + C()->method()->print_short_name(); + if(!EliminateAllocations) { + tty->print(" since EliminateAllocations is off ==="); + } else if(_compile->AliasLevel() < 3) { + tty->print(" since AliasLevel < 3 ==="); + } + tty->cr(); +#endif + } } void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) { - _processed.set(call->_idx); switch (call->Opcode()) { - - // arguments to allocation and locking don't escape +#ifdef ASSERT case Op_Allocate: case Op_AllocateArray: case Op_Lock: case Op_Unlock: + assert(false, "should be done already"); break; +#endif + case Op_CallLeafNoFP: + { + // Stub calls, objects do not escape but they are not scale replaceable. + // Adjust escape state for outgoing arguments. + const TypeTuple * d = call->tf()->domain(); + VectorSet ptset(Thread::current()->resource_area()); + for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { + const Type* at = d->field_at(i); + Node *arg = call->in(i)->uncast(); + const Type *aat = phase->type(arg); + if (!arg->is_top() && at->isa_ptr() && aat->isa_ptr()) { + assert(aat == Type::TOP || aat == TypePtr::NULL_PTR || + aat->isa_ptr() != NULL, "expecting an Ptr"); + set_escape_state(arg->_idx, PointsToNode::ArgEscape); + if (arg->is_AddP()) { + // + // The inline_native_clone() case when the arraycopy stub is called + // after the allocation before Initialize and CheckCastPP nodes. + // + // Set AddP's base (Allocate) as not scalar replaceable since + // pointer to the base (with offset) is passed as argument. + // + arg = get_addp_base(arg); + } + ptset.Clear(); + PointsTo(ptset, arg, phase); + for( VectorSetI j(&ptset); j.test(); ++j ) { + uint pt = j.elem; + set_escape_state(pt, PointsToNode::ArgEscape); + } + } + } + break; + } case Op_CallStaticJava: // For a static call, we know exactly what method is being called. // Use bytecode estimator to record the call's escape affects { ciMethod *meth = call->as_CallJava()->method(); - if (meth != NULL) { + BCEscapeAnalyzer *call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL; + // fall-through if not a Java method or no analyzer information + if (call_analyzer != NULL) { const TypeTuple * d = call->tf()->domain(); - BCEscapeAnalyzer call_analyzer(meth); VectorSet ptset(Thread::current()->resource_area()); + bool copy_dependencies = false; for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); int k = i - TypeFunc::Parms; if (at->isa_oopptr() != NULL) { - Node *arg = skip_casts(call->in(i)); + Node *arg = call->in(i)->uncast(); - if (!call_analyzer.is_arg_stack(k)) { + bool global_escapes = false; + bool fields_escapes = false; + if (!call_analyzer->is_arg_stack(k)) { // The argument global escapes, mark everything it could point to - ptset.Clear(); - PointsTo(ptset, arg, phase); - for( VectorSetI j(&ptset); j.test(); ++j ) { - uint pt = j.elem; - - set_escape_state(pt, PointsToNode::GlobalEscape); + set_escape_state(arg->_idx, PointsToNode::GlobalEscape); + global_escapes = true; + } else { + if (!call_analyzer->is_arg_local(k)) { + // The argument itself doesn't escape, but any fields might + fields_escapes = true; } - } else if (!call_analyzer.is_arg_local(k)) { - // The argument itself doesn't escape, but any fields might - ptset.Clear(); - PointsTo(ptset, arg, phase); - for( VectorSetI j(&ptset); j.test(); ++j ) { - uint pt = j.elem; - add_edge_from_fields(pt, _phantom_object, Type::OffsetBot); + set_escape_state(arg->_idx, PointsToNode::ArgEscape); + copy_dependencies = true; + } + + ptset.Clear(); + PointsTo(ptset, arg, phase); + for( VectorSetI j(&ptset); j.test(); ++j ) { + uint pt = j.elem; + if (global_escapes) { + //The argument global escapes, mark everything it could point to + set_escape_state(pt, PointsToNode::GlobalEscape); + } else { + if (fields_escapes) { + // The argument itself doesn't escape, but any fields might + add_edge_from_fields(pt, _phantom_object, Type::OffsetBot); + } + set_escape_state(pt, PointsToNode::ArgEscape); } } } } - call_analyzer.copy_dependencies(C()->dependencies()); + if (copy_dependencies) + call_analyzer->copy_dependencies(C()->dependencies()); break; } - // fall-through if not a Java method } default: - // Some other type of call, assume the worst case: all arguments + // Fall-through here if not a Java method or no analyzer information + // or some other type of call, assume the worst case: all arguments // globally escape. { // adjust escape state for outgoing arguments @@ -1017,15 +1480,15 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha VectorSet ptset(Thread::current()->resource_area()); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); - if (at->isa_oopptr() != NULL) { - Node *arg = skip_casts(call->in(i)); + Node *arg = call->in(i)->uncast(); + set_escape_state(arg->_idx, PointsToNode::GlobalEscape); ptset.Clear(); PointsTo(ptset, arg, phase); for( VectorSetI j(&ptset); j.test(); ++j ) { uint pt = j.elem; - set_escape_state(pt, PointsToNode::GlobalEscape); + PointsToNode *ptadr = ptnode_adr(pt); } } } @@ -1033,15 +1496,9 @@ void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *pha } } void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) { - CallNode *call = resproj->in(0)->as_Call(); - PointsToNode *ptadr = ptnode_adr(resproj->_idx); - ptadr->_node = resproj; - ptadr->set_node_type(PointsToNode::LocalVar); - set_escape_state(resproj->_idx, PointsToNode::UnknownEscape); - _processed.set(resproj->_idx); - + CallNode *call = resproj->in(0)->as_Call(); switch (call->Opcode()) { case Op_Allocate: { @@ -1057,36 +1514,40 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha ciInstanceKlass* ciik = cik->as_instance_klass(); PointsToNode *ptadr = ptnode_adr(call->_idx); - ptadr->set_node_type(PointsToNode::JavaObject); + PointsToNode::EscapeState es; + uint edge_to; if (cik->is_subclass_of(_compile->env()->Thread_klass()) || ciik->has_finalizer()) { - set_escape_state(call->_idx, PointsToNode::GlobalEscape); - add_pointsto_edge(resproj->_idx, _phantom_object); + es = PointsToNode::GlobalEscape; + edge_to = _phantom_object; // Could not be worse } else { - set_escape_state(call->_idx, PointsToNode::NoEscape); - add_pointsto_edge(resproj->_idx, call->_idx); + es = PointsToNode::NoEscape; + edge_to = call->_idx; } - _processed.set(call->_idx); + set_escape_state(call->_idx, es); + add_pointsto_edge(resproj->_idx, edge_to); + _processed.set(resproj->_idx); break; } case Op_AllocateArray: { PointsToNode *ptadr = ptnode_adr(call->_idx); - ptadr->set_node_type(PointsToNode::JavaObject); + int length = call->in(AllocateNode::ALength)->find_int_con(-1); + if (length < 0 || length > EliminateAllocationArraySizeLimit) { + // Not scalar replaceable if the length is not constant or too big. + ptadr->_scalar_replaceable = false; + } set_escape_state(call->_idx, PointsToNode::NoEscape); - _processed.set(call->_idx); add_pointsto_edge(resproj->_idx, call->_idx); + _processed.set(resproj->_idx); break; } - case Op_Lock: - case Op_Unlock: - break; - case Op_CallStaticJava: // For a static call, we know exactly what method is being called. // Use bytecode estimator to record whether the call's return value escapes { + bool done = true; const TypeTuple *r = call->tf()->range(); const Type* ret_type = NULL; @@ -1095,32 +1556,45 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // Note: we use isa_ptr() instead of isa_oopptr() here because the // _multianewarray functions return a TypeRawPtr. - if (ret_type == NULL || ret_type->isa_ptr() == NULL) + if (ret_type == NULL || ret_type->isa_ptr() == NULL) { + _processed.set(resproj->_idx); break; // doesn't return a pointer type - + } ciMethod *meth = call->as_CallJava()->method(); + const TypeTuple * d = call->tf()->domain(); if (meth == NULL) { // not a Java method, assume global escape set_escape_state(call->_idx, PointsToNode::GlobalEscape); if (resproj != NULL) add_pointsto_edge(resproj->_idx, _phantom_object); } else { - BCEscapeAnalyzer call_analyzer(meth); + BCEscapeAnalyzer *call_analyzer = meth->get_bcea(); VectorSet ptset(Thread::current()->resource_area()); + bool copy_dependencies = false; - if (call_analyzer.is_return_local() && resproj != NULL) { + if (call_analyzer->is_return_allocated()) { + // Returns a newly allocated unescaped object, simply + // update dependency information. + // Mark it as NoEscape so that objects referenced by + // it's fields will be marked as NoEscape at least. + set_escape_state(call->_idx, PointsToNode::NoEscape); + if (resproj != NULL) + add_pointsto_edge(resproj->_idx, call->_idx); + copy_dependencies = true; + } else if (call_analyzer->is_return_local() && resproj != NULL) { // determine whether any arguments are returned - const TypeTuple * d = call->tf()->domain(); set_escape_state(call->_idx, PointsToNode::NoEscape); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); if (at->isa_oopptr() != NULL) { - Node *arg = skip_casts(call->in(i)); + Node *arg = call->in(i)->uncast(); - if (call_analyzer.is_arg_returned(i - TypeFunc::Parms)) { + if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) { PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); - if (arg_esp->node_type() == PointsToNode::JavaObject) + if (arg_esp->node_type() == PointsToNode::UnknownType) + done = false; + else if (arg_esp->node_type() == PointsToNode::JavaObject) add_pointsto_edge(resproj->_idx, arg->_idx); else add_deferred_edge(resproj->_idx, arg->_idx); @@ -1128,13 +1602,25 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha } } } + copy_dependencies = true; } else { set_escape_state(call->_idx, PointsToNode::GlobalEscape); if (resproj != NULL) add_pointsto_edge(resproj->_idx, _phantom_object); + for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { + const Type* at = d->field_at(i); + if (at->isa_oopptr() != NULL) { + Node *arg = call->in(i)->uncast(); + PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); + arg_esp->_hidden_alias = true; + } + } } - call_analyzer.copy_dependencies(C()->dependencies()); + if (copy_dependencies) + call_analyzer->copy_dependencies(C()->dependencies()); } + if (done) + _processed.set(resproj->_idx); break; } @@ -1143,7 +1629,6 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // returned value, if any, globally escapes. { const TypeTuple *r = call->tf()->range(); - if (r->cnt() > TypeFunc::Parms) { const Type* ret_type = r->field_at(TypeFunc::Parms); @@ -1151,188 +1636,414 @@ void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *pha // _multianewarray functions return a TypeRawPtr. if (ret_type->isa_ptr() != NULL) { PointsToNode *ptadr = ptnode_adr(call->_idx); - ptadr->set_node_type(PointsToNode::JavaObject); set_escape_state(call->_idx, PointsToNode::GlobalEscape); if (resproj != NULL) add_pointsto_edge(resproj->_idx, _phantom_object); } } + _processed.set(resproj->_idx); } } } -void ConnectionGraph::record_for_escape_analysis(Node *n) { - if (_collecting) { - if (n->is_Phi()) { - PhiNode *phi = n->as_Phi(); - const Type *pt = phi->type(); - if ((pt->isa_oopptr() != NULL) || pt == TypePtr::NULL_PTR) { - PointsToNode *ptn = ptnode_adr(phi->_idx); - ptn->set_node_type(PointsToNode::LocalVar); - ptn->_node = n; - _deferred.push(n); - } - } - } -} - -void ConnectionGraph::record_escape_work(Node *n, PhaseTransform *phase) { - - int opc = n->Opcode(); - PointsToNode *ptadr = ptnode_adr(n->_idx); - +// Populate Connection Graph with Ideal nodes and create simple +// connection graph edges (do not need to check the node_type of inputs +// or to call PointsTo() to walk the connection graph). +void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) { if (_processed.test(n->_idx)) - return; + return; // No need to redefine node's state. - ptadr->_node = n; if (n->is_Call()) { - CallNode *call = n->as_Call(); - process_call_arguments(call, phase); + // Arguments to allocation and locking don't escape. + if (n->is_Allocate()) { + add_node(n, PointsToNode::JavaObject, PointsToNode::UnknownEscape, true); + record_for_optimizer(n); + } else if (n->is_Lock() || n->is_Unlock()) { + // Put Lock and Unlock nodes on IGVN worklist to process them during + // the first IGVN optimization when escape information is still available. + record_for_optimizer(n); + _processed.set(n->_idx); + } else { + // Have to process call's arguments first. + PointsToNode::NodeType nt = PointsToNode::UnknownType; + + // Check if a call returns an object. + const TypeTuple *r = n->as_Call()->tf()->range(); + if (r->cnt() > TypeFunc::Parms && + n->as_Call()->proj_out(TypeFunc::Parms) != NULL) { + // Note: use isa_ptr() instead of isa_oopptr() here because + // the _multianewarray functions return a TypeRawPtr. + if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) { + nt = PointsToNode::JavaObject; + } + } + add_node(n, nt, PointsToNode::UnknownEscape, false); + } return; } - switch (opc) { + // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because + // ThreadLocal has RawPrt type. + switch (n->Opcode()) { case Op_AddP: { - Node *base = skip_casts(n->in(AddPNode::Base)); - ptadr->set_node_type(PointsToNode::Field); - - // create a field edge to this node from everything adr could point to - VectorSet ptset(Thread::current()->resource_area()); - PointsTo(ptset, base, phase); - for( VectorSetI i(&ptset); i.test(); ++i ) { - uint pt = i.elem; - add_field_edge(pt, n->_idx, type_to_offset(phase->type(n))); - } + add_node(n, PointsToNode::Field, PointsToNode::UnknownEscape, false); break; } - case Op_Parm: + case Op_CastX2P: + { // "Unsafe" memory access. + add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); + break; + } + case Op_CastPP: + case Op_CheckCastPP: { - ProjNode *nproj = n->as_Proj(); - uint con = nproj->_con; - if (con < TypeFunc::Parms) - return; - const Type *t = nproj->in(0)->as_Start()->_domain->field_at(con); - if (t->isa_ptr() == NULL) - return; - ptadr->set_node_type(PointsToNode::JavaObject); - if (t->isa_oopptr() != NULL) { - set_escape_state(n->_idx, PointsToNode::ArgEscape); + add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); + int ti = n->in(1)->_idx; + PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + if (nt == PointsToNode::UnknownType) { + _delayed_worklist.push(n); // Process it later. + break; + } else if (nt == PointsToNode::JavaObject) { + add_pointsto_edge(n->_idx, ti); } else { - // this must be the incoming state of an OSR compile, we have to assume anything - // passed in globally escapes - assert(_compile->is_osr_compilation(), "bad argument type for non-osr compilation"); - set_escape_state(n->_idx, PointsToNode::GlobalEscape); + add_deferred_edge(n->_idx, ti); } _processed.set(n->_idx); break; } - case Op_Phi: - { - PhiNode *phi = n->as_Phi(); - if (phi->type()->isa_oopptr() == NULL) - return; // nothing to do if not an oop - ptadr->set_node_type(PointsToNode::LocalVar); - process_phi_escape(phi, phase); - break; - } - case Op_CreateEx: - { - // assume that all exception objects globally escape - ptadr->set_node_type(PointsToNode::JavaObject); - set_escape_state(n->_idx, PointsToNode::GlobalEscape); - _processed.set(n->_idx); - break; - } case Op_ConP: { - const Type *t = phase->type(n); - ptadr->set_node_type(PointsToNode::JavaObject); // assume all pointer constants globally escape except for null - if (t == TypePtr::NULL_PTR) - set_escape_state(n->_idx, PointsToNode::NoEscape); + PointsToNode::EscapeState es; + if (phase->type(n) == TypePtr::NULL_PTR) + es = PointsToNode::NoEscape; else - set_escape_state(n->_idx, PointsToNode::GlobalEscape); - _processed.set(n->_idx); + es = PointsToNode::GlobalEscape; + + add_node(n, PointsToNode::JavaObject, es, true); + break; + } + case Op_CreateEx: + { + // assume that all exception objects globally escape + add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); break; } case Op_LoadKlass: { - ptadr->set_node_type(PointsToNode::JavaObject); - set_escape_state(n->_idx, PointsToNode::GlobalEscape); - _processed.set(n->_idx); + add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true); break; } case Op_LoadP: { const Type *t = phase->type(n); - if (!t->isa_oopptr()) + if (t->isa_ptr() == NULL) { + _processed.set(n->_idx); return; - ptadr->set_node_type(PointsToNode::LocalVar); - set_escape_state(n->_idx, PointsToNode::UnknownEscape); + } + add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); + break; + } + case Op_Parm: + { + _processed.set(n->_idx); // No need to redefine it state. + uint con = n->as_Proj()->_con; + if (con < TypeFunc::Parms) + return; + const Type *t = n->in(0)->as_Start()->_domain->field_at(con); + if (t->isa_ptr() == NULL) + return; + // We have to assume all input parameters globally escape + // (Note: passing 'false' since _processed is already set). + add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, false); + break; + } + case Op_Phi: + { + if (n->as_Phi()->type()->isa_ptr() == NULL) { + // nothing to do if not an oop + _processed.set(n->_idx); + return; + } + add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); + uint i; + for (i = 1; i < n->req() ; i++) { + Node* in = n->in(i); + if (in == NULL) + continue; // ignore NULL + in = in->uncast(); + if (in->is_top() || in == n) + continue; // ignore top or inputs which go back this node + int ti = in->_idx; + PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + if (nt == PointsToNode::UnknownType) { + break; + } else if (nt == PointsToNode::JavaObject) { + add_pointsto_edge(n->_idx, ti); + } else { + add_deferred_edge(n->_idx, ti); + } + } + if (i >= n->req()) + _processed.set(n->_idx); + else + _delayed_worklist.push(n); + break; + } + case Op_Proj: + { + // we are only interested in the result projection from a call + if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) { + add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); + process_call_result(n->as_Proj(), phase); + if (!_processed.test(n->_idx)) { + // The call's result may need to be processed later if the call + // returns it's argument and the argument is not processed yet. + _delayed_worklist.push(n); + } + } else { + _processed.set(n->_idx); + } + break; + } + case Op_Return: + { + if( n->req() > TypeFunc::Parms && + phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) { + // Treat Return value as LocalVar with GlobalEscape escape state. + add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false); + int ti = n->in(TypeFunc::Parms)->_idx; + PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); + if (nt == PointsToNode::UnknownType) { + _delayed_worklist.push(n); // Process it later. + break; + } else if (nt == PointsToNode::JavaObject) { + add_pointsto_edge(n->_idx, ti); + } else { + add_deferred_edge(n->_idx, ti); + } + } + _processed.set(n->_idx); + break; + } + case Op_StoreP: + { + const Type *adr_type = phase->type(n->in(MemNode::Address)); + if (adr_type->isa_oopptr()) { + add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false); + } else { + Node* adr = n->in(MemNode::Address); + if (adr->is_AddP() && phase->type(adr) == TypeRawPtr::NOTNULL && + adr->in(AddPNode::Address)->is_Proj() && + adr->in(AddPNode::Address)->in(0)->is_Allocate()) { + add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false); + // We are computing a raw address for a store captured + // by an Initialize compute an appropriate address type. + int offs = (int)phase->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot); + assert(offs != Type::OffsetBot, "offset must be a constant"); + } else { + _processed.set(n->_idx); + return; + } + } + break; + } + case Op_StorePConditional: + case Op_CompareAndSwapP: + { + const Type *adr_type = phase->type(n->in(MemNode::Address)); + if (adr_type->isa_oopptr()) { + add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false); + } else { + _processed.set(n->_idx); + return; + } + break; + } + case Op_ThreadLocal: + { + add_node(n, PointsToNode::JavaObject, PointsToNode::ArgEscape, true); + break; + } + default: + ; + // nothing to do + } + return; +} - Node *adr = skip_casts(n->in(MemNode::Address)); - const Type *adr_type = phase->type(adr); - Node *adr_base = skip_casts((adr->Opcode() == Op_AddP) ? adr->in(AddPNode::Base) : adr); +void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { + // Don't set processed bit for AddP, LoadP, StoreP since + // they may need more then one pass to process. + if (_processed.test(n->_idx)) + return; // No need to redefine node's state. - // For everything "adr" could point to, create a deferred edge from - // this node to each field with the same offset as "adr_type" + PointsToNode *ptadr = ptnode_adr(n->_idx); + + if (n->is_Call()) { + CallNode *call = n->as_Call(); + process_call_arguments(call, phase); + _processed.set(n->_idx); + return; + } + + switch (n->Opcode()) { + case Op_AddP: + { + Node *base = get_addp_base(n); + // Create a field edge to this node from everything base could point to. VectorSet ptset(Thread::current()->resource_area()); - PointsTo(ptset, adr_base, phase); - // If ptset is empty, then this value must have been set outside - // this method, so we add the phantom node - if (ptset.Size() == 0) - ptset.set(_phantom_object); + PointsTo(ptset, base, phase); for( VectorSetI i(&ptset); i.test(); ++i ) { uint pt = i.elem; - add_deferred_edge_to_fields(n->_idx, pt, type_to_offset(adr_type)); + add_field_edge(pt, n->_idx, address_offset(n, phase)); } break; } + case Op_CastX2P: + { + assert(false, "Op_CastX2P"); + break; + } + case Op_CastPP: + case Op_CheckCastPP: + { + int ti = n->in(1)->_idx; + if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n->_idx, ti); + } else { + add_deferred_edge(n->_idx, ti); + } + _processed.set(n->_idx); + break; + } + case Op_ConP: + { + assert(false, "Op_ConP"); + break; + } + case Op_CreateEx: + { + assert(false, "Op_CreateEx"); + break; + } + case Op_LoadKlass: + { + assert(false, "Op_LoadKlass"); + break; + } + case Op_LoadP: + { + const Type *t = phase->type(n); +#ifdef ASSERT + if (t->isa_ptr() == NULL) + assert(false, "Op_LoadP"); +#endif + + Node* adr = n->in(MemNode::Address)->uncast(); + const Type *adr_type = phase->type(adr); + Node* adr_base; + if (adr->is_AddP()) { + adr_base = get_addp_base(adr); + } else { + adr_base = adr; + } + + // For everything "adr_base" could point to, create a deferred edge from + // this node to each field with the same offset. + VectorSet ptset(Thread::current()->resource_area()); + PointsTo(ptset, adr_base, phase); + int offset = address_offset(adr, phase); + for( VectorSetI i(&ptset); i.test(); ++i ) { + uint pt = i.elem; + add_deferred_edge_to_fields(n->_idx, pt, offset); + } + break; + } + case Op_Parm: + { + assert(false, "Op_Parm"); + break; + } + case Op_Phi: + { +#ifdef ASSERT + if (n->as_Phi()->type()->isa_ptr() == NULL) + assert(false, "Op_Phi"); +#endif + for (uint i = 1; i < n->req() ; i++) { + Node* in = n->in(i); + if (in == NULL) + continue; // ignore NULL + in = in->uncast(); + if (in->is_top() || in == n) + continue; // ignore top or inputs which go back this node + int ti = in->_idx; + if (_nodes->adr_at(in->_idx)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n->_idx, ti); + } else { + add_deferred_edge(n->_idx, ti); + } + } + _processed.set(n->_idx); + break; + } + case Op_Proj: + { + // we are only interested in the result projection from a call + if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) { + process_call_result(n->as_Proj(), phase); + assert(_processed.test(n->_idx), "all call results should be processed"); + } else { + assert(false, "Op_Proj"); + } + break; + } + case Op_Return: + { +#ifdef ASSERT + if( n->req() <= TypeFunc::Parms || + !phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) { + assert(false, "Op_Return"); + } +#endif + int ti = n->in(TypeFunc::Parms)->_idx; + if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { + add_pointsto_edge(n->_idx, ti); + } else { + add_deferred_edge(n->_idx, ti); + } + _processed.set(n->_idx); + break; + } case Op_StoreP: case Op_StorePConditional: case Op_CompareAndSwapP: { Node *adr = n->in(MemNode::Address); - Node *val = skip_casts(n->in(MemNode::ValueIn)); const Type *adr_type = phase->type(adr); +#ifdef ASSERT if (!adr_type->isa_oopptr()) - return; + assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP"); +#endif - assert(adr->Opcode() == Op_AddP, "expecting an AddP"); - Node *adr_base = adr->in(AddPNode::Base); - - // For everything "adr_base" could point to, create a deferred edge to "val" from each field - // with the same offset as "adr_type" + assert(adr->is_AddP(), "expecting an AddP"); + Node *adr_base = get_addp_base(adr); + Node *val = n->in(MemNode::ValueIn)->uncast(); + // For everything "adr_base" could point to, create a deferred edge + // to "val" from each field with the same offset. VectorSet ptset(Thread::current()->resource_area()); PointsTo(ptset, adr_base, phase); for( VectorSetI i(&ptset); i.test(); ++i ) { uint pt = i.elem; - add_edge_from_fields(pt, val->_idx, type_to_offset(adr_type)); + add_edge_from_fields(pt, val->_idx, address_offset(adr, phase)); } break; } - case Op_Proj: + case Op_ThreadLocal: { - ProjNode *nproj = n->as_Proj(); - Node *n0 = nproj->in(0); - // we are only interested in the result projection from a call - if (nproj->_con == TypeFunc::Parms && n0->is_Call() ) { - process_call_result(nproj, phase); - } - - break; - } - case Op_CastPP: - case Op_CheckCastPP: - { - ptadr->set_node_type(PointsToNode::LocalVar); - int ti = n->in(1)->_idx; - if (_nodes->at(ti).node_type() == PointsToNode::JavaObject) { - add_pointsto_edge(n->_idx, ti); - } else { - add_deferred_edge(n->_idx, ti); - } + assert(false, "Op_ThreadLocal"); break; } default: @@ -1341,34 +2052,48 @@ void ConnectionGraph::record_escape_work(Node *n, PhaseTransform *phase) { } } -void ConnectionGraph::record_escape(Node *n, PhaseTransform *phase) { - if (_collecting) - record_escape_work(n, phase); -} - #ifndef PRODUCT void ConnectionGraph::dump() { PhaseGVN *igvn = _compile->initial_gvn(); bool first = true; - for (uint ni = 0; ni < (uint)_nodes->length(); ni++) { - PointsToNode *esp = _nodes->adr_at(ni); - if (esp->node_type() == PointsToNode::UnknownType || esp->_node == NULL) + uint size = (uint)_nodes->length(); + for (uint ni = 0; ni < size; ni++) { + PointsToNode *ptn = _nodes->adr_at(ni); + PointsToNode::NodeType ptn_type = ptn->node_type(); + + if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL) continue; - PointsToNode::EscapeState es = escape_state(esp->_node, igvn); - if (es == PointsToNode::NoEscape || (Verbose && - (es != PointsToNode::UnknownEscape || esp->edge_count() != 0))) { - // don't print null pointer node which almost every method has - if (esp->_node->Opcode() != Op_ConP || igvn->type(esp->_node) != TypePtr::NULL_PTR) { - if (first) { - tty->print("======== Connection graph for "); - C()->method()->print_short_name(); - tty->cr(); - first = false; - } - tty->print("%4d ", ni); - esp->dump(); + PointsToNode::EscapeState es = escape_state(ptn->_node, igvn); + if (ptn->_node->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) { + if (first) { + tty->cr(); + tty->print("======== Connection graph for "); + C()->method()->print_short_name(); + tty->cr(); + first = false; } + tty->print("%6d ", ni); + ptn->dump(); + // Print all locals which reference this allocation + for (uint li = ni; li < size; li++) { + PointsToNode *ptn_loc = _nodes->adr_at(li); + PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type(); + if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL && + ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) { + tty->print("%6d LocalVar [[%d]]", li, ni); + _nodes->adr_at(li)->_node->dump(); + } + } + if (Verbose) { + // Print all fields which reference this allocation + for (uint i = 0; i < ptn->edge_count(); i++) { + uint ei = ptn->edge_target(i); + tty->print("%6d Field [[%d]]", ei, ni); + _nodes->adr_at(ei)->_node->dump(); + } + } + tty->cr(); } } } diff --git a/hotspot/src/share/vm/opto/escape.hpp b/hotspot/src/share/vm/opto/escape.hpp index 3cd879257e7..a7552b2c3ae 100644 --- a/hotspot/src/share/vm/opto/escape.hpp +++ b/hotspot/src/share/vm/opto/escape.hpp @@ -25,14 +25,15 @@ // // Adaptation for C2 of the escape analysis algorithm described in: // -// [Choi99] Jong-Deok Shoi, Manish Gupta, Mauricio Seffano, Vugranam C. Sreedhar, -// Sam Midkiff, "Escape Analysis for Java", Procedings of ACM SIGPLAN -// OOPSLA Conference, November 1, 1999 +// [Choi99] Jong-Deok Shoi, Manish Gupta, Mauricio Seffano, +// Vugranam C. Sreedhar, Sam Midkiff, +// "Escape Analysis for Java", Procedings of ACM SIGPLAN +// OOPSLA Conference, November 1, 1999 // // The flow-insensitive analysis described in the paper has been implemented. // -// The analysis requires construction of a "connection graph" (CG) for the method being -// analyzed. The nodes of the connection graph are: +// The analysis requires construction of a "connection graph" (CG) for +// the method being analyzed. The nodes of the connection graph are: // // - Java objects (JO) // - Local variables (LV) @@ -40,47 +41,51 @@ // // The CG contains 3 types of edges: // -// - PointsTo (-P>) {LV,OF} to JO -// - Deferred (-D>) from {LV, OF} to {LV, OF} +// - PointsTo (-P>) {LV, OF} to JO +// - Deferred (-D>) from {LV, OF} to {LV, OF} // - Field (-F>) from JO to OF // // The following utility functions is used by the algorithm: // -// PointsTo(n) - n is any CG node, it returns the set of JO that n could -// point to. +// PointsTo(n) - n is any CG node, it returns the set of JO that n could +// point to. // -// The algorithm describes how to construct the connection graph in the following 4 cases: +// The algorithm describes how to construct the connection graph +// in the following 4 cases: // // Case Edges Created // -// (1) p = new T() LV -P> JO -// (2) p = q LV -D> LV -// (3) p.f = q JO -F> OF, OF -D> LV -// (4) p = q.f JO -F> OF, LV -D> OF +// (1) p = new T() LV -P> JO +// (2) p = q LV -D> LV +// (3) p.f = q JO -F> OF, OF -D> LV +// (4) p = q.f JO -F> OF, LV -D> OF // -// In all these cases, p and q are local variables. For static field references, we can -// construct a local variable containing a reference to the static memory. +// In all these cases, p and q are local variables. For static field +// references, we can construct a local variable containing a reference +// to the static memory. // // C2 does not have local variables. However for the purposes of constructing // the connection graph, the following IR nodes are treated as local variables: // Phi (pointer values) // LoadP -// Proj (value returned from callnodes including allocations) -// CheckCastPP +// Proj#5 (value returned from callnodes including allocations) +// CheckCastPP, CastPP // -// The LoadP, Proj and CheckCastPP behave like variables assigned to only once. Only -// a Phi can have multiple assignments. Each input to a Phi is treated +// The LoadP, Proj and CheckCastPP behave like variables assigned to only once. +// Only a Phi can have multiple assignments. Each input to a Phi is treated // as an assignment to it. // -// The following note types are JavaObject: +// The following node types are JavaObject: // // top() // Allocate // AllocateArray // Parm (for incoming arguments) +// CastX2P ("unsafe" operations) // CreateEx // ConP // LoadKlass +// ThreadLocal // // AddP nodes are fields. // @@ -89,7 +94,7 @@ // source. This results in a graph with no deferred edges, only: // // LV -P> JO -// OF -P> JO +// OF -P> JO (the object whose oop is stored in the field) // JO -F> OF // // Then, for each node which is GlobalEscape, anything it could point to @@ -110,17 +115,18 @@ class PointsToNode { friend class ConnectionGraph; public: typedef enum { - UnknownType = 0, - JavaObject = 1, - LocalVar = 2, - Field = 3 + UnknownType = 0, + JavaObject = 1, + LocalVar = 2, + Field = 3 } NodeType; typedef enum { UnknownEscape = 0, - NoEscape = 1, - ArgEscape = 2, - GlobalEscape = 3 + NoEscape = 1, // A scalar replaceable object with unique type. + ArgEscape = 2, // An object passed as argument or referenced by + // argument (and not globally escape during call). + GlobalEscape = 3 // An object escapes the method and thread. } EscapeState; typedef enum { @@ -140,18 +146,24 @@ private: NodeType _type; EscapeState _escape; - GrowableArray* _edges; // outgoing edges - int _offset; // for fields + GrowableArray* _edges; // outgoing edges - bool _unique_type; // For allocated objects, this node may be a unique type public: - Node* _node; // Ideal node corresponding to this PointsTo node - int _inputs_processed; // the number of Phi inputs that have been processed so far - bool _hidden_alias; // this node is an argument to a function which may return it - // creating a hidden alias + Node* _node; // Ideal node corresponding to this PointsTo node. + int _offset; // Object fields offsets. + bool _scalar_replaceable;// Not escaped object could be replaced with scalar + bool _hidden_alias; // This node is an argument to a function. + // which may return it creating a hidden alias. + PointsToNode(): + _type(UnknownType), + _escape(UnknownEscape), + _edges(NULL), + _node(NULL), + _offset(-1), + _scalar_replaceable(true), + _hidden_alias(false) {} - PointsToNode(): _offset(-1), _type(UnknownType), _escape(UnknownEscape), _edges(NULL), _node(NULL), _inputs_processed(0), _hidden_alias(false), _unique_type(true) {} EscapeState escape_state() const { return _escape; } NodeType node_type() const { return _type;} @@ -182,22 +194,28 @@ public: class ConnectionGraph: public ResourceObj { private: - enum { - INITIAL_NODE_COUNT = 100 // initial size of _nodes array - }; + GrowableArray* _nodes; // Connection graph nodes indexed + // by ideal node index. + Unique_Node_List _delayed_worklist; // Nodes to be processed before + // the call build_connection_graph(). - GrowableArray* _nodes; // connection graph nodes Indexed by ideal - // node index - Unique_Node_List _deferred; // Phi's to be processed after parsing - VectorSet _processed; // records which nodes have been processed - bool _collecting; // indicates whether escape information is - // still being collected. If false, no new - // nodes will be processed - uint _phantom_object; // index of globally escaping object that - // pointer values loaded from a field which - // has not been set are assumed to point to - Compile * _compile; // Compile object for current compilation + VectorSet _processed; // Records which nodes have been + // processed. + + bool _collecting; // Indicates whether escape information + // is still being collected. If false, + // no new nodes will be processed. + + bool _has_allocations; // Indicates whether method has any + // non-escaping allocations. + + uint _phantom_object; // Index of globally escaping object + // that pointer values loaded from + // a field which has not been set + // are assumed to point to. + + Compile * _compile; // Compile object for current compilation // address of an element in _nodes. Used when the element is to be modified PointsToNode *ptnode_adr(uint idx) { @@ -208,8 +226,11 @@ private: return _nodes->adr_at(idx); } + // Add node to ConnectionGraph. + void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done); + // offset of a field reference - int type_to_offset(const Type *t); + int address_offset(Node* adr, PhaseTransform *phase); // compute the escape state for arguments to a call void process_call_arguments(CallNode *call, PhaseTransform *phase); @@ -217,12 +238,11 @@ private: // compute the escape state for the return value of a call void process_call_result(ProjNode *resproj, PhaseTransform *phase); - // compute the escape state of a Phi. This may be called multiple - // times as new inputs are added to the Phi. - void process_phi_escape(PhiNode *phi, PhaseTransform *phase); + // Populate Connection Graph with Ideal nodes. + void record_for_escape_analysis(Node *n, PhaseTransform *phase); - // compute the escape state of an ideal node. - void record_escape_work(Node *n, PhaseTransform *phase); + // Build Connection Graph and set nodes escape state. + void build_connection_graph(Node *n, PhaseTransform *phase); // walk the connection graph starting at the node corresponding to "n" and // add the index of everything it could point to, to "ptset". This may cause @@ -241,8 +261,8 @@ private: // a pointsto edge is added if it is a JavaObject void add_edge_from_fields(uint adr, uint to_i, int offs); - // Add a deferred edge from node given by "from_i" to any field of adr_i whose offset - // matches "offset" + // Add a deferred edge from node given by "from_i" to any field + // of adr_i whose offset matches "offset" void add_deferred_edge_to_fields(uint from_i, uint adr, int offs); @@ -262,6 +282,8 @@ private: PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, PhaseGVN *igvn, bool &new_created); PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, PhaseGVN *igvn); Node *find_mem(Node *mem, int alias_idx, PhaseGVN *igvn); + Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray &orig_phi_worklist, PhaseGVN *igvn); + // Propagate unique types created for unescaped allocated objects // through the graph void split_unique_types(GrowableArray &alloc_worklist); @@ -285,26 +307,24 @@ private: // Set the escape state of a node void set_escape_state(uint ni, PointsToNode::EscapeState es); - // bypass any casts and return the node they refer to - Node * skip_casts(Node *n); - // Get Compile object for current compilation. Compile *C() const { return _compile; } public: ConnectionGraph(Compile *C); - // record a Phi for later processing. - void record_for_escape_analysis(Node *n); - - // process a node and fill in its connection graph node - void record_escape(Node *n, PhaseTransform *phase); - - // All nodes have been recorded, compute the escape information + // Compute the escape information void compute_escape(); // escape state of a node PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase); + // other information we have collected + bool is_scalar_replaceable(Node *n) { + if (_collecting) + return false; + PointsToNode ptn = _nodes->at_grow(n->_idx); + return ptn.escape_state() == PointsToNode::NoEscape && ptn._scalar_replaceable; + } bool hidden_alias(Node *n) { if (_collecting) diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp index f361ef8b888..63606340527 100644 --- a/hotspot/src/share/vm/opto/node.cpp +++ b/hotspot/src/share/vm/opto/node.cpp @@ -812,8 +812,7 @@ int Node::disconnect_inputs(Node *n) { Node* Node::uncast() const { // Should be inline: //return is_ConstraintCast() ? uncast_helper(this) : (Node*) this; - if (is_ConstraintCast() || - (is_Type() && req() == 2 && Opcode() == Op_CheckCastPP)) + if (is_ConstraintCast() || is_CheckCastPP()) return uncast_helper(this); else return (Node*) this; @@ -827,7 +826,7 @@ Node* Node::uncast_helper(const Node* p) { break; } else if (p->is_ConstraintCast()) { p = p->in(1); - } else if (p->is_Type() && p->Opcode() == Op_CheckCastPP) { + } else if (p->is_CheckCastPP()) { p = p->in(1); } else { break; diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index ac35f9b4f1b..6dbd2a4cd30 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -1328,7 +1328,6 @@ public: // Inline definition of Compile::record_for_igvn must be deferred to this point. inline void Compile::record_for_igvn(Node* n) { _for_igvn->push(n); - record_for_escape_analysis(n); } //------------------------------Node_Stack------------------------------------- diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp index 90b34d4afad..f462fe7d230 100644 --- a/hotspot/src/share/vm/opto/phaseX.cpp +++ b/hotspot/src/share/vm/opto/phaseX.cpp @@ -587,11 +587,6 @@ ConNode* PhaseValues::uncached_makecon(const Type *t) { Node_Notes* loc = C->locate_node_notes(nna, x->_idx, true); loc->clear(); // do not put debug info on constants } - // Collect points-to information for escape analysys - ConnectionGraph *cgr = C->congraph(); - if (cgr != NULL) { - cgr->record_escape(x, this); - } } else { x->destruct(); // Hit, destroy duplicate constant x = k; // use existing constant @@ -714,12 +709,6 @@ Node *PhaseGVN::transform_no_reclaim( Node *n ) { return i; } - // Collect points-to information for escape analysys - ConnectionGraph *cgr = C->congraph(); - if (cgr != NULL) { - cgr->record_escape(k, this); - } - // Return Idealized original return k; } @@ -1245,7 +1234,7 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) { uint use_op = use->Opcode(); // If changed Cast input, check Phi users for simple cycles - if( use->is_ConstraintCast() || use->Opcode() == Op_CheckCastPP ) { + if( use->is_ConstraintCast() || use->is_CheckCastPP() ) { for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) { Node* u = use->fast_out(i2); if (u->is_Phi()) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index ccb60b7cb4b..991ed66233a 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1276,6 +1276,9 @@ void Arguments::set_aggressive_opts_flags() { sprintf(buffer, "java.lang.Integer.IntegerCache.high=%d", AutoBoxCacheMax); add_property(buffer); } + if (AggressiveOpts && FLAG_IS_DEFAULT(DoEscapeAnalysis)) { + FLAG_SET_DEFAULT(DoEscapeAnalysis, true); + } #endif if (AggressiveOpts) { From 2f36d025cab284c2e4e5ed35c35756065de60aaf Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 14 Mar 2008 16:09:30 -0700 Subject: [PATCH 167/274] 6638501: Regression with Javac in JDK6 U4 b03? Replace some String paths with File paths in Paths.java Reviewed-by: ksrini --- .../com/sun/tools/javac/util/Paths.java | 22 +- .../6638501/HelloLib/test/HelloImpl.java | 32 +++ .../Paths/6638501/JarFromManifestFailure.java | 169 ++++++++++++++++ .../javac/Paths/6638501/WsCompileExample.java | 189 ++++++++++++++++++ .../javac/Paths/6638501/test/SayHello.java | 31 +++ .../Paths/6638501/test1/SayHelloToo.java | 31 +++ 6 files changed, 462 insertions(+), 12 deletions(-) create mode 100644 langtools/test/tools/javac/Paths/6638501/HelloLib/test/HelloImpl.java create mode 100644 langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java create mode 100644 langtools/test/tools/javac/Paths/6638501/WsCompileExample.java create mode 100644 langtools/test/tools/javac/Paths/6638501/test/SayHello.java create mode 100644 langtools/test/tools/javac/Paths/6638501/test1/SayHelloToo.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Paths.java b/langtools/src/share/classes/com/sun/tools/javac/util/Paths.java index 073ce5bd6a9..a28bfa26582 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Paths.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Paths.java @@ -38,13 +38,8 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.Iterator; import java.util.StringTokenizer; -import java.util.zip.ZipException; import java.util.zip.ZipFile; import com.sun.tools.javac.code.Lint; -import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Log; -import com.sun.tools.javac.util.Options; -import com.sun.tools.javac.util.Position; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; @@ -70,7 +65,10 @@ public class Paths { protected static final Context.Key pathsKey = new Context.Key(); - /** Get the Paths instance for this context. */ + /** Get the Paths instance for this context. + * @param context the context + * @return the Paths instance for this context + */ public static Paths instance(Context context) { Paths instance = context.get(pathsKey); if (instance == null) @@ -89,7 +87,7 @@ public class Paths { private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. private static Map pathExistanceCache = new ConcurrentHashMap(); - private static Map> manifestEntries = new ConcurrentHashMap>(); + private static Map> manifestEntries = new ConcurrentHashMap>(); private static Map isDirectory = new ConcurrentHashMap(); private static Lock lock = new ReentrantLock(); @@ -369,13 +367,13 @@ public class Paths { // filenames, but if we do, we should redo all path-related code. private void addJarClassPath(File jarFile, boolean warn) { try { - java.util.List manifestsList = manifestEntries.get(jarFile); + java.util.List manifestsList = manifestEntries.get(jarFile); if (!NON_BATCH_MODE) { lock.lock(); try { if (manifestsList != null) { - for (String entr : manifestsList) { - addFile(new File(entr), warn); + for (File entr : manifestsList) { + addFile(entr, warn); } return; } @@ -386,7 +384,7 @@ public class Paths { } if (!NON_BATCH_MODE) { - manifestsList = new ArrayList(); + manifestsList = new ArrayList(); manifestEntries.put(jarFile, manifestsList); } @@ -412,7 +410,7 @@ public class Paths { if (!NON_BATCH_MODE) { lock.lock(); try { - manifestsList.add(elt); + manifestsList.add(f); } finally { lock.unlock(); diff --git a/langtools/test/tools/javac/Paths/6638501/HelloLib/test/HelloImpl.java b/langtools/test/tools/javac/Paths/6638501/HelloLib/test/HelloImpl.java new file mode 100644 index 00000000000..7f5a934e601 --- /dev/null +++ b/langtools/test/tools/javac/Paths/6638501/HelloLib/test/HelloImpl.java @@ -0,0 +1,32 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. + */ + +package test; + +public class HelloImpl { + + public void Hello() { + java.lang.System.out.println("Hello"); + } + +} diff --git a/langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java b/langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java new file mode 100644 index 00000000000..a82cbb017ab --- /dev/null +++ b/langtools/test/tools/javac/Paths/6638501/JarFromManifestFailure.java @@ -0,0 +1,169 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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 6638501 + * @summary REGRESSION: Java Compiler cannot find jar files referenced by other + * @run main JarFromManifestFailure + */ + +import java.io.*; +import java.nio.*; +import java.util.*; +import java.util.jar.*; +import javax.tools.*; +import javax.tools.StandardJavaFileManager.*; + +public class JarFromManifestFailure { + static File testSrc = new File(System.getProperty("test.src", ".")); + static File testClasses = new File(System.getProperty("test.classes", ".")); + + public static void main(String... args) throws Exception { + compile(testClasses, null, new File(testSrc, "HelloLib/test/HelloImpl.java"), new File(testSrc, "WsCompileExample.java")); + File libFile = new File(testClasses, "lib"); + libFile.mkdir(); + jar(new File(libFile, "HelloLib.jar"), new ArrayList(), testClasses, new File("test")); + + ArrayList arList = new ArrayList(); + arList.add(new File("HelloLib.jar")); + jar(new File(libFile, "JarPointer.jar"), arList, testClasses); + + String[] args1 = { + "-d", ".", + "-cp", new File(libFile, "JarPointer.jar").getPath().replace('\\', '/'), + new File(testSrc, "test/SayHello.java").getPath().replace('\\', '/') + }; + System.err.println("First compile!!!"); + if (com.sun.tools.javac.Main.compile(args1) != 0) { + throw new AssertionError("Failure in first compile!"); + } + + System.err.println("Second compile!!!"); + + args1 = new String[] { + "-d", ".", + "-cp", new File(libFile, "JarPointer.jar").getPath().replace('\\', '/'), + new File(testSrc, "test1/SayHelloToo.java").getPath().replace('\\', '/') + }; + if (com.sun.tools.javac.Main.compile(args1) != 0) { + throw new AssertionError("Failure in second compile!"); + } + } + + static void compile(File classOutDir, Iterable classPath, File... files) { + System.err.println("compile..."); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); + Iterable fileObjects = + fm.getJavaFileObjectsFromFiles(Arrays.asList(files)); + + List options = new ArrayList(); + if (classOutDir != null) { + options.add("-d"); + options.add(classOutDir.getPath()); + } + if (classPath != null) { + options.add("-classpath"); + options.add(join(classPath, File.pathSeparator)); + } + options.add("-verbose"); + + JavaCompiler.CompilationTask task = + compiler.getTask(null, fm, null, options, null, fileObjects); + if (!task.call()) + throw new AssertionError("compilation failed"); + } + + static void jar(File jar, Iterable classPath, File base, File... files) + throws IOException { + System.err.println("jar..."); + Manifest m = new Manifest(); + if (classPath != null) { + Attributes mainAttrs = m.getMainAttributes(); + mainAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); + mainAttrs.put(Attributes.Name.CLASS_PATH, join(classPath, " ")); + } + OutputStream out = new BufferedOutputStream(new FileOutputStream(jar)); + JarOutputStream j = new JarOutputStream(out, m); + add(j, base, files); + j.close(); + } + + static void add(JarOutputStream j, File base, File... files) throws IOException { + if (files == null) + return; + + for (File f: files) + add(j, base, f); + } + + static void add(JarOutputStream j, File base, File file) throws IOException { + File f = new File(base, file.getPath()); + if (f.isDirectory()) { + JarEntry e = new JarEntry(new String(file.getPath() + File.separator).replace('\\', '/')); + e.setSize(file.length()); + j.putNextEntry(e); + String[] children = f.list(); + if (children != null) { + for (String c: children) { + add(j, base, new File(file, c)); + } + } + } else { + JarEntry e = new JarEntry(file.getPath().replace('\\', '/')); + e.setSize(f.length()); + j.putNextEntry(e); + j.write(read(f)); + j.closeEntry(); + } + + } + + static byte[] read(File f) throws IOException { + byte[] buf = new byte[(int) f.length()]; + BufferedInputStream in = new BufferedInputStream(new FileInputStream(f)); + int offset = 0; + while (offset < buf.length) { + int n = in.read(buf, offset, buf.length - offset); + if (n < 0) + throw new EOFException(); + offset += n; + } + return buf; + } + + static Iterable iterable(T single) { + return Collections.singleton(single); + } + + static String join(Iterable iter, String sep) { + StringBuilder p = new StringBuilder(); + for (T t: iter) { + if (p.length() > 0) + p.append(' '); + p.append(t); + } + return p.toString(); + } +} diff --git a/langtools/test/tools/javac/Paths/6638501/WsCompileExample.java b/langtools/test/tools/javac/Paths/6638501/WsCompileExample.java new file mode 100644 index 00000000000..3884af9588c --- /dev/null +++ b/langtools/test/tools/javac/Paths/6638501/WsCompileExample.java @@ -0,0 +1,189 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. + */ + +import java.util.List; +import java.util.ArrayList; +import java.io.File; +//for CompilerHelper +import java.io.OutputStream; +import java.io.PrintWriter; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + + + +public class WsCompileExample { + File destDir; + File srcDir; + protected boolean compilerDebug = false; + protected boolean compilerOptimize = false; + protected String userClasspath = null; + + public static void main(String[] args) { + new WsCompileExample().do_main(args); + } + + public void do_main(String[] args) { + if(!args[0].equals("-s")) { + throw new RuntimeException("specify -s for src"); + } + + //run it once + srcDir = new File(args[1]); + if(!args[2].equals("-d")) { + throw new RuntimeException("specify -d for dest"); + } + destDir = new File(args[3]); + if(!destDir.exists()) + destDir.mkdirs(); + System.out.println("----test compile 1-----"); + compileGeneratedClasses(); + + //run it twice + srcDir = new File(args[1]+"1"); + destDir = new File(args[3]+"1"); + if(!destDir.exists()) + destDir.mkdirs(); + System.out.println("----test compile 2-----"); + compileGeneratedClasses(); + + } + protected void compileGeneratedClasses() { + List sourceFiles = new ArrayList(); + + for (File f: srcDir.listFiles()) { + if (f.getName().endsWith(".java")) { + sourceFiles.add(f.getAbsolutePath()); + } + } + + if (sourceFiles.size() > 0) { + String classDir = destDir.getAbsolutePath(); + String classpathString = createClasspathString(); + System.out.println("classpathString: " + classpathString); + + String[] args = new String[4 + (compilerDebug == true ? 1 : 0) + + (compilerOptimize == true ? 1 : 0) + + sourceFiles.size()]; + args[0] = "-d"; + args[1] = classDir; + args[2] = "-classpath"; + args[3] = classpathString; +// args[4]="-DnonBatchMode"; + int baseIndex = 4; + if (compilerDebug) { + args[baseIndex++] = "-g"; + } + if (compilerOptimize) { + args[baseIndex++] = "-O"; + } + for (int i = 0; i < sourceFiles.size(); ++i) { + args[baseIndex + i] = (String)sourceFiles.get(i); + } + + // ByteArrayOutputStream javacOutput = new ByteArrayOutputStream(); + JavaCompilerHelper compilerHelper = new JavaCompilerHelper(System.out); + boolean result = compilerHelper.compile(args); + if (!result) { + System.out.println("wscompile.compilation Failed"); + } + } + } + + protected String createClasspathString() { + if (userClasspath == null) { + userClasspath = ""; + } + String jcp = userClasspath + File.pathSeparator + System.getProperty("java.class.path"); + return jcp; + } +} +/////////////////////////////////////////////////////////////////// +class JavaCompilerHelper { + public JavaCompilerHelper(OutputStream out) { + this.out = out; + } + + public boolean compile(String[] args) { + return internalCompile(args); + } + + protected boolean internalCompile(String[] args) { + + System.out.println("Args: "); + for(String arg : args){ + System.out.print(arg+" "); + } + System.out.println(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Class comSunToolsJavacMainClass = null; + try { + /* try to use the new compiler */ + comSunToolsJavacMainClass = + cl.loadClass("com.sun.tools.javac.Main"); + try { + Method compileMethod = + comSunToolsJavacMainClass.getMethod( + "compile", + compile141MethodSignature); + try { + Object result = + compileMethod.invoke( + null, + new Object[] { args, new PrintWriter(out)}); + if (!(result instanceof Integer)) { + return false; + } + return ((Integer) result).intValue() == 0; + } catch (IllegalAccessException e3) { + return false; + } catch (IllegalArgumentException e3) { + return false; + } catch (InvocationTargetException e3) { + return false; + } + } catch (NoSuchMethodException e2) { + System.out.println("ERROR: Compile failed with error:" + e2.toString() ); + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + return false; + } catch (SecurityException e) { + return false; + } + return true; + } + + protected String getGenericErrorMessage() {return "javacompiler.error"; } + protected void run() { } + protected boolean parseArguments(String[] args) {return false;} + protected OutputStream out; + + protected static final Class[] compile141MethodSignature; + static + { + compile141MethodSignature = new Class[2]; + compile141MethodSignature[0] = (new String[0]).getClass(); + compile141MethodSignature[1] = PrintWriter.class; + } +} diff --git a/langtools/test/tools/javac/Paths/6638501/test/SayHello.java b/langtools/test/tools/javac/Paths/6638501/test/SayHello.java new file mode 100644 index 00000000000..fa008b9db6d --- /dev/null +++ b/langtools/test/tools/javac/Paths/6638501/test/SayHello.java @@ -0,0 +1,31 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. + */ + +import test.HelloImpl; + +public class SayHello extends HelloImpl { + public static void main(String... args) { + new SayHello().Hello(); +} + +} diff --git a/langtools/test/tools/javac/Paths/6638501/test1/SayHelloToo.java b/langtools/test/tools/javac/Paths/6638501/test1/SayHelloToo.java new file mode 100644 index 00000000000..08fa024f550 --- /dev/null +++ b/langtools/test/tools/javac/Paths/6638501/test1/SayHelloToo.java @@ -0,0 +1,31 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. + */ + +import test.HelloImpl; + +public class SayHelloToo extends HelloImpl { + public static void main(String... args) { + new SayHelloToo().Hello(); +} + +} From 20046c1a187cad1a934bb3df58ea4ef686ec6d58 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 14 Mar 2008 16:40:42 -0700 Subject: [PATCH 168/274] 6672848: (Escape Analysis) improve lock elimination with EA Remove lock/unlock MemBar nodes and specify locks in debug info for deoptimization. Reviewed-by: never --- hotspot/src/share/vm/opto/callnode.cpp | 91 +++++++------------- hotspot/src/share/vm/opto/locknode.cpp | 3 +- hotspot/src/share/vm/opto/locknode.hpp | 5 ++ hotspot/src/share/vm/opto/macro.cpp | 111 +++++++++++++++++++------ hotspot/src/share/vm/opto/macro.hpp | 2 +- hotspot/src/share/vm/opto/output.cpp | 3 +- 6 files changed, 123 insertions(+), 92 deletions(-) diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp index 60a183def71..ce9d353b41b 100644 --- a/hotspot/src/share/vm/opto/callnode.cpp +++ b/hotspot/src/share/vm/opto/callnode.cpp @@ -1364,7 +1364,7 @@ void AbstractLockNode::set_eliminated() { //============================================================================= Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { - // perform any generic optimizations first + // perform any generic optimizations first (returns 'this' or NULL) Node *result = SafePointNode::Ideal(phase, can_reshape); // Now see if we can optimize away this lock. We don't actually @@ -1372,7 +1372,20 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { // prevents macro expansion from expanding the lock. Since we don't // modify the graph, the value returned from this function is the // one computed above. - if (EliminateLocks && !is_eliminated()) { + if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) { + // + // If we are locking an unescaped object, the lock/unlock is unnecessary + // + ConnectionGraph *cgr = Compile::current()->congraph(); + PointsToNode::EscapeState es = PointsToNode::GlobalEscape; + if (cgr != NULL) + es = cgr->escape_state(obj_node(), phase); + if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { + // Mark it eliminated to update any counters + this->set_eliminated(); + return result; + } + // // Try lock coarsening // @@ -1412,8 +1425,10 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { int unlocks = 0; for (int i = 0; i < lock_ops.length(); i++) { AbstractLockNode* lock = lock_ops.at(i); - if (lock->Opcode() == Op_Lock) locks++; - else unlocks++; + if (lock->Opcode() == Op_Lock) + locks++; + else + unlocks++; if (Verbose) { lock->dump(1); } @@ -1450,7 +1465,7 @@ uint UnlockNode::size_of() const { return sizeof(*this); } //============================================================================= Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { - // perform any generic optimizations first + // perform any generic optimizations first (returns 'this' or NULL) Node * result = SafePointNode::Ideal(phase, can_reshape); // Now see if we can optimize away this unlock. We don't actually @@ -1458,66 +1473,18 @@ Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { // prevents macro expansion from expanding the unlock. Since we don't // modify the graph, the value returned from this function is the // one computed above. - if (EliminateLocks && !is_eliminated()) { + // Escape state is defined after Parse phase. + if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) { // - // If we are unlocking an unescaped object, the lock/unlock is unnecessary - // We can eliminate them if there are no safepoints in the locked region. + // If we are unlocking an unescaped object, the lock/unlock is unnecessary. // ConnectionGraph *cgr = Compile::current()->congraph(); - if (cgr != NULL && cgr->escape_state(obj_node(), phase) == PointsToNode::NoEscape) { - GrowableArray lock_ops; - LockNode *lock = find_matching_lock(this); - if (lock != NULL) { - lock_ops.append(this); - lock_ops.append(lock); - // find other unlocks which pair with the lock we found and add them - // to the list - Node * box = box_node(); - - for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) { - Node *use = box->fast_out(i); - if (use->is_Unlock() && use != this) { - UnlockNode *unlock1 = use->as_Unlock(); - if (!unlock1->is_eliminated()) { - LockNode *lock1 = find_matching_lock(unlock1); - if (lock == lock1) - lock_ops.append(unlock1); - else if (lock1 == NULL) { - // we can't find a matching lock, we must assume the worst - lock_ops.trunc_to(0); - break; - } - } - } - } - if (lock_ops.length() > 0) { - - #ifndef PRODUCT - if (PrintEliminateLocks) { - int locks = 0; - int unlocks = 0; - for (int i = 0; i < lock_ops.length(); i++) { - AbstractLockNode* lock = lock_ops.at(i); - if (lock->Opcode() == Op_Lock) locks++; - else unlocks++; - if (Verbose) { - lock->dump(1); - } - } - tty->print_cr("***Eliminated %d unescaped unlocks and %d unescaped locks", unlocks, locks); - } - #endif - - // for each of the identified locks, mark them - // as eliminatable - for (int i = 0; i < lock_ops.length(); i++) { - AbstractLockNode* lock = lock_ops.at(i); - - // Mark it eliminated to update any counters - lock->set_eliminated(); - } - } - } + PointsToNode::EscapeState es = PointsToNode::GlobalEscape; + if (cgr != NULL) + es = cgr->escape_state(obj_node(), phase); + if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { + // Mark it eliminated to update any counters + this->set_eliminated(); } } return result; diff --git a/hotspot/src/share/vm/opto/locknode.cpp b/hotspot/src/share/vm/opto/locknode.cpp index 90da8efaa36..48bf9ebfefc 100644 --- a/hotspot/src/share/vm/opto/locknode.cpp +++ b/hotspot/src/share/vm/opto/locknode.cpp @@ -36,7 +36,8 @@ const RegMask &BoxLockNode::out_RegMask() const { uint BoxLockNode::size_of() const { return sizeof(*this); } -BoxLockNode::BoxLockNode( int slot ) : Node( Compile::current()->root() ), _slot(slot) { +BoxLockNode::BoxLockNode( int slot ) : Node( Compile::current()->root() ), + _slot(slot), _is_eliminated(false) { init_class_id(Class_BoxLock); init_flags(Flag_rematerialize); OptoReg::Name reg = OptoReg::stack2reg(_slot); diff --git a/hotspot/src/share/vm/opto/locknode.hpp b/hotspot/src/share/vm/opto/locknode.hpp index 6b1a8883ca4..e765a6c5d69 100644 --- a/hotspot/src/share/vm/opto/locknode.hpp +++ b/hotspot/src/share/vm/opto/locknode.hpp @@ -27,6 +27,7 @@ class BoxLockNode : public Node { public: const int _slot; RegMask _inmask; + bool _is_eliminated; // indicates this lock was safely eliminated BoxLockNode( int lock ); virtual int Opcode() const; @@ -42,6 +43,10 @@ public: static OptoReg::Name stack_slot(Node* box_node); + bool is_eliminated() { return _is_eliminated; } + // mark lock as eliminated. + void set_eliminated() { _is_eliminated = true; } + #ifndef PRODUCT virtual void format( PhaseRegAlloc *, outputStream *st ) const; virtual void dump_spec(outputStream *st) const { st->print(" Lock %d",_slot); } diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 4a8ffd1076f..014280aaa0a 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -828,43 +828,102 @@ void PhaseMacroExpand::expand_allocate_array(AllocateArrayNode *alloc) { // Note: The membar's associated with the lock/unlock are currently not // eliminated. This should be investigated as a future enhancement. // -void PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { - Node* mem = alock->in(TypeFunc::Memory); +bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { + + if (!alock->is_eliminated()) { + return false; + } + // Mark the box lock as eliminated if all correspondent locks are eliminated + // to construct correct debug info. + BoxLockNode* box = alock->box_node()->as_BoxLock(); + if (!box->is_eliminated()) { + bool eliminate = true; + for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) { + Node *lck = box->fast_out(i); + if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) { + eliminate = false; + break; + } + } + if (eliminate) + box->set_eliminated(); + } + + #ifndef PRODUCT + if (PrintEliminateLocks) { + if (alock->is_Lock()) { + tty->print_cr("++++ Eliminating: %d Lock", alock->_idx); + } else { + tty->print_cr("++++ Eliminating: %d Unlock", alock->_idx); + } + } + #endif + + Node* mem = alock->in(TypeFunc::Memory); + Node* ctrl = alock->in(TypeFunc::Control); + + extract_call_projections(alock); + // There are 2 projections from the lock. The lock node will + // be deleted when its last use is subsumed below. + assert(alock->outcnt() == 2 && + _fallthroughproj != NULL && + _memproj_fallthrough != NULL, + "Unexpected projections from Lock/Unlock"); + + Node* fallthroughproj = _fallthroughproj; + Node* memproj_fallthrough = _memproj_fallthrough; // The memory projection from a lock/unlock is RawMem // The input to a Lock is merged memory, so extract its RawMem input // (unless the MergeMem has been optimized away.) if (alock->is_Lock()) { - if (mem->is_MergeMem()) - mem = mem->as_MergeMem()->in(Compile::AliasIdxRaw); + // Seach for MemBarAcquire node and delete it also. + MemBarNode* membar = fallthroughproj->unique_ctrl_out()->as_MemBar(); + assert(membar != NULL && membar->Opcode() == Op_MemBarAcquire, ""); + Node* ctrlproj = membar->proj_out(TypeFunc::Control); + Node* memproj = membar->proj_out(TypeFunc::Memory); + _igvn.hash_delete(ctrlproj); + _igvn.subsume_node(ctrlproj, fallthroughproj); + _igvn.hash_delete(memproj); + _igvn.subsume_node(memproj, memproj_fallthrough); } - extract_call_projections(alock); - // There are 2 projections from the lock. The lock node will - // be deleted when its last use is subsumed below. - assert(alock->outcnt() == 2 && _fallthroughproj != NULL && - _memproj_fallthrough != NULL, "Unexpected projections from Lock/Unlock"); - _igvn.hash_delete(_fallthroughproj); - _igvn.subsume_node(_fallthroughproj, alock->in(TypeFunc::Control)); - _igvn.hash_delete(_memproj_fallthrough); - _igvn.subsume_node(_memproj_fallthrough, mem); - return; + // Seach for MemBarRelease node and delete it also. + if (alock->is_Unlock() && ctrl != NULL && ctrl->is_Proj() && + ctrl->in(0)->is_MemBar()) { + MemBarNode* membar = ctrl->in(0)->as_MemBar(); + assert(membar->Opcode() == Op_MemBarRelease && + mem->is_Proj() && membar == mem->in(0), ""); + _igvn.hash_delete(fallthroughproj); + _igvn.subsume_node(fallthroughproj, ctrl); + _igvn.hash_delete(memproj_fallthrough); + _igvn.subsume_node(memproj_fallthrough, mem); + fallthroughproj = ctrl; + memproj_fallthrough = mem; + ctrl = membar->in(TypeFunc::Control); + mem = membar->in(TypeFunc::Memory); + } + + _igvn.hash_delete(fallthroughproj); + _igvn.subsume_node(fallthroughproj, ctrl); + _igvn.hash_delete(memproj_fallthrough); + _igvn.subsume_node(memproj_fallthrough, mem); + return true; } //------------------------------expand_lock_node---------------------- void PhaseMacroExpand::expand_lock_node(LockNode *lock) { + if (eliminate_locking_node(lock)) { + return; + } + Node* ctrl = lock->in(TypeFunc::Control); Node* mem = lock->in(TypeFunc::Memory); Node* obj = lock->obj_node(); Node* box = lock->box_node(); - Node *flock = lock->fastlock_node(); - - if (lock->is_eliminated()) { - eliminate_locking_node(lock); - return; - } + Node* flock = lock->fastlock_node(); // Make the merge point Node *region = new (C, 3) RegionNode(3); @@ -913,17 +972,15 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) { //------------------------------expand_unlock_node---------------------- void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) { - Node *ctrl = unlock->in(TypeFunc::Control); + if (eliminate_locking_node(unlock)) { + return; + } + + Node* ctrl = unlock->in(TypeFunc::Control); Node* mem = unlock->in(TypeFunc::Memory); Node* obj = unlock->obj_node(); Node* box = unlock->box_node(); - - if (unlock->is_eliminated()) { - eliminate_locking_node(unlock); - return; - } - // No need for a null check on unlock // Make the merge point diff --git a/hotspot/src/share/vm/opto/macro.hpp b/hotspot/src/share/vm/opto/macro.hpp index 20dd65c40b7..a34094dbf00 100644 --- a/hotspot/src/share/vm/opto/macro.hpp +++ b/hotspot/src/share/vm/opto/macro.hpp @@ -78,7 +78,7 @@ private: Node* length, const TypeFunc* slow_call_type, address slow_call_address); - void eliminate_locking_node(AbstractLockNode *alock); + bool eliminate_locking_node(AbstractLockNode *alock); void expand_lock_node(LockNode *lock); void expand_unlock_node(UnlockNode *unlock); diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp index 3c06b135f9a..b1f2ca12155 100644 --- a/hotspot/src/share/vm/opto/output.cpp +++ b/hotspot/src/share/vm/opto/output.cpp @@ -882,7 +882,8 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { } OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node); - monarray->append(new MonitorValue(scval, Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg)))); + Location basic_lock = Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg)); + monarray->append(new MonitorValue(scval, basic_lock, box_node->as_BoxLock()->is_eliminated())); } // We dump the object pool first, since deoptimization reads it in first. From 5fc030e9d39499f81062d88b694b1ea122899cee Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Sat, 15 Mar 2008 13:43:05 -0400 Subject: [PATCH 169/274] 6648816: REGRESSION: setting -Djava.security.debug=failure result in NPE in ACC Unchecking the null pointer of the debug handle Reviewed-by: mullan, weijun --- .../java/security/AccessControlContext.java | 4 +- .../FailureDebugOption.java | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/security/AccessControlContext/FailureDebugOption.java diff --git a/jdk/src/share/classes/java/security/AccessControlContext.java b/jdk/src/share/classes/java/security/AccessControlContext.java index 601bc40ba56..0a9cfb85b5e 100644 --- a/jdk/src/share/classes/java/security/AccessControlContext.java +++ b/jdk/src/share/classes/java/security/AccessControlContext.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. 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 @@ -322,7 +322,7 @@ public final class AccessControlContext { debug.println("access denied " + perm); } - if (Debug.isOn("failure")) { + if (Debug.isOn("failure") && debug != null) { // Want to make sure this is always displayed for failure, // but do not want to display again if already displayed // above. diff --git a/jdk/test/java/security/AccessControlContext/FailureDebugOption.java b/jdk/test/java/security/AccessControlContext/FailureDebugOption.java new file mode 100644 index 00000000000..df48203ecb9 --- /dev/null +++ b/jdk/test/java/security/AccessControlContext/FailureDebugOption.java @@ -0,0 +1,50 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6648816 + * @summary REGRESSION: setting -Djava.security.debug=failure result in NPE + * in ACC + * @run main/othervm -Djava.security.debug=failure FailureDebugOption + */ + +import java.security.ProtectionDomain; +import java.security.AccessController; +import java.security.AccessControlException; +import java.security.BasicPermission; + +public class FailureDebugOption { + + public static void main (String argv[]) throws Exception { + try { + AccessController.checkPermission( + new BasicPermission("no such permission"){}); + } catch (NullPointerException npe) { + throw new Exception("Unexpected NullPointerException for security" + + " debug option, -Djava.security.debug=failure"); + } catch (AccessControlException ace) { + } + } +} + From 4a616b57053f86afef3ce9d6b97c271c5a637322 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Sun, 16 Mar 2008 01:37:44 -0400 Subject: [PATCH 170/274] 6618387: SSL client sessions do not close cleanly. A TCP reset occurs instead of a close_notify alert CloseIdelConnection() does not query the cached connection correctly. Reviewed-by: chegar --- .../net/www/protocol/https/HttpsClient.java | 12 +- .../CloseKeepAliveCached.java | 308 ++++++++++++++++++ 2 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java diff --git a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java index 7f82e993161..d21425680c8 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems, Inc. 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 @@ -518,6 +518,16 @@ final class HttpsClient extends HttpClient kac.put(url, sslSocketFactory, this); } + /* + * Close an idle connection to this URL (if it exists in the cache). + */ + public void closeIdleConnection() { + HttpClient http = (HttpClient) kac.get(url, sslSocketFactory); + if (http != null) { + http.closeServer(); + } + } + /** * Returns the cipher suite in use on this connection. */ diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java new file mode 100644 index 00000000000..c6098fbf769 --- /dev/null +++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java @@ -0,0 +1,308 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6618387 + * @summary SSL client sessions do not close cleanly. A TCP reset occurs + * instead of a close_notify alert. + * @run main/othervm -Djavax.net.debug=ssl CloseKeepAliveCached + * + * @ignore + * After run the test manually, at the end of the debug output, + * if "MainThread, called close()" found, the test passed. Otherwise, + * if "Keep-Alive-Timer: called close()", the test failed. + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import javax.net.ssl.*; + +public class CloseKeepAliveCached { + static Map cookies; + ServerSocket ss; + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = true; + + /* + * Where do we find the keystores? + */ + static String pathToStores = "../../../../../../etc"; + static String keyStoreFile = "keystore"; + static String trustStoreFile = "truststore"; + static String passwd = "passphrase"; + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + private SSLServerSocket sslServerSocket = null; + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); + sslServerSocket = + (SSLServerSocket) sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + SSLSocket sslSocket = null; + try { + sslSocket = (SSLSocket) sslServerSocket.accept(); + for (int i = 0; i < 3 && !sslSocket.isClosed(); i++) { + // read request + InputStream is = sslSocket.getInputStream (); + + BufferedReader r = new BufferedReader( + new InputStreamReader(is)); + String x; + while ((x=r.readLine()) != null) { + if (x.length() ==0) { + break; + } + } + + + PrintStream out = new PrintStream( + new BufferedOutputStream( + sslSocket.getOutputStream() )); + + /* send the header */ + out.print("HTTP/1.1 200 OK\r\n"); + out.print("Keep-Alive: timeout=15, max=100\r\n"); + out.print("Connection: Keep-Alive\r\n"); + out.print("Content-Type: text/html; charset=iso-8859-1\r\n"); + out.print("Content-Length: 9\r\n"); + out.print("\r\n"); + out.print("Testing\r\n"); + out.flush(); + + Thread.sleep(50); + } + sslSocket.close(); + sslServerSocket.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + try { + HttpsURLConnection http = null; + + /* establish http connection to server */ + URL url = new URL("https://localhost:" + serverPort+"/"); + HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier()); + http = (HttpsURLConnection)url.openConnection(); + InputStream is = http.getInputStream (); + while (is.read() != -1); + is.close(); + + url = new URL("https://localhost:" + serverPort+"/"); + http = (HttpsURLConnection)url.openConnection(); + is = http.getInputStream (); + while (is.read() != -1); + + // if inputstream.close() called, the http.disconnect() will + // not able to close the cached connection. If application + // wanna close the keep-alive cached connection immediately + // with httpURLConnection.disconnect(), they should not call + // inputstream.close() explicitly, the + // httpURLConnection.disconnect() will do it internally. + // is.close(); + + // close the connection, sending close_notify to peer. + // otherwise, the connection will be closed by Finalizer or + // Keep-Alive-Timer if timeout. + http.disconnect(); + // Thread.sleep(5000); + } catch (IOException ioex) { + if (sslServerSocket != null) + sslServerSocket.close(); + throw ioex; + } + } + + static class NameVerifier implements HostnameVerifier { + public boolean verify(String hostname, SSLSession session) { + return true; + } + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String args[]) throws Exception { + String keyFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + if (debug) + System.setProperty("javax.net.debug", "all"); + + /* + * Start the tests. + */ + new CloseKeepAliveCached(); + } + + Thread clientThread = null; + Thread serverThread = null; + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + CloseKeepAliveCached() throws Exception { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + serverThread.join(); + } else { + clientThread.join(); + } + + /* + * When we get here, the test is pretty much over. + * + * If the main thread excepted, that propagates back + * immediately. If the other thread threw an exception, we + * should report back. + */ + if (serverException != null) + throw serverException; + if (clientException != null) + throw clientException; + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + doServerSide(); + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + doClientSide(); + } + } +} + From e61d136dd95b9f136eb85d9d1f4c3615a6184c69 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Sun, 16 Mar 2008 23:46:27 -0400 Subject: [PATCH 171/274] 6542796: CPU issue with JSSE and tomcat Record length count error Reviewed-by: weijun --- .../classes/sun/security/ssl/InputRecord.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/sun/security/ssl/InputRecord.java b/jdk/src/share/classes/sun/security/ssl/InputRecord.java index 56ea2b0483e..c0e3e4aa526 100644 --- a/jdk/src/share/classes/sun/security/ssl/InputRecord.java +++ b/jdk/src/share/classes/sun/security/ssl/InputRecord.java @@ -426,12 +426,12 @@ class InputRecord extends ByteArrayInputStream implements Record { if (really < 0) { throw new SSLException("SSL peer shut down incorrectly"); } - - // now we've got a complete record. - count = contentLen + headerSize; - exlen = 0; } + // now we've got a complete record. + count = contentLen + headerSize; + exlen = 0; + if (debug != null && Debug.isOn("record")) { if (count < 0 || count > (maxRecordSize - headerSize)) { System.out.println(Thread.currentThread().getName() @@ -502,10 +502,11 @@ class InputRecord extends ByteArrayInputStream implements Record { if (really < 0) { throw new EOFException("SSL peer shut down incorrectly"); } - - // now we've got a complete record. - exlen = 0; } + + // now we've got a complete record. + exlen = 0; + hashInternal(buf, 2, 3); hashInternal(v2Buf, 0, len); V2toV3ClientHello(v2Buf); From 04886b6f44239255890f94a732e008c8f68d4763 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Mon, 17 Mar 2008 03:11:29 -0400 Subject: [PATCH 172/274] 6447412: Issue with socket.close() for ssl sockets when poweroff on other system Support SSL sockets SOLINGER Reviewed-by: chegar --- .../classes/sun/security/ssl/Handshaker.java | 5 +- .../sun/security/ssl/OutputRecord.java | 12 ++ .../sun/security/ssl/SSLSocketImpl.java | 94 ++++++++++++-- .../SSLSocketImpl/AsyncSSLSocketClose.java | 116 ++++++++++++++++++ 4 files changed, 214 insertions(+), 13 deletions(-) create mode 100644 jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java diff --git a/jdk/src/share/classes/sun/security/ssl/Handshaker.java b/jdk/src/share/classes/sun/security/ssl/Handshaker.java index b8395665d5a..5b9dae6c590 100644 --- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java +++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java @@ -617,7 +617,8 @@ abstract class Handshaker { r.write(1); // single byte of data if (conn != null) { - synchronized (conn.writeLock) { + conn.writeLock.lock(); + try { conn.writeRecord(r); conn.changeWriteCiphers(); if (debug != null && Debug.isOn("handshake")) { @@ -625,6 +626,8 @@ abstract class Handshaker { } mesg.write(output); output.flush(); + } finally { + conn.writeLock.unlock(); } } else { synchronized (engine.writeLock) { diff --git a/jdk/src/share/classes/sun/security/ssl/OutputRecord.java b/jdk/src/share/classes/sun/security/ssl/OutputRecord.java index 3153b07f1ac..3d580e5cd5b 100644 --- a/jdk/src/share/classes/sun/security/ssl/OutputRecord.java +++ b/jdk/src/share/classes/sun/security/ssl/OutputRecord.java @@ -174,6 +174,18 @@ class OutputRecord extends ByteArrayOutputStream implements Record { return count == headerSize; } + /* + * Return true if the record is of a given alert. + */ + boolean isAlert(byte description) { + // An alert is defined with a two bytes struct, + // {byte level, byte description}, following after the header bytes. + if (count > (headerSize + 1) && contentType == ct_alert) { + return buf[headerSize + 1] == description; + } + + return false; + } /* * Compute the MAC and append it to this record. In case we diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java index 0b8a16c0958..66b6e6d112c 100644 --- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems, Inc. 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,6 +33,8 @@ import java.security.AccessController; import java.security.AccessControlContext; import java.security.PrivilegedAction; import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import javax.crypto.BadPaddingException; @@ -274,7 +276,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { * from the peer are handled properly. */ private Object handshakeLock; - Object writeLock; + ReentrantLock writeLock; private Object readLock; private InputRecord inrec; @@ -314,7 +316,6 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { private HashMap handshakeListeners; - /* * Reuse the same internal input/output streams. */ @@ -526,7 +527,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { enabledCipherSuites = CipherSuiteList.getDefault(); enabledProtocols = ProtocolList.getDefault(); handshakeLock = new Object(); - writeLock = new Object(); + writeLock = new ReentrantLock(); readLock = new Object(); inrec = null; @@ -677,16 +678,81 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { // implementations are fragile and don't like to see empty // records, so this also increases robustness. // - synchronized (writeLock) { - if (!r.isEmpty()) { - // r.compress(c); - r.addMAC(writeMAC); - r.encrypt(writeCipher); - r.write(sockOutput); + if (!r.isEmpty()) { + + // If the record is a close notify alert, we need to honor + // socket option SO_LINGER. Note that we will try to send + // the close notify even if the SO_LINGER set to zero. + if (r.isAlert(Alerts.alert_close_notify) && getSoLinger() >= 0) { + + // keep and clear the current thread interruption status. + boolean interrupted = Thread.interrupted(); + try { + if (writeLock.tryLock(getSoLinger(), TimeUnit.SECONDS)) { + try { + writeRecordInternal(r); + } finally { + writeLock.unlock(); + } + } else { + SSLException ssle = new SSLException( + "SO_LINGER timeout," + + " close_notify message cannot be sent."); + + + // For layered, non-autoclose sockets, we are not + // able to bring them into a usable state, so we + // treat it as fatal error. + if (self != this && !autoClose) { + // Note that the alert description is + // specified as -1, so no message will be send + // to peer anymore. + fatal((byte)(-1), ssle); + } else if ((debug != null) && Debug.isOn("ssl")) { + System.out.println(threadName() + + ", received Exception: " + ssle); + } + + // RFC2246 requires that the session becomes + // unresumable if any connection is terminated + // without proper close_notify messages with + // level equal to warning. + // + // RFC4346 no longer requires that a session not be + // resumed if failure to properly close a connection. + // + // We choose to make the session unresumable if + // failed to send the close_notify message. + // + sess.invalidate(); + } + } catch (InterruptedException ie) { + // keep interrupted status + interrupted = true; + } + + // restore the interrupted status + if (interrupted) { + Thread.currentThread().interrupt(); + } + } else { + writeLock.lock(); + try { + writeRecordInternal(r); + } finally { + writeLock.unlock(); + } } } } + private void writeRecordInternal(OutputRecord r) throws IOException { + // r.compress(c); + r.addMAC(writeMAC); + r.encrypt(writeCipher); + r.write(sockOutput); + } + /* * Read an application data record. Alerts and handshake @@ -1533,7 +1599,11 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { if (oldState == cs_HANDSHAKE) { sockInput.skip(sockInput.available()); } - sendAlert(Alerts.alert_fatal, description); + + // If the description equals -1, the alert won't be sent to peer. + if (description != -1) { + sendAlert(Alerts.alert_fatal, description); + } if (cause instanceof SSLException) { // only true if != null closeReason = (SSLException)cause; } else { @@ -1614,7 +1684,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { * Emit alerts. Caller must have synchronized with "this". */ private void sendAlert(byte level, byte description) { - if (connectionState >= cs_CLOSED) { + if (connectionState >= cs_SENT_CLOSE) { return; } diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java new file mode 100644 index 00000000000..21fe5303a6e --- /dev/null +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java @@ -0,0 +1,116 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 6447412 + * @summary Issue with socket.close() for ssl sockets when poweroff on + * other system + */ + +import javax.net.ssl.*; +import java.io.*; + +public class AsyncSSLSocketClose implements Runnable +{ + SSLSocket socket; + SSLServerSocket ss; + + // Where do we find the keystores? + static String pathToStores = "../../../../../../../etc"; + static String keyStoreFile = "keystore"; + static String trustStoreFile = "truststore"; + static String passwd = "passphrase"; + + public static void main(String[] args) { + String keyFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + new AsyncSSLSocketClose(); + } + + public AsyncSSLSocketClose() { + try { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); + ss = (SSLServerSocket) sslssf.createServerSocket(0); + + SSLSocketFactory sslsf = + (SSLSocketFactory)SSLSocketFactory.getDefault(); + socket = (SSLSocket)sslsf.createSocket("localhost", + ss.getLocalPort()); + SSLSocket serverSoc = (SSLSocket) ss.accept(); + ss.close(); + + (new Thread(this)).start(); + serverSoc.startHandshake(); + + try { + Thread.sleep(5000); + } catch (Exception e) { + e.printStackTrace(); + } + + socket.setSoLinger(true, 10); + System.out.println("Calling Socket.close"); + socket.close(); + System.out.println("ssl socket get closed"); + System.out.flush(); + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + // block in write + public void run() { + try { + byte[] ba = new byte[1024]; + for (int i=0; i Date: Tue, 18 Mar 2008 12:04:20 +0300 Subject: [PATCH 173/274] 6608764: PropertyChangeListeners machinery should have a better locking scheme Change to use a private final object java.awt.Component.changeSupportLock for locking purposes instead of using this Reviewed-by: son, ant --- jdk/src/share/classes/java/awt/Component.java | 82 ++++++++++++------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 718cafe0614..cce43bfe166 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -634,6 +634,11 @@ public abstract class Component implements ImageObserver, MenuContainer, */ private PropertyChangeSupport changeSupport; + private transient final Object changeSupportLock = new Object(); + private Object getChangeSupportLock() { + return changeSupportLock; + } + boolean isPacked = false; /** @@ -7839,15 +7844,17 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) */ - public synchronized void addPropertyChangeListener( + public void addPropertyChangeListener( PropertyChangeListener listener) { - if (listener == null) { - return; + synchronized (getChangeSupportLock()) { + if (listener == null) { + return; + } + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + changeSupport.addPropertyChangeListener(listener); } - if (changeSupport == null) { - changeSupport = new PropertyChangeSupport(this); - } - changeSupport.addPropertyChangeListener(listener); } /** @@ -7863,12 +7870,14 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener) */ - public synchronized void removePropertyChangeListener( + public void removePropertyChangeListener( PropertyChangeListener listener) { - if (listener == null || changeSupport == null) { - return; + synchronized (getChangeSupportLock()) { + if (listener == null || changeSupport == null) { + return; + } + changeSupport.removePropertyChangeListener(listener); } - changeSupport.removePropertyChangeListener(listener); } /** @@ -7885,11 +7894,13 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners * @since 1.4 */ - public synchronized PropertyChangeListener[] getPropertyChangeListeners() { - if (changeSupport == null) { - return new PropertyChangeListener[0]; + public PropertyChangeListener[] getPropertyChangeListeners() { + synchronized (getChangeSupportLock()) { + if (changeSupport == null) { + return new PropertyChangeListener[0]; + } + return changeSupport.getPropertyChangeListeners(); } - return changeSupport.getPropertyChangeListeners(); } /** @@ -7923,16 +7934,18 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners(java.lang.String) * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener) */ - public synchronized void addPropertyChangeListener( + public void addPropertyChangeListener( String propertyName, PropertyChangeListener listener) { - if (listener == null) { - return; + synchronized (getChangeSupportLock()) { + if (listener == null) { + return; + } + if (changeSupport == null) { + changeSupport = new PropertyChangeSupport(this); + } + changeSupport.addPropertyChangeListener(propertyName, listener); } - if (changeSupport == null) { - changeSupport = new PropertyChangeSupport(this); - } - changeSupport.addPropertyChangeListener(propertyName, listener); } /** @@ -7951,13 +7964,15 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners(java.lang.String) * @see #removePropertyChangeListener(java.beans.PropertyChangeListener) */ - public synchronized void removePropertyChangeListener( + public void removePropertyChangeListener( String propertyName, PropertyChangeListener listener) { - if (listener == null || changeSupport == null) { - return; + synchronized (getChangeSupportLock()) { + if (listener == null || changeSupport == null) { + return; + } + changeSupport.removePropertyChangeListener(propertyName, listener); } - changeSupport.removePropertyChangeListener(propertyName, listener); } /** @@ -7974,12 +7989,14 @@ public abstract class Component implements ImageObserver, MenuContainer, * @see #getPropertyChangeListeners * @since 1.4 */ - public synchronized PropertyChangeListener[] getPropertyChangeListeners( + public PropertyChangeListener[] getPropertyChangeListeners( String propertyName) { - if (changeSupport == null) { - return new PropertyChangeListener[0]; + synchronized (getChangeSupportLock()) { + if (changeSupport == null) { + return new PropertyChangeListener[0]; + } + return changeSupport.getPropertyChangeListeners(propertyName); } - return changeSupport.getPropertyChangeListeners(propertyName); } /** @@ -7994,7 +8011,10 @@ public abstract class Component implements ImageObserver, MenuContainer, */ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - PropertyChangeSupport changeSupport = this.changeSupport; + PropertyChangeSupport changeSupport; + synchronized (getChangeSupportLock()) { + changeSupport = this.changeSupport; + } if (changeSupport == null || (oldValue != null && newValue != null && oldValue.equals(newValue))) { return; From f92bcde478135cad4accec4a70be1e167c7bf03e Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 18 Mar 2008 13:53:08 +0300 Subject: [PATCH 174/274] 6613927: Compilation of splashscreen png library failed on Ubuntu 7.04 (64bit) The macro PNG_NO_MMX_CODE should be defined when compiling on 64bit Linux Reviewed-by: yan, avu --- jdk/make/sun/splashscreen/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/jdk/make/sun/splashscreen/Makefile b/jdk/make/sun/splashscreen/Makefile index 1b51d3a6484..8a0dffe62c9 100644 --- a/jdk/make/sun/splashscreen/Makefile +++ b/jdk/make/sun/splashscreen/Makefile @@ -85,3 +85,13 @@ vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3 +ifeq ($(PLATFORM), linux) + ifeq ($(ARCH_DATA_MODEL), 64) + # 64-bit gcc has problems compiling MMX instructions. + # Google it for more details. Possibly the newer versions of + # the PNG-library and/or the new compiler will not need this + # option in the future. + CPPFLAGS += -DPNG_NO_MMX_CODE + endif +endif + From cdf1fcc79dc9f6525288bc7d97dd919a4517cddd Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 18 Mar 2008 14:10:28 +0300 Subject: [PATCH 175/274] 6607660: java.awt.Container.getMouseEventTargetImpl should be invoked while holding the TreeLock The body of the method has been wrapped into the synchronized (getTreeLock()) { } block. Reviewed-by: son, art --- jdk/src/share/classes/java/awt/Container.java | 85 ++++++++++--------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Container.java b/jdk/src/share/classes/java/awt/Container.java index 4a347f3d5e9..e92c7665f03 100644 --- a/jdk/src/share/classes/java/awt/Container.java +++ b/jdk/src/share/classes/java/awt/Container.java @@ -2267,53 +2267,56 @@ public class Container extends Component { EventTargetFilter filter, boolean searchHeavyweightChildren, boolean searchHeavyweightDescendants) { - int ncomponents = this.ncomponents; - Component component[] = this.component; + synchronized (getTreeLock()) { + int ncomponents = this.ncomponents; + Component component[] = this.component; - for (int i = 0 ; i < ncomponents ; i++) { - Component comp = component[i]; - if (comp != null && comp.visible && - ((!searchHeavyweightChildren && - comp.peer instanceof LightweightPeer) || - (searchHeavyweightChildren && - !(comp.peer instanceof LightweightPeer))) && - comp.contains(x - comp.x, y - comp.y)) { + for (int i = 0 ; i < ncomponents ; i++) { + Component comp = component[i]; + if (comp != null && comp.visible && + ((!searchHeavyweightChildren && + comp.peer instanceof LightweightPeer) || + (searchHeavyweightChildren && + !(comp.peer instanceof LightweightPeer))) && + comp.contains(x - comp.x, y - comp.y)) { - // found a component that intersects the point, see if there is - // a deeper possibility. - if (comp instanceof Container) { - Container child = (Container) comp; - Component deeper = child.getMouseEventTarget(x - child.x, - y - child.y, - includeSelf, - filter, - searchHeavyweightDescendants); - if (deeper != null) { - return deeper; - } - } else { - if (filter.accept(comp)) { - // there isn't a deeper target, but this component is a - // target - return comp; + // found a component that intersects the point, see if there + // is a deeper possibility. + if (comp instanceof Container) { + Container child = (Container) comp; + Component deeper = child.getMouseEventTarget( + x - child.x, + y - child.y, + includeSelf, + filter, + searchHeavyweightDescendants); + if (deeper != null) { + return deeper; + } + } else { + if (filter.accept(comp)) { + // there isn't a deeper target, but this component + // is a target + return comp; + } } } } + + boolean isPeerOK; + boolean isMouseOverMe; + + isPeerOK = (peer instanceof LightweightPeer) || includeSelf; + isMouseOverMe = contains(x,y); + + // didn't find a child target, return this component if it's + // a possible target + if (isMouseOverMe && isPeerOK && filter.accept(this)) { + return this; + } + // no possible target + return null; } - - boolean isPeerOK; - boolean isMouseOverMe; - - isPeerOK = (peer instanceof LightweightPeer) || includeSelf; - isMouseOverMe = contains(x,y); - - // didn't find a child target, return this component if it's a possible - // target - if (isMouseOverMe && isPeerOK && filter.accept(this)) { - return this; - } - // no possible target - return null; } static interface EventTargetFilter { From 80a01c07965a89945b5d7c51ba791a215955afed Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 18 Mar 2008 14:20:28 +0300 Subject: [PATCH 176/274] 6637796: setBounds doesn't enlarge Component Added the areBoundsValid() method that verifies whether the current bounds of the component are valid. Using the isValid() method for this purpose previously was incorrect. Reviewed-by: son, art --- jdk/src/share/classes/java/awt/Component.java | 17 +- jdk/test/java/awt/Mixing/ValidBounds.java | 411 ++++++++++++++++++ 2 files changed, 426 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/awt/Mixing/ValidBounds.java diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index cce43bfe166..f8f47c8c2de 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -9475,6 +9475,19 @@ public abstract class Component implements ImageObserver, MenuContainer, // ************************** MIXING CODE ******************************* + /** + * Check whether we can trust the current bounds of the component. + * The return value of false indicates that the container of the + * component is invalid, and therefore needs to be layed out, which would + * probably mean changing the bounds of its children. + * Null-layout of the container or absence of the container mean + * the bounds of the component are final and can be trusted. + */ + private boolean areBoundsValid() { + Container cont = getContainer(); + return cont == null || cont.isValid() || cont.getLayout() == null; + } + /** * Applies the shape to the component * @param shape Shape to be applied to the component @@ -9498,7 +9511,7 @@ public abstract class Component implements ImageObserver, MenuContainer, // to modify the object outside of the mixing code. this.compoundShape = shape; - if (isValid()) { + if (areBoundsValid()) { Point compAbsolute = getLocationOnWindow(); if (mixingLog.isLoggable(Level.FINER)) { @@ -9625,7 +9638,7 @@ public abstract class Component implements ImageObserver, MenuContainer, void applyCurrentShape() { checkTreeLock(); - if (!isValid()) { + if (!areBoundsValid()) { return; // Because applyCompoundShape() ignores such components anyway } if (mixingLog.isLoggable(Level.FINE)) { diff --git a/jdk/test/java/awt/Mixing/ValidBounds.java b/jdk/test/java/awt/Mixing/ValidBounds.java new file mode 100644 index 00000000000..dec7e6fce44 --- /dev/null +++ b/jdk/test/java/awt/Mixing/ValidBounds.java @@ -0,0 +1,411 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 6637796 + @summary Shape should be correctly updated on invalid components + @author anthony.petrov@...: area=awt.mixing + @library ../regtesthelpers + @build Util + @run main ValidBounds +*/ + +/** + * ValidBounds.java + * + * summary: Shape should be correctly updated on invalid components + */ + +import java.awt.*; +import java.awt.event.*; +import test.java.awt.regtesthelpers.Util; + +public class ValidBounds +{ + + static volatile boolean clickPassed = false; + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "This is an AUTOMATIC test, simply wait until it is done.", + "The result (passed or failed) will be shown in the", + "message window below." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + + // Create the frame and the button + Frame f = new Frame(); + f.setBounds(100, 100, 400, 300); + + Button b = new Button("OK"); + + f.setLayout(null); + f.add(b); + b.setBounds(50, 50, 200, 50); + + b.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent e) { + clickPassed = true; + } + }); + + f.setVisible(true); + + // Let's make the button much smaller first... + Robot robot = Util.createRobot(); + robot.setAutoDelay(20); + + Util.waitForIdle(robot); + + b.setBounds(50, 50, 5, 5); + Util.waitForIdle(robot); + + // ... and now let's enlarge it. + b.setBounds(50, 50, 200, 50); + Util.waitForIdle(robot); + + // If the button doesn't receive the click, it means that the test + // failed: the shape of the button was not enlarged. + Point heavyLoc = b.getLocationOnScreen(); + robot.mouseMove(heavyLoc.x + 20, heavyLoc.y + 20); + + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Util.waitForIdle(robot); + + if (clickPassed) { + pass(); + } else { + fail("The button cannot be clicked."); + } + }//End init() + + + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test- + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + // Not sure about what happens if multiple of this test are + // instantiated in the same VM. Being static (and using + // static vars), it aint gonna work. Not worrying about + // it for now. + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test pass nor test fail has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + //The test harness may have interrupted the test. If so, rethrow the exception + // so that the harness gets it and deals with it. + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class ValidBounds + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// if want to make listeners, here is the recommended place for them, then instantiate +// them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + ValidBounds.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + ValidBounds.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + System.out.println(messageIn); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + +}// TestDialog class From 8813269b78a456d9a3fc6a4567e5567de2a2d5f3 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 18 Mar 2008 14:36:14 +0300 Subject: [PATCH 177/274] 6304277: PIT: Adding a TrayIcon closes a SplashScreen on Solaris but not on Win32 The Window.closeSplashScreen() method now verified the boolean flag isTrayIconWindow, and returns if it is true. Reviewed-by: son, dcherepanov --- jdk/src/share/classes/java/awt/Window.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index a0841af43e4..3ebeee00639 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -826,7 +826,10 @@ public class Window extends Container implements Accessible { static private final AtomicBoolean beforeFirstWindowShown = new AtomicBoolean(true); - static final void closeSplashScreen() { + final void closeSplashScreen() { + if (isTrayIconWindow) { + return; + } if (beforeFirstWindowShown.getAndSet(false)) { SunToolkit.closeSplashScreen(); } From c195eb4ef5b8c781010edeae726f9754c7085414 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 18 Mar 2008 15:07:42 +0300 Subject: [PATCH 178/274] 6581927: REG : Non focusable frame can be minimized to very small & Frame icon can be seen on frame buttons The SWP_NOSENDCHANGING flag should not be passed to the ::SetWindowPos() WinAPI function when we receive the WM_MOUSEMOVE message while manually handling the resizing of non-focusable frames. Reviewed-by: son, ant --- .../windows/native/sun/windows/awt_Frame.cpp | 2 +- .../NonFocusableResizableTooSmall.java | 413 ++++++++++++++++++ 2 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 55c85b4c0b3..2f22aff5dfd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -495,7 +495,7 @@ MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) { ::SetWindowPos(GetHWnd(), NULL, r.left, r.top, r.right-r.left, r.bottom-r.top, - SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOCOPYBITS | SWP_DEFERERASE); } return mrConsume; diff --git a/jdk/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java b/jdk/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java new file mode 100644 index 00000000000..ef3207ffcb8 --- /dev/null +++ b/jdk/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java @@ -0,0 +1,413 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6581927 + @summary Non-focusable frame should honor the size of the frame buttons/decorations when resizing + @library ../../regtesthelpers + @build Util + @author anthony.petrov@...: area=awt.toplevel + @run main NonFocusableResizableTooSmall +*/ + +/** + * NonFocusableResizableTooSmall.java + * + * summary: Non-focusable frame should honor the size of the frame buttons/decorations when resizing + */ + +import java.awt.*; +import java.awt.event.*; +import test.java.awt.regtesthelpers.Util; + +public class NonFocusableResizableTooSmall +{ + + //*** test-writer defined static variables go here *** + + + private static void init() + { + //*** Create instructions for the user here *** + + String[] instructions = + { + "This is an AUTOMATIC test, simply wait until it is done.", + "The result (passed or failed) will be shown in the", + "message window below." + }; + Sysout.createDialog( ); + Sysout.printInstructions( instructions ); + + final Frame frame = new Frame(); + frame.setFocusableWindowState(false); + frame.setSize(200, 100); + frame.setVisible(true); + + final Robot robot = Util.createRobot(); + robot.setAutoDelay(20); + + // To be sure the window is shown and packed + Util.waitForIdle(robot); + + final Insets insets = frame.getInsets(); + System.out.println("The insets of the frame: " + insets); + if (insets.right == 0 || insets.bottom == 0) { + System.out.println("The test environment must have non-zero right & bottom insets!"); + pass(); + return; + } + + // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip") + final Rectangle bounds1 = frame.getBounds(); + System.out.println("The bounds before resizing: " + bounds1); + + robot.mouseMove(bounds1.x + bounds1.width - 1, bounds1.y + bounds1.height - 1); + + // ... and start resizing to some very small + robot.mousePress( InputEvent.BUTTON1_MASK ); + + // Now resize the frame so that the width is smaller + // than the widths of the left and the right borders. + // The sum of widths of the icon of the frame + the control-buttons + // (close, minimize, etc.) should be definitely larger! + robot.mouseMove(bounds1.x + insets.left + insets.right - 5, bounds1.y + bounds1.height - 1); + Util.waitForIdle(robot); + + robot.mouseRelease( InputEvent.BUTTON1_MASK ); + + Util.waitForIdle(robot); + + // Check the current bounds of the frame + final Rectangle bounds2 = frame.getBounds(); + System.out.println("The bounds after resizing: " + bounds2); + + if (bounds2.width <= (insets.left + insets.right)) { + fail("The frame has been resized to very small."); + } + pass(); + }//End init() + + + + /***************************************************** + * Standard Test Machinery Section + * DO NOT modify anything in this section -- it's a + * standard chunk of code which has all of the + * synchronisation necessary for the test harness. + * By keeping it the same in all tests, it is easier + * to read and understand someone else's test, as + * well as insuring that all tests behave correctly + * with the test harness. + * There is a section following this for test- + * classes + ******************************************************/ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + + private static Thread mainThread = null; + + private static int sleepTime = 300000; + + // Not sure about what happens if multiple of this test are + // instantiated in the same VM. Being static (and using + // static vars), it aint gonna work. Not worrying about + // it for now. + public static void main( String args[] ) throws InterruptedException + { + mainThread = Thread.currentThread(); + try + { + init(); + } + catch( TestPassedException e ) + { + //The test passed, so just return from main and harness will + // interepret this return as a pass + return; + } + //At this point, neither test pass nor test fail has been + // called -- either would have thrown an exception and ended the + // test, so we know we have multiple threads. + + //Test involves other threads, so sleep and wait for them to + // called pass() or fail() + try + { + Thread.sleep( sleepTime ); + //Timed out, so fail the test + throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); + } + catch (InterruptedException e) + { + //The test harness may have interrupted the test. If so, rethrow the exception + // so that the harness gets it and deals with it. + if( ! testGeneratedInterrupt ) throw e; + + //reset flag in case hit this code more than once for some reason (just safety) + testGeneratedInterrupt = false; + + if ( theTestPassed == false ) + { + throw new RuntimeException( failureMessage ); + } + } + + }//main + + public static synchronized void setTimeoutTo( int seconds ) + { + sleepTime = seconds * 1000; + } + + public static synchronized void pass() + { + Sysout.println( "The test passed." ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //first check if this is executing in main thread + if ( mainThread == Thread.currentThread() ) + { + //Still in the main thread, so set the flag just for kicks, + // and throw a test passed exception which will be caught + // and end the test. + theTestPassed = true; + throw new TestPassedException(); + } + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + }//pass() + + public static synchronized void fail() + { + //test writer didn't specify why test failed, so give generic + fail( "it just plain failed! :-)" ); + } + + public static synchronized void fail( String whyFailed ) + { + Sysout.println( "The test failed: " + whyFailed ); + Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); + //check if this called from main thread + if ( mainThread == Thread.currentThread() ) + { + //If main thread, fail now 'cause not sleeping + throw new RuntimeException( whyFailed ); + } + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); + }//fail() + +}// class NonFocusableResizableTooSmall + +//This exception is used to exit from any level of call nesting +// when it's determined that the test has passed, and immediately +// end the test. +class TestPassedException extends RuntimeException +{ +} + +//*********** End Standard Test Machinery Section ********** + + +//************ Begin classes defined for the test **************** + +// if want to make listeners, here is the recommended place for them, then instantiate +// them in init() + +/* Example of a class which may be written as part of a test +class NewClass implements anInterface + { + static int newVar = 0; + + public void eventDispatched(AWTEvent e) + { + //Counting events to see if we get enough + eventCount++; + + if( eventCount == 20 ) + { + //got enough events, so pass + + NonFocusableResizableTooSmall.pass(); + } + else if( tries == 20 ) + { + //tried too many times without getting enough events so fail + + NonFocusableResizableTooSmall.fail(); + } + + }// eventDispatched() + + }// NewClass class + +*/ + + +//************** End classes defined for the test ******************* + + + + +/**************************************************** + Standard Test Machinery + DO NOT modify anything below -- it's a standard + chunk of code whose purpose is to make user + interaction uniform, and thereby make it simpler + to read and understand someone else's test. + ****************************************************/ + +/** + This is part of the standard test machinery. + It creates a dialog (with the instructions), and is the interface + for sending text messages to the user. + To print the instructions, send an array of strings to Sysout.createDialog + WithInstructions method. Put one line of instructions per array entry. + To display a message for the tester to see, simply call Sysout.println + with the string to be displayed. + This mimics System.out.println but works within the test harness as well + as standalone. + */ + +class Sysout +{ + private static TestDialog dialog; + + public static void createDialogWithInstructions( String[] instructions ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + dialog.printInstructions( instructions ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + public static void createDialog( ) + { + dialog = new TestDialog( new Frame(), "Instructions" ); + String[] defInstr = { "Instructions will appear here. ", "" } ; + dialog.printInstructions( defInstr ); + dialog.setVisible(true); + println( "Any messages for the tester will display here." ); + } + + + public static void printInstructions( String[] instructions ) + { + dialog.printInstructions( instructions ); + } + + + public static void println( String messageIn ) + { + dialog.displayMessage( messageIn ); + System.out.println(messageIn); + } + +}// Sysout class + +/** + This is part of the standard test machinery. It provides a place for the + test instructions to be displayed, and a place for interactive messages + to the user to be displayed. + To have the test instructions displayed, see Sysout. + To have a message to the user be displayed, see Sysout. + Do not call anything in this dialog directly. + */ +class TestDialog extends Dialog +{ + + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + + //DO NOT call this directly, go through Sysout + public TestDialog( Frame frame, String name ) + { + super( frame, name ); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); + add( "North", instructionsText ); + + messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); + add("Center", messageText); + + pack(); + + setVisible(true); + }// TestDialog() + + //DO NOT call this directly, go through Sysout + public void printInstructions( String[] instructions ) + { + //Clear out any current instructions + instructionsText.setText( "" ); + + //Go down array of instruction strings + + String printStr, remainingStr; + for( int i=0; i < instructions.length; i++ ) + { + //chop up each into pieces maxSringLength long + remainingStr = instructions[ i ]; + while( remainingStr.length() > 0 ) + { + //if longer than max then chop off first max chars to print + if( remainingStr.length() >= maxStringLength ) + { + //Try to chop on a word boundary + int posOfSpace = remainingStr. + lastIndexOf( ' ', maxStringLength - 1 ); + + if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; + + printStr = remainingStr.substring( 0, posOfSpace + 1 ); + remainingStr = remainingStr.substring( posOfSpace + 1 ); + } + //else just print + else + { + printStr = remainingStr; + remainingStr = ""; + } + + instructionsText.append( printStr + "\n" ); + + }// while + + }// for + + }//printInstructions() + + //DO NOT call this directly, go through Sysout + public void displayMessage( String messageIn ) + { + messageText.append( messageIn + "\n" ); + System.out.println(messageIn); + } + +}// TestDialog class From 723e2559384052eef9884a6bafe4d6fa38b85bd7 Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 18 Mar 2008 16:19:03 +0300 Subject: [PATCH 179/274] 6589527: Window and Frame instances can hide their "Applet Warning" Additional constraints have been added for the setBounds() operation. Reviewed-by: son, art --- .../classes/sun/awt/X11/XDecoratedPeer.java | 54 ++++++++++- .../classes/sun/awt/X11/XDialogPeer.java | 3 +- .../sun/awt/X11/XEmbeddedFramePeer.java | 6 ++ .../classes/sun/awt/X11/XFramePeer.java | 3 +- .../classes/sun/awt/X11/XWindowPeer.java | 61 +++++++++++- .../classes/sun/awt/motif/MDialogPeer.java | 5 + .../sun/awt/motif/MEmbeddedFramePeer.java | 6 ++ .../classes/sun/awt/motif/MFramePeer.java | 5 + .../classes/sun/awt/motif/MWindowPeer.java | 94 +++++++++++++++++++ .../classes/sun/awt/windows/WDialogPeer.java | 11 ++- .../sun/awt/windows/WEmbeddedFramePeer.java | 6 ++ .../classes/sun/awt/windows/WFramePeer.java | 11 ++- .../classes/sun/awt/windows/WWindowPeer.java | 91 ++++++++++++++++++ .../windows/native/sun/windows/awt_Window.cpp | 22 +++++ .../windows/native/sun/windows/awt_Window.h | 6 ++ 15 files changed, 375 insertions(+), 9 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java index e0b46de2291..8aa3085282f 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java @@ -36,7 +36,7 @@ import java.util.logging.Logger; import sun.awt.ComponentAccessor; import sun.awt.SunToolkit; -class XDecoratedPeer extends XWindowPeer { +abstract class XDecoratedPeer extends XWindowPeer { private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer"); private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer"); private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer"); @@ -456,6 +456,15 @@ class XDecoratedPeer extends XWindowPeer { if (insLog.isLoggable(Level.FINE)) { insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape); } + if (userReshape) { + // We handle only userReshape == true cases. It means that + // if the window manager or any other part of the windowing + // system sets inappropriate size for this window, we can + // do nothing but accept it. + Rectangle reqBounds = newDimensions.getBounds(); + Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height); + newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet()); + } XToolkit.awtLock(); try { if (!isReparented() || !isVisible()) { @@ -571,6 +580,49 @@ class XDecoratedPeer extends XWindowPeer { reshape(dims, operation, userReshape); } + // This method gets overriden in XFramePeer & XDialogPeer. + abstract boolean isTargetUndecorated(); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + // If it's undecorated or is not currently visible, + // apply the same constraints as for the Window. + if (!isVisible() || isTargetUndecorated()) { + return super.constrainBounds(x, y, width, height); + } + + // If it's visible & decorated, constraint the size only + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + Rectangle curBounds = getBounds(); + + int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width); + int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height); + + // First make sure the size is withing the visible part of the screen + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + + return new Rectangle(newX, newY, newW, newH); + } + /** * @see java.awt.peer.ComponentPeer#setBounds */ diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java index 248e6f8e60c..40822e2c27d 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java @@ -88,7 +88,8 @@ class XDialogPeer extends XDecoratedPeer implements DialogPeer { } } - private boolean isTargetUndecorated() { + @Override + boolean isTargetUndecorated() { if (undecorated != null) { return undecorated.booleanValue(); } else { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java index d33e545e279..b0cb3aa6d07 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java @@ -184,6 +184,12 @@ public class XEmbeddedFramePeer extends XFramePeer { } } + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } + // don't use getBounds() inherited from XDecoratedPeer public Rectangle getBounds() { return new Rectangle(x, y, width, height); diff --git a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java index 5cd03b1b062..28989acc609 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java @@ -95,7 +95,8 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants { } } - private boolean isTargetUndecorated() { + @Override + boolean isTargetUndecorated() { if (undecorated != null) { return undecorated.booleanValue(); } else { diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java index c69e8f3a2ba..be679208974 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java @@ -182,6 +182,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, GraphicsConfiguration gc = getGraphicsConfiguration(); ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this); + + Rectangle bounds = (Rectangle)(params.get(BOUNDS)); + params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height)); } private void initWMProtocols() { @@ -431,6 +434,56 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, return ownerPeer; } + // This method is overriden at the XDecoratedPeer to handle + // decorated windows a bit differently. + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + // The window bounds should be within the visible part of the screen + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + // Now check each point is within the visible part of the screen + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + + return new Rectangle(newX, newY, newW, newH); + } + //Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges //the window but fails to revalidate, Sol-CDE //This bug is regression for @@ -439,10 +492,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, //Note that this function is overriden in XDecoratedPeer so event //posting is not changing for decorated peers public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + XToolkit.awtLock(); try { Rectangle oldBounds = getBounds(); - super.setBounds(x, y, width, height, op); + + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + Rectangle bounds = getBounds(); XSizeHints hints = getHints(); @@ -1029,7 +1086,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, return !(target instanceof Frame || target instanceof Dialog); } boolean hasWarningWindow() { - return warningWindow != null; + return ((Window)target).getWarningString() != null; } // The height of menu bar window diff --git a/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java b/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java index 16ccab54ca6..5e22931aa60 100644 --- a/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java +++ b/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java @@ -102,4 +102,9 @@ class MDialogPeer extends MWindowPeer implements DialogPeer, MInputMethodControl public void blockWindows(java.util.List toBlock) { // do nothing } + + @Override + final boolean isTargetUndecorated() { + return ((Dialog)target).isUndecorated(); + } } diff --git a/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java b/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java index d608721d97d..60de1a245f6 100644 --- a/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java @@ -204,4 +204,10 @@ public class MEmbeddedFramePeer extends MFramePeer { } public native Rectangle getBoundsPrivate(); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } } diff --git a/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java b/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java index 99516d5a98b..d772b99c4c2 100644 --- a/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java +++ b/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java @@ -503,4 +503,9 @@ class MFramePeer extends MWindowPeer implements FramePeer, MInputMethodControl { public Rectangle getBoundsPrivate() { return getBounds(); } + + @Override + final boolean isTargetUndecorated() { + return ((Frame)target).isUndecorated(); + } } diff --git a/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java b/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java index c59750aec51..15c5c80de3b 100644 --- a/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java +++ b/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java @@ -113,6 +113,12 @@ DisplayChangedListener { insets.right = getInset("awt.frame.rightInset", -1); } + Rectangle bounds = target.getBounds(); + sysX = bounds.x; + sysY = bounds.y; + sysW = bounds.width; + sysH = bounds.height; + super.init(target); InputMethodManager imm = InputMethodManager.getInstance(); String menuString = imm.getTriggerMenuString(); @@ -150,6 +156,7 @@ DisplayChangedListener { GraphicsConfiguration gc = getGraphicsConfiguration(); ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this); + } /* Support for multiple icons is not implemented in MAWT */ @@ -246,6 +253,8 @@ DisplayChangedListener { // NOTE: This method may be called by privileged threads. // DO NOT INVOKE CLIENT CODE ON THIS THREAD! public void handleResize(int width, int height) { + sysW = width; + sysH = height; // REMIND: Is this secure? Can client code subclass input method? if (!tcList.isEmpty() && @@ -268,6 +277,8 @@ DisplayChangedListener { } public void handleMoved(int x, int y) { + sysX = x; + sysY = y; postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); } @@ -505,4 +516,87 @@ DisplayChangedListener { } return false; } + + private final boolean hasWarningWindow() { + return ((Window)target).getWarningString() != null; + } + + // This method is overriden at Dialog and Frame peers. + boolean isTargetUndecorated() { + return true; + } + + private volatile int sysX = 0; + private volatile int sysY = 0; + private volatile int sysW = 0; + private volatile int sysH = 0; + + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + // If it's undecorated or is not currently visible, + // then check each point is within the visible part of the screen + if (!target.isVisible() || isTargetUndecorated()) { + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + } else { + int maxW = Math.max(screenW, sysW); + int maxH = Math.max(screenH, sysH); + + // Make sure the size is withing the visible part of the screen + // OR is less that the current size of the window. + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + } + + return new Rectangle(newX, newY, newW, newH); + } + + public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + } + } diff --git a/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java b/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java index 735e5f9f135..4056c4a6f65 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java @@ -108,11 +108,18 @@ class WDialogPeer extends WWindowPeer implements DialogPeer { } } + @Override + boolean isTargetUndecorated() { + return ((Dialog)target).isUndecorated(); + } + public void reshape(int x, int y, int width, int height) { + Rectangle newBounds = constrainBounds(x, y, width, height); + if (((Dialog)target).isUndecorated()) { - super.reshape(x,y,width,height); + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } else { - reshapeFrame(x,y,width,height); + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } } diff --git a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java index 56513d30863..8c446ff9184 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java @@ -65,4 +65,10 @@ public class WEmbeddedFramePeer extends WFramePeer { public native Rectangle getBoundsPrivate(); public native void synthesizeWmActivate(boolean doActivate); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } } diff --git a/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java b/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java index cdf23ec7d3b..2667fafe047 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java @@ -64,11 +64,18 @@ class WFramePeer extends WWindowPeer implements FramePeer { } } + @Override + boolean isTargetUndecorated() { + return ((Frame)target).isUndecorated(); + } + public void reshape(int x, int y, int width, int height) { + Rectangle newBounds = constrainBounds(x, y, width, height); + if (((Frame)target).isUndecorated()) { - super.reshape(x,y,width,height); + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } else { - reshapeFrame(x,y,width,height); + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } } diff --git a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java index 03fb08c7c76..070c67dd15e 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java @@ -434,6 +434,97 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer { private native void nativeGrab(); private native void nativeUngrab(); + private final boolean hasWarningWindow() { + return ((Window)target).getWarningString() != null; + } + + boolean isTargetUndecorated() { + return true; + } + + // These are the peer bounds. They get updated at: + // 1. the WWindowPeer.setBounds() method. + // 2. the native code (on WM_SIZE/WM_MOVE) + private volatile int sysX = 0; + private volatile int sysY = 0; + private volatile int sysW = 0; + private volatile int sysH = 0; + + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + // If it's undecorated or is not currently visible + if (!((Window)target).isVisible() || isTargetUndecorated()) { + // Now check each point is within the visible part of the screen + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + } else { + int maxW = Math.max(screenW, sysW); + int maxH = Math.max(screenH, sysH); + + // Make sure the size is withing the visible part of the screen + // OR less that the current size of the window. + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + } + + return new Rectangle(newX, newY, newW, newH); + } + + @Override + public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + + sysX = newBounds.x; + sysY = newBounds.y; + sysW = newBounds.width; + sysH = newBounds.height; + + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + } + /* * The method maps the list of the active windows to the window's AppContext, * then the method registers ActiveWindowListener, GuiDisposedListener listeners; diff --git a/jdk/src/windows/native/sun/windows/awt_Window.cpp b/jdk/src/windows/native/sun/windows/awt_Window.cpp index 866dffaf1c7..eda6e178c8c 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp @@ -125,6 +125,11 @@ jfieldID AwtWindow::autoRequestFocusID; jclass AwtWindow::wwindowPeerCls; jmethodID AwtWindow::getActiveWindowsMID; +jfieldID AwtWindow::sysXID; +jfieldID AwtWindow::sysYID; +jfieldID AwtWindow::sysWID; +jfieldID AwtWindow::sysHID; + int AwtWindow::ms_instanceCounter = 0; HHOOK AwtWindow::ms_hCBTFilter; AwtWindow * AwtWindow::m_grabbedWindow = NULL; @@ -1052,6 +1057,8 @@ MsgRouting AwtWindow::WmMove(int x, int y) (env)->SetIntField(target, AwtComponent::xID, rect.left); (env)->SetIntField(target, AwtComponent::yID, rect.top); + (env)->SetIntField(peer, AwtWindow::sysXID, rect.left); + (env)->SetIntField(peer, AwtWindow::sysYID, rect.top); SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED); env->DeleteLocalRef(target); @@ -1115,6 +1122,11 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h) (env)->SetIntField(target, AwtComponent::widthID, newWidth); (env)->SetIntField(target, AwtComponent::heightID, newHeight); + + jobject peer = GetPeer(env); + (env)->SetIntField(peer, AwtWindow::sysWID, newWidth); + (env)->SetIntField(peer, AwtWindow::sysHID, newHeight); + if (!AwtWindow::IsResizing()) { WindowResized(); } @@ -1750,17 +1762,22 @@ void AwtWindow::_ReshapeFrame(void *param) // Fix for 4459064 : do not enforce thresholds for embedded frames if (!p->IsEmbeddedFrame()) { + jobject peer = p->GetPeer(env); int minWidth = ::GetSystemMetrics(SM_CXMIN); int minHeight = ::GetSystemMetrics(SM_CYMIN); if (w < minWidth) { env->SetIntField(target, AwtComponent::widthID, w = minWidth); + env->SetIntField(peer, AwtWindow::sysWID, + w); } if (h < minHeight) { env->SetIntField(target, AwtComponent::heightID, h = minHeight); + env->SetIntField(peer, AwtWindow::sysHID, + h); } } env->DeleteLocalRef(target); @@ -2144,6 +2161,11 @@ Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls) env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J"); DASSERT(AwtWindow::getActiveWindowsMID != NULL); + AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I"); + AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I"); + AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I"); + AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I"); + CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Window.h b/jdk/src/windows/native/sun/windows/awt_Window.h index ca3b68c3220..8e654a2d813 100644 --- a/jdk/src/windows/native/sun/windows/awt_Window.h +++ b/jdk/src/windows/native/sun/windows/awt_Window.h @@ -62,6 +62,12 @@ public: /* long[] getActiveWindowHandles() method in WWindowPeer */ static jmethodID getActiveWindowsMID; + // The coordinates at the peer. + static jfieldID sysXID; + static jfieldID sysYID; + static jfieldID sysWID; + static jfieldID sysHID; + AwtWindow(); virtual ~AwtWindow(); From 3bcb13882070a40f0e26e1014144820a205481a3 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 18 Mar 2008 11:01:40 -0700 Subject: [PATCH 180/274] 6674232: OPENJDK=false is same as OPENJDK=true If OPENJDK has a value, that value must be "true", empty value == undefined with GNU make. Reviewed-by: tbell --- make/Defs-internal.gmk | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/make/Defs-internal.gmk b/make/Defs-internal.gmk index 97c9395f068..5d5e7491b34 100644 --- a/make/Defs-internal.gmk +++ b/make/Defs-internal.gmk @@ -28,6 +28,12 @@ # not contain rules. # +ifdef OPENJDK + ifneq ($(OPENJDK),true) + x:=$(error "OPENJDK (if defined) can only be set to true") + endif +endif + # Define absolute paths to TOPDIRs ABS_CONTROL_TOPDIR:=$(call OptFullPath,"$(CONTROL_TOPDIR)") ABS_LANGTOOLS_TOPDIR:=$(call OptFullPath,"$(LANGTOOLS_TOPDIR)") @@ -96,10 +102,8 @@ ifndef BUILD_JDK endif ifeq ($(JDK_SRC_AVAILABLE),true) JDK_CLOSED_SRC_AVAILABLE := $(call MkExists,$(JDK_TOPDIR)/src/closed) - ifndef OPENJDK - ifeq ($(JDK_CLOSED_SRC_AVAILABLE),false) - OPENJDK = true - endif + ifeq ($(JDK_CLOSED_SRC_AVAILABLE),false) + OPENJDK = true endif endif From 65cbc8719faa021c1e3656f8612cfda2c9d03c5d Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 18 Mar 2008 11:03:27 -0700 Subject: [PATCH 181/274] 6674226: Warning errors in freetypecheck Just corrected some C code to remove warning errors from gcc. Reviewed-by: tbell --- jdk/make/tools/freetypecheck/freetypecheck.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/make/tools/freetypecheck/freetypecheck.c b/jdk/make/tools/freetypecheck/freetypecheck.c index 00f460d7dc1..12b26f7e88b 100644 --- a/jdk/make/tools/freetypecheck/freetypecheck.c +++ b/jdk/make/tools/freetypecheck/freetypecheck.c @@ -26,13 +26,16 @@ /* Test program for freetype sanity check. Prints "Failed" messages to STDOUT if check fails. */ +#include +#include + #include "ft2build.h" #include FT_FREETYPE_H #define QUOTEMACRO(x) QUOTEME(x) #define QUOTEME(x) #x -int main(char** argv, int argc) { +int main(int argc, char** argv) { char v[50]; FT_Int major, minor, patch; FT_Library library; From 0dbfd8d9bf60b6c73df06a94315f4c2211104e50 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 18 Mar 2008 11:04:42 -0700 Subject: [PATCH 182/274] 6611788: chmod a+x bin/winver.exe in make/tools/winver/Makefile fails on a read only file system Tell Mercurial this file has execute permission. Reviewed-by: tbell --- jdk/make/tools/winver/bin/winver.exe | Bin 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 jdk/make/tools/winver/bin/winver.exe diff --git a/jdk/make/tools/winver/bin/winver.exe b/jdk/make/tools/winver/bin/winver.exe old mode 100644 new mode 100755 From 42919ee3bb762481b1824225ffc545c966031f7a Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 18 Mar 2008 11:06:34 -0700 Subject: [PATCH 183/274] 6674232: OPENJDK=false is same as OPENJDK=true OPENJDK should be empty (undefined) or "true". Reviewed-by: tbell --- jdk/make/common/Defs.gmk | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 6fe53ebeced..268533ba608 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -32,6 +32,13 @@ # So when it includes other files, it must use JDK_TOPDIR. # +# Check for strange explicit settings (change to empty or true) +ifdef OPENJDK + ifneq ($(OPENJDK),true) + x:=$(error "OPENJDK (if defined) can only be set to true") + endif +endif + # # On Solaris, the 'make' utility from Sun will not work with these makefiles. # This little rule is only understood by Sun's make, and is harmless @@ -87,19 +94,6 @@ ifeq ($(CLOSED_SRC_DIR_EXISTS), false) OPENJDK = true endif -# Check for strange explicit settings (change to empty or true) -ifdef OPENJDK - ifeq ($(OPENJDK),false) - # Silently treat as not defined - OPENJDK = - else - ifneq ($(OPENJDK),true) - dummy := $(warning "WARNING: OPENKJDK=$(OPENJDK) being treated as true") - OPENJDK = true - endif - endif -endif - # Define where closed directories are ifdef OPENJDK CLOSED_SRC = From e35b18e39bd50fb93dc8e9dd45aae9791d37e6c0 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 18 Mar 2008 11:08:09 -0700 Subject: [PATCH 184/274] 6654458: /java/devtools findbugs doesn't work on windows Changes to both ant and findbugs version checking. Reviewed-by: tbell --- jdk/make/common/shared/Defs-utils.gmk | 10 ---------- jdk/make/common/shared/Defs.gmk | 18 ++++++++++++++++++ jdk/make/common/shared/Sanity.gmk | 20 ++++++++++++++------ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/jdk/make/common/shared/Defs-utils.gmk b/jdk/make/common/shared/Defs-utils.gmk index dc84d795b76..3886ee65ce4 100644 --- a/jdk/make/common/shared/Defs-utils.gmk +++ b/jdk/make/common/shared/Defs-utils.gmk @@ -67,16 +67,6 @@ ifeq ($(PLATFORM),windows) UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH) endif -# Utilities ant and findbugs -ifndef ANT_HOME - ANT_HOME = $(JDK_DEVTOOLS_DIR)/share/ant/latest -endif -ANT = $(ANT_HOME)/bin/ant -ifndef FINDBUGS_HOME - FINDBUGS_HOME = $(JDK_DEVTOOLS_DIR)/share/findbugs/latest -endif -FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs - # Utilities ADB = $(UTILS_COMMAND_PATH)adb AR = $(UTILS_CCS_BIN_PATH)ar diff --git a/jdk/make/common/shared/Defs.gmk b/jdk/make/common/shared/Defs.gmk index 0eb8c729a96..6b0adfcb533 100644 --- a/jdk/make/common/shared/Defs.gmk +++ b/jdk/make/common/shared/Defs.gmk @@ -503,6 +503,24 @@ JDK_CUPS_HEADERS_PATH=$(JDK_DEVTOOLS_DIR)/share/cups/include endif endif +# Utilities ant and findbugs +ifeq ($(ANT_HOME),) + ANT_HOME := $(call DirExists,/usr/share/ant,$(JDK_DEVTOOLS_DIR)/share/ant/latest,) +endif +ifeq ($(ANT_HOME),) + ANT = ant +else + ANT = $(ANT_HOME)/bin/ant +endif +ifeq ($(FINDBUGS_HOME),) + FINDBUGS_HOME := $(call DirExists,/usr/share/findbugs,$(JDK_DEVTOOLS_DIR)/share/findbugs/latest,) +endif +ifeq ($(FINDBUGS_HOME),) + FINDBUGS = findbugs +else + FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs +endif + ifdef ALT_COPYRIGHT_YEAR COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR) else diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk index a97ddddd534..8809842608f 100644 --- a/jdk/make/common/shared/Sanity.gmk +++ b/jdk/make/common/shared/Sanity.gmk @@ -105,13 +105,21 @@ ZIP_VER :=$(call GetVersion,"$(_ZIP_VER)") UNZIP_VER :=$(call GetVersion,"$(_UNZIP_VER)") BOOT_VER :=$(call GetVersion,"$(_BOOT_VER)") -REQUIRED_ANT_VER := 1.6.3 -_ANT_VER :=$(shell $(ANT) -version 2>&1 ) -ANT_VER :=$(call GetVersion,"$(_ANT_VER)") +REQUIRED_ANT_VER := 1.6.3 +ifeq ($(ANT_HOME),) + _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" $(ANT) -version 2>&1 ) +else + _ANT_VER:=$(shell JAVACMD="$(BOOTDIR)/bin/java" ANT_HOME="$(ANT_HOME)" $(ANT) -version 2>&1 ) +endif +ANT_VER:=$(call GetVersion,"$(_ANT_VER)") -REQUIRED_FINDBUGS_VER := 1.1 -_FINDBUGS_VER :=$(shell $(FINDBUGS) -version 2>&1 ) -FINDBUGS_VER :=$(call GetVersion,"$(_FINDBUGS_VER)") +REQUIRED_FINDBUGS_VER := 1.2 +ifeq ($(FINDBUGS_HOME),) + _FINDBUGS_VER:=$(shell $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 ) +else + _FINDBUGS_VER:=$(shell FINDBUGS_HOME="$(FINDBUGS_HOME)" $(FINDBUGS) -javahome "$(BOOTDIR)" -textui -version 2>&1 ) +endif +FINDBUGS_VER:=$(call GetVersion,"$(_FINDBUGS_VER)") ifdef ALT_BINDIR ALT_BINDIR_VERSION := $(shell $(ALT_BINDIR)/java$(EXE_SUFFIX) -version 2>&1 | $(NAWK) -F'"' '{ print $$2 }') From 641bce6847edcb34f889deb6e3431c8333dcd098 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Tue, 18 Mar 2008 11:17:37 -0700 Subject: [PATCH 185/274] 6666343: Compile::has_loops not always set correctly Compile::has_loops() should be set from inlined methods Reviewed-by: kvn, rasbold --- hotspot/src/share/vm/opto/doCall.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index ff85fb643e3..edf71c0caf0 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -390,6 +390,8 @@ void Parse::do_call() { } if (cg->is_inline()) { + // Accumulate has_loops estimate + C->set_has_loops(C->has_loops() || call_method->has_loops()); C->env()->notice_inlined_method(call_method); } From af4bff1a1e358dd8a232c16e5b19f2c002a38051 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Tue, 18 Mar 2008 11:53:15 -0700 Subject: [PATCH 186/274] 6658779: Regression: HotspotDiagnosticMXBean.getDiagnosticOptions() throws NullPointerException Add a null check for the VM option string Reviewed-by: alanb, tbell --- .../share/classes/sun/management/Flag.java | 3 +- .../GetDiagnosticOptions.java | 61 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDiagnosticOptions.java diff --git a/jdk/src/share/classes/sun/management/Flag.java b/jdk/src/share/classes/sun/management/Flag.java index 510edadd668..d89761cb1f7 100644 --- a/jdk/src/share/classes/sun/management/Flag.java +++ b/jdk/src/share/classes/sun/management/Flag.java @@ -64,7 +64,8 @@ class Flag { } VMOption getVMOption() { - return new VMOption(name, value.toString(), writeable, origin); + String val = value == null ? "" : value.toString(); + return new VMOption(name, val, writeable, origin); } static Flag getFlag(String name) { diff --git a/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDiagnosticOptions.java b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDiagnosticOptions.java new file mode 100644 index 00000000000..78d57b27578 --- /dev/null +++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDiagnosticOptions.java @@ -0,0 +1,61 @@ +/* + * Copyright 2005 Sun Microsystems, Inc. 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 6658779 + * @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticOptions() + * @author Daniel Fuchs + * + * @run main GetDiagnosticOptions + */ + +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; +import java.lang.management.ManagementFactory; +import java.util.List; +import javax.management.MBeanServer; + +public class GetDiagnosticOptions { + private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = + "com.sun.management:type=HotSpotDiagnostic"; + + public static void main(String[] args) throws Exception { + HotSpotDiagnosticMXBean mbean = + sun.management.ManagementFactory.getDiagnosticMXBean(); + checkDiagnosticOptions(mbean); + + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + mbean = ManagementFactory.newPlatformMXBeanProxy(mbs, + HOTSPOT_DIAGNOSTIC_MXBEAN_NAME, + HotSpotDiagnosticMXBean.class); + checkDiagnosticOptions(mbean); + } + + private static void checkDiagnosticOptions(HotSpotDiagnosticMXBean mbean) { + List options = mbean.getDiagnosticOptions(); + for (VMOption opt : options) { + System.out.println("option: "+opt.getName()+"="+opt.getValue()); + } + } +} From 9c8e97d713af1a018bba764c2fb0e5a03bacb3cf Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Tue, 18 Mar 2008 12:53:47 -0700 Subject: [PATCH 187/274] 6672804: First line in com/sun/management/package.html is broken Fixed the typo in package.html Reviewed-by: jjh --- jdk/src/share/classes/com/sun/management/package.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/com/sun/management/package.html b/jdk/src/share/classes/com/sun/management/package.html index 8a1a4a5381c..372d9c4cc54 100644 --- a/jdk/src/share/classes/com/sun/management/package.html +++ b/jdk/src/share/classes/com/sun/management/package.html @@ -1,4 +1,4 @@ -CTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd index d69852ff842..3a08c64f4b6 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/schema/etsi.xsd @@ -1,347 +1,347 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties index 1b8e97bfd63..8c8b2ab1f8d 100644 --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_en.properties @@ -1,123 +1,123 @@ -algorithm.alreadyRegistered = URI {0} already assigned to class {1} -algorithm.classDoesNotExist = Cannot register URI {0} to class {1} because this class does not exist in CLASSPATH -algorithm.ClassDoesNotExist = Class {0} does not exist -algorithm.extendsWrongClass = Cannot register URI {0} to class {1} because it does not extend {2} -algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures. -algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures. -algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs. -algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms -algorithms.NoSuchAlgorithm = The requested algorithm {0} does not exist. Original Message was: {1} -algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm -algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1} -algorithms.operationOnlyVerification = A public key can only used for verification of a signature. -algorithms.WrongKeyForThisOperation = Sorry, you supplied the wrong key type for this operation! You supplied a {0} but a {1} is needed. -attributeValueIllegal = The attribute {0} has value {1} but must be {2} -c14n.Canonicalizer.Exception = Exception during Canonicalization: Original Message was {0} -c14n.Canonicalizer.IllegalNode = Illegal node type {0}, node name was {1} -c14n.Canonicalizer.NoSuchCanonicalizer = No canonicalizer found with URI {0} -c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException during Canonicalization: Original Message was {0} -c14n.Canonicalizer.RelativeNamespace = Element {0} has a relative namespace: {1}="{2}" -c14n.Canonicalizer.SAXException = SAXException during Canonicalization: Original Message was {0} -c14n.Canonicalizer.TraversalNotSupported = This DOM document does not support Traversal {0} -c14n.Canonicalizer.UnsupportedEncoding = Unsupported encoding {0} -c14n.Canonicalizer.UnsupportedOperation = This canonicalizer does not support this operation -c14n.XMLUtils.circumventBug2650forgotten = The tree has not been prepared for canonicalization using XMLUtils#circumventBug2650(Document) -certificate.noSki.lowVersion = Certificate cannot contain a SubjectKeyIdentifier because it is only X509v{0} -certificate.noSki.notOctetString = Certificates SubjectKeyIdentifier is not a OctetString -certificate.noSki.null = Certificate does not contain a SubjectKeyIdentifier -defaultNamespaceCannotBeSetHere = Default namespace cannot be set here -ElementProxy.nullElement = Cannot create an ElementProxy from a null argument -empty = {0} -encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0} -encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams -encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt -encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap -encryption.ExplicitKeySizeMismatch = The xenc:KeySize element requests a key size of {0} bit but the algorithm implements {1} bit -encryption.nonceLongerThanDecryptedPlaintext = The given nonce is longer than the available plaintext. I Cannot strip away this. -encryption.RSAOAEP.dataHashWrong = data hash wrong -encryption.RSAOAEP.dataStartWrong = data wrong start {0} -encryption.RSAOAEP.dataTooShort = data too short -encryption.RSAPKCS15.blockTruncated = block truncated -encryption.RSAPKCS15.noDataInBlock = no data in block -encryption.RSAPKCS15.unknownBlockType = unknown block type -encryption.nokey = No Key Encryption Key loaded and cannot determine using key resolvers -endorsed.jdk1.4.0 = Since it seems that nobody reads our installation notes, we must do it in the exception messages. Hope you read them. You did NOT use the endorsed mechanism from JDK 1.4 properly; look at how to solve this problem. -errorMessages.InvalidDigestValueException = INVALID signature -- check reference resolution. -errorMessages.InvalidSignatureValueException = INVALID signature -- core validation failed. -errorMessages.IOException = Other file I/O and similar exceptions. -errorMessages.MissingKeyFailureException = Cannot verify because of missing public key. Provide it via addResource and try again. -errorMessages.MissingResourceFailureException = Cannot verify because of unresolved references. Provide it via addResource and try again. -errorMessages.NoSuchAlgorithmException = Unknown Algorithm {0} -errorMessages.NotYetImplementedException = Functionality not yet there. -errorMessages.XMLSignatureException = Verification failed for some other reason. -decoding.divisible.four = It should be divisible by four -decoding.general = Error while decoding -FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Method addToDefaultFromRemote() not yet implemented. -FileKeyStorageImpl.NoCert.Context = Not found such a X509Certificate including context {0} -FileKeyStorageImpl.NoCert.IssNameSerNo = Not found such a X509Certificate with IssuerName {0} and serial number {1} -FileKeyStorageImpl.NoCert.SubjName = Not found such a X509Certificate including SubjectName {0} -generic.dontHaveConstructionElement = I do not have a construction Element -generic.EmptyMessage = {0} -generic.NotYetImplemented = {0} Not YET implemented ;-(( -java.security.InvalidKeyException = Invalid key -java.security.NoSuchProviderException = Unknown or unsupported provider -java.security.UnknownKeyType = Unknown or unsupported key type {0} -KeyInfo.needKeyResolver = More than one keyResovler have to be registered -KeyInfo.nokey = Cannot get key from {0} -KeyInfo.noKey = Cannot get the public key -KeyInfo.wrongNumberOfObject = Need {0} keyObjects -KeyInfo.wrongUse = This object was made for getting {0} -keyResolver.alreadyRegistered = {1} class has already been registered for {0} -KeyResolver.needStorageResolver = Need a StorageResolver to retrieve a Certificate from a {0} -KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0} -KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0} -KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0} -KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0} -KeyResoverSpiImpl.keyStore = KeyStorage error in implement class {0} -KeyResoverSpiImpl.need.Element = {1} type of Element is needed in implement class {0} -KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0} -KeyResoverSpiImpl.wrongKeyObject = Need {1} type of KeyObject for generation Element in implement class{0} -KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0} -KeyStore.alreadyRegistered = {0} Class has already been registered for {1} -KeyStore.register = {1} type class register error in class {0} -KeyStore.registerStore.register = Registeration error for type {0} -KeyValue.IllegalArgument = Cannot create a {0} from {1} -namespacePrefixAlreadyUsedByOtherURI = Namespace prefix {0} already used by other URI {1} -notYetInitialized = The module {0} is not yet initialized -prefix.AlreadyAssigned = You want to assign {0} as prefix for namespace {1} but it is already assigned for {2} -signature.Canonicalizer.UnknownCanonicalizer = Unknown canonicalizer. No handler installed for URI {0} -signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature -signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first -signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set -signature.Transform.ErrorDuringTransform = A {1} was thrown during the {0} transform -signature.Transform.NotYetImplemented = Transform {0} not yet implemented -signature.Transform.NullPointerTransform = Null pointer as URI. Programming bug? -signature.Transform.UnknownTransform = Unknown transformation. No handler installed for URI {0} -signature.Transform.node = Current Node: {0} -signature.Transform.nodeAndType = Current Node: {0}, type: {1} -signature.Util.BignumNonPositive = bigInteger.signum() must be positive -signature.Util.NonTextNode = Not a text node -signature.Util.TooManyChilds = Too many childs of Type {0} in {1} -signature.Verification.certificateError = Certificate error -signature.Verification.IndexOutOfBounds = Index {0} illegal. We only have {1} References -signature.Verification.internalError = Internal error -signature.Verification.InvalidDigestOrReference = Invalid digest of reference {0} -signature.Verification.keyStore = KeyStore error -signature.Verification.MissingID = Cannot resolve element with ID {0} -signature.Verification.MissingResources = Cannot resolve external resource {0} -signature.Verification.NoSignatureElement = Input document contains no {0} Element in namespace {1} -signature.Verification.Reference.NoInput = The Reference for URI {0} has no XMLSignatureInput -signature.Verification.SignatureError = Signature error -signature.XMLSignatureInput.MissingConstuctor = Cannot construct a XMLSignatureInput from class {0} -signature.XMLSignatureInput.SerializeDOM = Input initialized with DOM Element. Use Canonicalization to serialize it -signature.XMLSignatureInput.nodesetReference = Unable to convert to nodeset the reference -transform.Init.IllegalContextArgument = Invalid context argument of class {0}. Must be String, org.w3c.dom.NodeList or java.io.InputStream. -transform.init.NotInitialized = -transform.init.wrongURI = Initialized with wrong URI. How could this happen? We implement {0} but {1} was used during initialization -utils.Base64.IllegalBitlength = Illegal byte length; Data to be decoded must be a multiple of 4 -Base64Decoding = Error while decoding -utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1} -xml.WrongContent = Cannot find {0} in {1} -xml.WrongElement = Cannot create a {0} from a {1} element -xpath.funcHere.documentsDiffer = The XPath is not in the same document as the context node -xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0} +algorithm.alreadyRegistered = URI {0} already assigned to class {1} +algorithm.classDoesNotExist = Cannot register URI {0} to class {1} because this class does not exist in CLASSPATH +algorithm.ClassDoesNotExist = Class {0} does not exist +algorithm.extendsWrongClass = Cannot register URI {0} to class {1} because it does not extend {2} +algorithms.CannotUseAlgorithmParameterSpecOnDSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating DSA signatures. +algorithms.CannotUseAlgorithmParameterSpecOnRSA = Sorry, but you cannot use a AlgorithmParameterSpec object for creating RSA signatures. +algorithms.CannotUseSecureRandomOnMAC = Sorry, but you cannot use a SecureRandom object for creating MACs. +algorithms.HMACOutputLengthOnlyForHMAC = A HMACOutputLength can only be specified for HMAC integrity algorithms +algorithms.NoSuchAlgorithm = The requested algorithm {0} does not exist. Original Message was: {1} +algorithms.NoSuchMap = The algorithm URI "{0}" could not be mapped to a JCE algorithm +algorithms.NoSuchProvider = The specified Provider {0} does not exist. Original Message was: {1} +algorithms.operationOnlyVerification = A public key can only used for verification of a signature. +algorithms.WrongKeyForThisOperation = Sorry, you supplied the wrong key type for this operation! You supplied a {0} but a {1} is needed. +attributeValueIllegal = The attribute {0} has value {1} but must be {2} +c14n.Canonicalizer.Exception = Exception during Canonicalization: Original Message was {0} +c14n.Canonicalizer.IllegalNode = Illegal node type {0}, node name was {1} +c14n.Canonicalizer.NoSuchCanonicalizer = No canonicalizer found with URI {0} +c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException during Canonicalization: Original Message was {0} +c14n.Canonicalizer.RelativeNamespace = Element {0} has a relative namespace: {1}="{2}" +c14n.Canonicalizer.SAXException = SAXException during Canonicalization: Original Message was {0} +c14n.Canonicalizer.TraversalNotSupported = This DOM document does not support Traversal {0} +c14n.Canonicalizer.UnsupportedEncoding = Unsupported encoding {0} +c14n.Canonicalizer.UnsupportedOperation = This canonicalizer does not support this operation +c14n.XMLUtils.circumventBug2650forgotten = The tree has not been prepared for canonicalization using XMLUtils#circumventBug2650(Document) +certificate.noSki.lowVersion = Certificate cannot contain a SubjectKeyIdentifier because it is only X509v{0} +certificate.noSki.notOctetString = Certificates SubjectKeyIdentifier is not a OctetString +certificate.noSki.null = Certificate does not contain a SubjectKeyIdentifier +defaultNamespaceCannotBeSetHere = Default namespace cannot be set here +ElementProxy.nullElement = Cannot create an ElementProxy from a null argument +empty = {0} +encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeUsedForEncryptedData {0} +encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams +encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt +encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap +encryption.ExplicitKeySizeMismatch = The xenc:KeySize element requests a key size of {0} bit but the algorithm implements {1} bit +encryption.nonceLongerThanDecryptedPlaintext = The given nonce is longer than the available plaintext. I Cannot strip away this. +encryption.RSAOAEP.dataHashWrong = data hash wrong +encryption.RSAOAEP.dataStartWrong = data wrong start {0} +encryption.RSAOAEP.dataTooShort = data too short +encryption.RSAPKCS15.blockTruncated = block truncated +encryption.RSAPKCS15.noDataInBlock = no data in block +encryption.RSAPKCS15.unknownBlockType = unknown block type +encryption.nokey = No Key Encryption Key loaded and cannot determine using key resolvers +endorsed.jdk1.4.0 = Since it seems that nobody reads our installation notes, we must do it in the exception messages. Hope you read them. You did NOT use the endorsed mechanism from JDK 1.4 properly; look at how to solve this problem. +errorMessages.InvalidDigestValueException = INVALID signature -- check reference resolution. +errorMessages.InvalidSignatureValueException = INVALID signature -- core validation failed. +errorMessages.IOException = Other file I/O and similar exceptions. +errorMessages.MissingKeyFailureException = Cannot verify because of missing public key. Provide it via addResource and try again. +errorMessages.MissingResourceFailureException = Cannot verify because of unresolved references. Provide it via addResource and try again. +errorMessages.NoSuchAlgorithmException = Unknown Algorithm {0} +errorMessages.NotYetImplementedException = Functionality not yet there. +errorMessages.XMLSignatureException = Verification failed for some other reason. +decoding.divisible.four = It should be divisible by four +decoding.general = Error while decoding +FileKeyStorageImpl.addToDefaultFromRemoteNotImplemented = Method addToDefaultFromRemote() not yet implemented. +FileKeyStorageImpl.NoCert.Context = Not found such a X509Certificate including context {0} +FileKeyStorageImpl.NoCert.IssNameSerNo = Not found such a X509Certificate with IssuerName {0} and serial number {1} +FileKeyStorageImpl.NoCert.SubjName = Not found such a X509Certificate including SubjectName {0} +generic.dontHaveConstructionElement = I do not have a construction Element +generic.EmptyMessage = {0} +generic.NotYetImplemented = {0} Not YET implemented ;-(( +java.security.InvalidKeyException = Invalid key +java.security.NoSuchProviderException = Unknown or unsupported provider +java.security.UnknownKeyType = Unknown or unsupported key type {0} +KeyInfo.needKeyResolver = More than one keyResovler have to be registered +KeyInfo.nokey = Cannot get key from {0} +KeyInfo.noKey = Cannot get the public key +KeyInfo.wrongNumberOfObject = Need {0} keyObjects +KeyInfo.wrongUse = This object was made for getting {0} +keyResolver.alreadyRegistered = {1} class has already been registered for {0} +KeyResolver.needStorageResolver = Need a StorageResolver to retrieve a Certificate from a {0} +KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0} +KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0} +KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0} +KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0} +KeyResoverSpiImpl.keyStore = KeyStorage error in implement class {0} +KeyResoverSpiImpl.need.Element = {1} type of Element is needed in implement class {0} +KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0} +KeyResoverSpiImpl.wrongKeyObject = Need {1} type of KeyObject for generation Element in implement class{0} +KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0} +KeyStore.alreadyRegistered = {0} Class has already been registered for {1} +KeyStore.register = {1} type class register error in class {0} +KeyStore.registerStore.register = Registeration error for type {0} +KeyValue.IllegalArgument = Cannot create a {0} from {1} +namespacePrefixAlreadyUsedByOtherURI = Namespace prefix {0} already used by other URI {1} +notYetInitialized = The module {0} is not yet initialized +prefix.AlreadyAssigned = You want to assign {0} as prefix for namespace {1} but it is already assigned for {2} +signature.Canonicalizer.UnknownCanonicalizer = Unknown canonicalizer. No handler installed for URI {0} +signature.DSA.invalidFormat = Invalid ASN.1 encoding of the DSA signature +signature.Generation.signBeforeGetValue = You have to XMLSignature.sign(java.security.PrivateKey) first +signature.signaturePropertyHasNoTarget = The Target attribute of the SignatureProperty must be set +signature.Transform.ErrorDuringTransform = A {1} was thrown during the {0} transform +signature.Transform.NotYetImplemented = Transform {0} not yet implemented +signature.Transform.NullPointerTransform = Null pointer as URI. Programming bug? +signature.Transform.UnknownTransform = Unknown transformation. No handler installed for URI {0} +signature.Transform.node = Current Node: {0} +signature.Transform.nodeAndType = Current Node: {0}, type: {1} +signature.Util.BignumNonPositive = bigInteger.signum() must be positive +signature.Util.NonTextNode = Not a text node +signature.Util.TooManyChilds = Too many childs of Type {0} in {1} +signature.Verification.certificateError = Certificate error +signature.Verification.IndexOutOfBounds = Index {0} illegal. We only have {1} References +signature.Verification.internalError = Internal error +signature.Verification.InvalidDigestOrReference = Invalid digest of reference {0} +signature.Verification.keyStore = KeyStore error +signature.Verification.MissingID = Cannot resolve element with ID {0} +signature.Verification.MissingResources = Cannot resolve external resource {0} +signature.Verification.NoSignatureElement = Input document contains no {0} Element in namespace {1} +signature.Verification.Reference.NoInput = The Reference for URI {0} has no XMLSignatureInput +signature.Verification.SignatureError = Signature error +signature.XMLSignatureInput.MissingConstuctor = Cannot construct a XMLSignatureInput from class {0} +signature.XMLSignatureInput.SerializeDOM = Input initialized with DOM Element. Use Canonicalization to serialize it +signature.XMLSignatureInput.nodesetReference = Unable to convert to nodeset the reference +transform.Init.IllegalContextArgument = Invalid context argument of class {0}. Must be String, org.w3c.dom.NodeList or java.io.InputStream. +transform.init.NotInitialized = +transform.init.wrongURI = Initialized with wrong URI. How could this happen? We implement {0} but {1} was used during initialization +utils.Base64.IllegalBitlength = Illegal byte length; Data to be decoded must be a multiple of 4 +Base64Decoding = Error while decoding +utils.resolver.noClass = Could not find a resolver for URI {0} and Base {1} +xml.WrongContent = Cannot find {0} in {1} +xml.WrongElement = Cannot create a {0} from a {1} element +xpath.funcHere.documentsDiffer = The XPath is not in the same document as the context node +xpath.funcHere.noXPathContext = Try to evaluate an XPath which uses the here() function but XPath is not inside an ds:XPath Element. XPath was : {0} diff --git a/jdk/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd b/jdk/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd index 5ac5a61f100..9188d43e2d4 100644 --- a/jdk/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd +++ b/jdk/src/share/classes/javax/swing/plaf/synth/doc-files/synth.dtd @@ -73,7 +73,7 @@ type (idref|boolean|dimension|insets|integer|string) "idref" value CDATA #REQUIRED > - + - - + + + - - -

    - Synth is a skinnable look and feel in which all painting is - delegated. Synth does not provide a default look. In - order to use Synth you need to specify a - file, or - provide a {@link - javax.swing.plaf.synth.SynthStyleFactory}. Both - configuration options require an - understanding of the synth architecture, which is described - below, as well as an understanding of Swing's architecture. -

    -

    - Unless otherwise specified null is not a legal value to any of - the methods defined in the synth package and if passed in will - result in a NullPointerException. - - -

    Synth

    -

    - Each {@link javax.swing.plaf.ComponentUI} implementation in Synth associates - itself with one {@link - javax.swing.plaf.synth.SynthStyle} per {@link - javax.swing.plaf.synth.Region}, most - Components only have one Region and - therefor only one SynthStyle. - SynthStyle - is used to access all style related properties: fonts, colors - and other Component properties. In addition - SynthStyles are used to obtain - {@link javax.swing.plaf.synth.SynthPainter}s for painting the background, border, - focus and other portions of a Component. The ComponentUIs obtain - SynthStyles from a - {@link javax.swing.plaf.synth.SynthStyleFactory}. - A SynthStyleFactory - can be provided directly by way of - {@link javax.swing.plaf.synth.SynthLookAndFeel#setStyleFactory(javax.swing.plaf.synth.SynthStyleFactory)}, - or indirectly by way of - {@link javax.swing.plaf.synth.SynthLookAndFeel#load}. The - following example uses the SynthLookAndFeel.load() - method to configure a SynthLookAndFeel and sets it - as the current look and feel: -

    -
    -
    -  SynthLookAndFeel laf = new SynthLookAndFeel();
    +
    +
    +    

    + Synth is a skinnable look and feel in which all painting is + delegated. Synth does not provide a default look. In + order to use Synth you need to specify a + file, or + provide a {@link + javax.swing.plaf.synth.SynthStyleFactory}. Both + configuration options require an + understanding of the synth architecture, which is described + below, as well as an understanding of Swing's architecture. +

    +

    + Unless otherwise specified null is not a legal value to any of + the methods defined in the synth package and if passed in will + result in a NullPointerException. + + +

    Synth

    +

    + Each {@link javax.swing.plaf.ComponentUI} implementation in Synth associates + itself with one {@link + javax.swing.plaf.synth.SynthStyle} per {@link + javax.swing.plaf.synth.Region}, most + Components only have one Region and + therefor only one SynthStyle. + SynthStyle + is used to access all style related properties: fonts, colors + and other Component properties. In addition + SynthStyles are used to obtain + {@link javax.swing.plaf.synth.SynthPainter}s for painting the background, border, + focus and other portions of a Component. The ComponentUIs obtain + SynthStyles from a + {@link javax.swing.plaf.synth.SynthStyleFactory}. + A SynthStyleFactory + can be provided directly by way of + {@link javax.swing.plaf.synth.SynthLookAndFeel#setStyleFactory(javax.swing.plaf.synth.SynthStyleFactory)}, + or indirectly by way of + {@link javax.swing.plaf.synth.SynthLookAndFeel#load}. The + following example uses the SynthLookAndFeel.load() + method to configure a SynthLookAndFeel and sets it + as the current look and feel: +

    +
    +
    +  SynthLookAndFeel laf = new SynthLookAndFeel();
       laf.load(MyClass.class.getResourceAsStream("laf.xml"), MyClass.class);
    -  UIManager.setLookAndFeel(laf);
    -      
    -
    -

    - Many JComponents are broken down into smaller - pieces and identified by the type safe enumeration in - {@link javax.swing.plaf.synth.Region}. For example, a JTabbedPane - consists of a Region for the - JTabbedPane ({@link - javax.swing.plaf.synth.Region#TABBED_PANE}), the content - area ({@link - javax.swing.plaf.synth.Region#TABBED_PANE_CONTENT}), the - area behind the tabs ({@link - javax.swing.plaf.synth.Region#TABBED_PANE_TAB_AREA}), and the - tabs ({@link - javax.swing.plaf.synth.Region#TABBED_PANE_TAB}). Each - Region of each - JComponent will have a - SynthStyle. This allows - you to customize individual pieces of each region of each - JComponent. -

    - Many of the Synth methods take a {@link javax.swing.plaf.synth.SynthContext}. This - is used to provide information about the current - Component and includes: the - {@link javax.swing.plaf.synth.SynthStyle} associated with the current - {@link javax.swing.plaf.synth.Region}, the state of the Component - as a bitmask (refer to {@link - javax.swing.plaf.synth.SynthConstants} for the valid - states), and a {@link javax.swing.plaf.synth.Region} identifying the portion of - the Component being painted. -

    - All text rendering by non-JTextComponents is - delegated to a {@link - javax.swing.plaf.synth.SynthGraphicsUtils}, which is - obtained using the {@link javax.swing.plaf.synth.SynthStyle} method - {@link javax.swing.plaf.synth.SynthStyle#getGraphicsUtils}. You can - customize text rendering - by supplying your own {@link javax.swing.plaf.synth.SynthGraphicsUtils}. - -

    - -

    Notes on specific components

    - -

    JTree

    -

    - Synth provides a region for the cells of a tree: - Region.TREE_CELL. To specify the colors of the - renderer you'll want to provide a style for the - TREE_CELL region. The following illustrates this: -

    -  <style id="treeCellStyle">
    -    <opaque value="TRUE"/>
    -    <state>
    -      <color value="WHITE" type="TEXT_FOREGROUND"/>
    -      <color value="RED" type="TEXT_BACKGROUND"/>
    -    </state>
    -    <state value="SELECTED">
    -      <color value="RED" type="TEXT_FOREGROUND"/>
    -      <color value="WHITE" type="BACKGROUND"/>
    -    </state>
    -  </style>
    -  <bind style="treeCellStyle" type="region" key="TreeCell"/>
    -
    -

    - This specifies a color combination of red on white, when - selected, and white on red when not selected. To see the - background you need to specify that labels are not opaque. The - following XML fragment does that: -

    -  <style id="labelStyle">
    -    <opaque value="FALSE"/>
    -  </style>
    -  <bind style="labelStyle" type="region" key="Label"/>
    -
    - -

    JList and JTable

    -

    - The colors that the renderers for JList and JTable use are - specified by way of the list and table Regions. The following - XML fragment illustrates how to specify red on white, when - selected, and white on red when not selected: -

    -  <style id="style">
    -    <opaque value="TRUE"/>
    -    <state>
    -      <color value="WHITE" type="TEXT_FOREGROUND"/>
    -      <color value="RED" type="TEXT_BACKGROUND"/>
    -      <color value="RED" type="BACKGROUND"/>
    -    </state>
    -    <state value="SELECTED">
    -      <color value="RED" type="TEXT_FOREGROUND"/>
    -      <color value="WHITE" type="TEXT_BACKGROUND"/>
    -    </state>
    -  </style>
    -  <bind style="style" type="region" key="Table"/>
    -  <bind style="style" type="region" key="List"/>
    -
    - - + UIManager.setLookAndFeel(laf); +
    +
    +

    + Many JComponents are broken down into smaller + pieces and identified by the type safe enumeration in + {@link javax.swing.plaf.synth.Region}. For example, a JTabbedPane + consists of a Region for the + JTabbedPane ({@link + javax.swing.plaf.synth.Region#TABBED_PANE}), the content + area ({@link + javax.swing.plaf.synth.Region#TABBED_PANE_CONTENT}), the + area behind the tabs ({@link + javax.swing.plaf.synth.Region#TABBED_PANE_TAB_AREA}), and the + tabs ({@link + javax.swing.plaf.synth.Region#TABBED_PANE_TAB}). Each + Region of each + JComponent will have a + SynthStyle. This allows + you to customize individual pieces of each region of each + JComponent. +

    + Many of the Synth methods take a {@link javax.swing.plaf.synth.SynthContext}. This + is used to provide information about the current + Component and includes: the + {@link javax.swing.plaf.synth.SynthStyle} associated with the current + {@link javax.swing.plaf.synth.Region}, the state of the Component + as a bitmask (refer to {@link + javax.swing.plaf.synth.SynthConstants} for the valid + states), and a {@link javax.swing.plaf.synth.Region} identifying the portion of + the Component being painted. +

    + All text rendering by non-JTextComponents is + delegated to a {@link + javax.swing.plaf.synth.SynthGraphicsUtils}, which is + obtained using the {@link javax.swing.plaf.synth.SynthStyle} method + {@link javax.swing.plaf.synth.SynthStyle#getGraphicsUtils}. You can + customize text rendering + by supplying your own {@link javax.swing.plaf.synth.SynthGraphicsUtils}. + +

    + +

    Notes on specific components

    + +

    JTree

    +

    + Synth provides a region for the cells of a tree: + Region.TREE_CELL. To specify the colors of the + renderer you'll want to provide a style for the + TREE_CELL region. The following illustrates this: +

    +  <style id="treeCellStyle">
    +    <opaque value="TRUE"/>
    +    <state>
    +      <color value="WHITE" type="TEXT_FOREGROUND"/>
    +      <color value="RED" type="TEXT_BACKGROUND"/>
    +    </state>
    +    <state value="SELECTED">
    +      <color value="RED" type="TEXT_FOREGROUND"/>
    +      <color value="WHITE" type="BACKGROUND"/>
    +    </state>
    +  </style>
    +  <bind style="treeCellStyle" type="region" key="TreeCell"/>
    +
    +

    + This specifies a color combination of red on white, when + selected, and white on red when not selected. To see the + background you need to specify that labels are not opaque. The + following XML fragment does that: +

    +  <style id="labelStyle">
    +    <opaque value="FALSE"/>
    +  </style>
    +  <bind style="labelStyle" type="region" key="Label"/>
    +
    + +

    JList and JTable

    +

    + The colors that the renderers for JList and JTable use are + specified by way of the list and table Regions. The following + XML fragment illustrates how to specify red on white, when + selected, and white on red when not selected: +

    +  <style id="style">
    +    <opaque value="TRUE"/>
    +    <state>
    +      <color value="WHITE" type="TEXT_FOREGROUND"/>
    +      <color value="RED" type="TEXT_BACKGROUND"/>
    +      <color value="RED" type="BACKGROUND"/>
    +    </state>
    +    <state value="SELECTED">
    +      <color value="RED" type="TEXT_FOREGROUND"/>
    +      <color value="WHITE" type="TEXT_BACKGROUND"/>
    +    </state>
    +  </style>
    +  <bind style="style" type="region" key="Table"/>
    +  <bind style="style" type="region" key="List"/>
    +
    + + diff --git a/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties b/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties index 9f9ec3a7531..fdd5c5a2246 100644 --- a/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties +++ b/jdk/src/share/demo/jfc/Notepad/resources/Notepad.properties @@ -1,76 +1,76 @@ -# -# Resource strings for Notepad example - -Title=Notepad -ElementTreeFrameTitle=Elements -ViewportBackingStore=false - -# menubar definition -# -# Each of the strings that follow form a key to be -# used to the actual menu definition. -menubar=file edit debug - -# file Menu definition -# -# Each of the strings that follow form a key to be -# used as the basis of a menu item definition. -# -# open -> Notepad.openAction -# new -> Notepad.newAction -# save -> Notepad.saveAction -# exit -> Notepad.exitAction -file=new open save - exit -fileLabel=File -openLabel=Open -openImage=resources/open.gif -newLabel=New -newImage=resources/new.gif -saveLabel=Save -saveImage=resources/save.gif -exitLabel=Exit - -# -# edit Menu definition -# -# cut -> JTextComponent.cutAction -# copy -> JTextComponent.copyAction -# paste -> JTextComponent.pasteAction -edit=cut copy paste - undo redo -editLabel=Edit -cutLabel=Cut -cutAction=cut-to-clipboard -cutImage=resources/cut.gif -copyLabel=Copy -copyAction=copy-to-clipboard -copyImage=resources/copy.gif -pasteLabel=Paste -pasteAction=paste-from-clipboard -pasteImage=resources/paste.gif -undoLabel=Undo -undoAction=Undo -redoLabel=Redo -redoAction=Redo - -# -# debug Menu definition -# -debug=dump showElementTree -debugLabel=Debug -dumpLabel=Dump model to System.err -dumpAction=dump-model -showElementTreeLabel=Show Elements - -# toolbar definition -# -# Each of the strings that follow form a key to be -# used as the basis of the tool definition. Actions -# are of course sharable, and in this case are shared -# with the menu items. -toolbar=new open save - cut copy paste -newTooltip=Create a new file -openTooltip=Open a file -saveTooltip=Save to a file -cutTooltip=Move selection to clipboard -copyTooltip=Copy selection to clipboard -pasteTooltip=Paste clipboard to selection +# +# Resource strings for Notepad example + +Title=Notepad +ElementTreeFrameTitle=Elements +ViewportBackingStore=false + +# menubar definition +# +# Each of the strings that follow form a key to be +# used to the actual menu definition. +menubar=file edit debug + +# file Menu definition +# +# Each of the strings that follow form a key to be +# used as the basis of a menu item definition. +# +# open -> Notepad.openAction +# new -> Notepad.newAction +# save -> Notepad.saveAction +# exit -> Notepad.exitAction +file=new open save - exit +fileLabel=File +openLabel=Open +openImage=resources/open.gif +newLabel=New +newImage=resources/new.gif +saveLabel=Save +saveImage=resources/save.gif +exitLabel=Exit + +# +# edit Menu definition +# +# cut -> JTextComponent.cutAction +# copy -> JTextComponent.copyAction +# paste -> JTextComponent.pasteAction +edit=cut copy paste - undo redo +editLabel=Edit +cutLabel=Cut +cutAction=cut-to-clipboard +cutImage=resources/cut.gif +copyLabel=Copy +copyAction=copy-to-clipboard +copyImage=resources/copy.gif +pasteLabel=Paste +pasteAction=paste-from-clipboard +pasteImage=resources/paste.gif +undoLabel=Undo +undoAction=Undo +redoLabel=Redo +redoAction=Redo + +# +# debug Menu definition +# +debug=dump showElementTree +debugLabel=Debug +dumpLabel=Dump model to System.err +dumpAction=dump-model +showElementTreeLabel=Show Elements + +# toolbar definition +# +# Each of the strings that follow form a key to be +# used as the basis of the tool definition. Actions +# are of course sharable, and in this case are shared +# with the menu items. +toolbar=new open save - cut copy paste +newTooltip=Create a new file +openTooltip=Open a file +saveTooltip=Save to a file +cutTooltip=Move selection to clipboard +copyTooltip=Copy selection to clipboard +pasteTooltip=Paste clipboard to selection diff --git a/jdk/src/share/sample/vm/clr-jvm/Makefile b/jdk/src/share/sample/vm/clr-jvm/Makefile index 2515650d1d5..5b8e6f3b6fa 100644 --- a/jdk/src/share/sample/vm/clr-jvm/Makefile +++ b/jdk/src/share/sample/vm/clr-jvm/Makefile @@ -29,16 +29,16 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -all: jinvoker.dll invoked.class invoker.exe - -jinvoker.dll: jinvoker.obj Makefile - cl /LD /o jinvoker.dll jinvoker.obj - -jinvoker.obj: jinvoker.cpp jinvokerExp.h Makefile - cl /Fojinvoker.obj /DJINVOKEREEXPORT /c jinvoker.cpp - -invoked.class: invoked.java Makefile - javac invoked.java - -invoker.exe: invoker.cs Makefile - csc /unsafe invoker.cs +all: jinvoker.dll invoked.class invoker.exe + +jinvoker.dll: jinvoker.obj Makefile + cl /LD /o jinvoker.dll jinvoker.obj + +jinvoker.obj: jinvoker.cpp jinvokerExp.h Makefile + cl /Fojinvoker.obj /DJINVOKEREEXPORT /c jinvoker.cpp + +invoked.class: invoked.java Makefile + javac invoked.java + +invoker.exe: invoker.cs Makefile + csc /unsafe invoker.cs diff --git a/jdk/src/share/sample/vm/clr-jvm/README.txt b/jdk/src/share/sample/vm/clr-jvm/README.txt index a081c878c94..52ed44e6d82 100644 --- a/jdk/src/share/sample/vm/clr-jvm/README.txt +++ b/jdk/src/share/sample/vm/clr-jvm/README.txt @@ -1,54 +1,54 @@ -This sample provides Java "Hello World" program that is invoked -from C# application in the same process. - -The problem of direct call of the JVM API from CLR applications -by PInvoke interface is the JVM API functions do not have static -adresses, they need to be got by JNI_CreateJavaVM() call. -The sample contains C++ libraty that wraps JVM API calls by the -static functions that are called from the C# application by -PInvoke interface. - -The sample contains the following files: - -Makefile - make file -README.txt - this readme -invoked.java - the invoked HelloWorld Java program -invoker.cs - C# invoker application -jinvoker.cpp - C++ wrapper -jinvokerExp.h - wrapper library exports - -After the success making the following files are produced: - -invoked.class - the compiled HelloWorld class -invoker.exe - the executable .NET program that invokes Java -jinvoker.dll - the wrapper library - -The following environment needs to be set for the correct sample -build and execution: - -INCLUDE must contain the paths to: - 1. MS Visual C++ standard include - 2. .NET SDK include - 3. Java includes - Example: %MSDEV%/VC98/Include;%DOTNET%/Include;%JAVA_HOME%/include;%JAVA_HOME%/include/win32 - -LIB must contain the paths to: - 1. MS Visual C++ standard libraries - 2. .NET SDK libraries - 3. jvm.dll - Example: %MSDEV%/VC98/Lib;%DOTNET%/Lib;%JAVA_HOME%/jre/bin/client - -PATH must contain the paths to: - 1. MS Visual C++ standard bin - 2. MS Dev common bin - 3. .NET SDK libraries - 4. Java bin - 5. jvm.dll - Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin/client;%PATH% - -To run the sample please do: - - invoker.exe invoked - - ---Dmitry Ryashchentsev +This sample provides Java "Hello World" program that is invoked +from C# application in the same process. + +The problem of direct call of the JVM API from CLR applications +by PInvoke interface is the JVM API functions do not have static +adresses, they need to be got by JNI_CreateJavaVM() call. +The sample contains C++ libraty that wraps JVM API calls by the +static functions that are called from the C# application by +PInvoke interface. + +The sample contains the following files: + +Makefile - make file +README.txt - this readme +invoked.java - the invoked HelloWorld Java program +invoker.cs - C# invoker application +jinvoker.cpp - C++ wrapper +jinvokerExp.h - wrapper library exports + +After the success making the following files are produced: + +invoked.class - the compiled HelloWorld class +invoker.exe - the executable .NET program that invokes Java +jinvoker.dll - the wrapper library + +The following environment needs to be set for the correct sample +build and execution: + +INCLUDE must contain the paths to: + 1. MS Visual C++ standard include + 2. .NET SDK include + 3. Java includes + Example: %MSDEV%/VC98/Include;%DOTNET%/Include;%JAVA_HOME%/include;%JAVA_HOME%/include/win32 + +LIB must contain the paths to: + 1. MS Visual C++ standard libraries + 2. .NET SDK libraries + 3. jvm.dll + Example: %MSDEV%/VC98/Lib;%DOTNET%/Lib;%JAVA_HOME%/jre/bin/client + +PATH must contain the paths to: + 1. MS Visual C++ standard bin + 2. MS Dev common bin + 3. .NET SDK libraries + 4. Java bin + 5. jvm.dll + Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin/client;%PATH% + +To run the sample please do: + + invoker.exe invoked + + +--Dmitry Ryashchentsev diff --git a/jdk/src/share/sample/vm/clr-jvm/invoker.cs b/jdk/src/share/sample/vm/clr-jvm/invoker.cs index 7e5646230bf..b4ae1bb3d0a 100644 --- a/jdk/src/share/sample/vm/clr-jvm/invoker.cs +++ b/jdk/src/share/sample/vm/clr-jvm/invoker.cs @@ -29,30 +29,30 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* -*/ - +/* +*/ + using System; using System.Runtime.InteropServices; class jinvoker{ public static int Main(string[] aArgs){ - - // Print Hello to show we are in CLR - Console.WriteLine("Hello from C#"); - if(aArgs.Length > 0) - // invoke JVM - return InvokeMain(aArgs[0]); - else - return -1; + + // Print Hello to show we are in CLR + Console.WriteLine("Hello from C#"); + if(aArgs.Length > 0) + // invoke JVM + return InvokeMain(aArgs[0]); + else + return -1; } // Link the JVM API functions and the wrappers [DllImport("jvm.dll")] public unsafe static extern int JNI_CreateJavaVM(void** ppVm, void** ppEnv, void* pArgs); [DllImport("jinvoker.dll")] public unsafe static extern int MakeJavaVMInitArgs( void** ppArgs ); - [DllImport("jinvoker.dll")] public unsafe static extern void FreeJavaVMInitArgs( void* pArgs ); + [DllImport("jinvoker.dll")] public unsafe static extern void FreeJavaVMInitArgs( void* pArgs ); [DllImport("jinvoker.dll")] public unsafe static extern int FindClass( void* pEnv, String sClass, void** ppClass ); [DllImport("jinvoker.dll")] public unsafe static extern int GetStaticMethodID( void* pEnv, void* pClass, @@ -73,7 +73,7 @@ class jinvoker{ [DllImport("jinvoker.dll")] public unsafe static extern int DestroyJavaVM( void* pJVM ); public unsafe static int InvokeMain( String sClass ){ - + void* pJVM; // JVM struct void* pEnv; // JVM environment void* pVMArgs; // VM args @@ -81,23 +81,23 @@ class jinvoker{ void* pMethod; // The executed method struct void* pArgs; // The executed method arguments struct - // Fill the pVMArgs structs + // Fill the pVMArgs structs MakeJavaVMInitArgs( &pVMArgs ); - // Create JVM + // Create JVM int nRes = JNI_CreateJavaVM( &pJVM, &pEnv, pVMArgs ); if( nRes == 0 ){ - - // Find the executed method class + + // Find the executed method class if(FindClass( pEnv, sClass, &pClass) == 0 ) - - // Find the executed method + + // Find the executed method if( GetStaticMethodID( pEnv, pClass, "main", "([Ljava/lang/String;)V", &pMethod ) == 0 ) - - // Create empty String[] array to pass to the main() + + // Create empty String[] array to pass to the main() if( NewObjectArray( pEnv, 0, "java/lang/String", &pArgs ) == 0 ){ - - // Call main() + + // Call main() nRes = CallStaticVoidMethod( pEnv, pClass, pMethod, pArgs ); if( nRes != -1 ) Console.WriteLine("Result:"+nRes); @@ -116,16 +116,16 @@ class jinvoker{ Console.WriteLine("can not find class:"+sClass); nRes = -102; } - - // Destroy the JVM + + // Destroy the JVM DestroyJavaVM( pJVM ); }else - Console.WriteLine("Can not create Java VM"); - - // Free the JVM args structs + Console.WriteLine("Can not create Java VM"); + + // Free the JVM args structs FreeJavaVMInitArgs(pVMArgs); - + return nRes; } } diff --git a/jdk/src/share/sample/vm/jvm-clr/README.txt b/jdk/src/share/sample/vm/jvm-clr/README.txt index a8fe79db343..1d1c2f4bb12 100644 --- a/jdk/src/share/sample/vm/jvm-clr/README.txt +++ b/jdk/src/share/sample/vm/jvm-clr/README.txt @@ -42,10 +42,10 @@ PATH must contain the paths to: 3. .NET SDK libraries 4. Java bin Example: %MSDEV%/VC98/Bin;%MSDEV%/Common/MSDev98/Bin;%DOTNET%/Lib;%JAVA_HOME%/bin;%PATH% - -To run the sample please do: - -java invoker invoked.exe - - ---Dmitry Ryashchentsev + +To run the sample please do: + +java invoker invoked.exe + + +--Dmitry Ryashchentsev diff --git a/jdk/src/share/sample/vm/jvm-clr/invoked.cs b/jdk/src/share/sample/vm/jvm-clr/invoked.cs index 1904bb7191b..e5eead480af 100644 --- a/jdk/src/share/sample/vm/jvm-clr/invoked.cs +++ b/jdk/src/share/sample/vm/jvm-clr/invoked.cs @@ -29,17 +29,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* -*/ - - +/* +*/ + + using System; class App{ public static int Main(){ - - // Print Hello to show we are in CLR + + // Print Hello to show we are in CLR Console.WriteLine("Hello from C#!!!"); return 0; } From 938ac15f82f0b910330ae05e9abc9c3b46bca774 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 25 Mar 2008 14:42:28 -0700 Subject: [PATCH 228/274] 6627817: Remove ^M characters in all files (Makefiles too) Some files included the use of the ^M character, which has been deleted Reviewed-by: xdono --- .../corba/se/impl/corba/orb_config_design.txt | 2 +- corba/src/share/classes/org/omg/CORBA/ir.idl | 22 +++++++++---------- .../classes/org/omg/DynamicAny/DynamicAny.idl | 18 +++++++-------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/corba/src/share/classes/com/sun/corba/se/impl/corba/orb_config_design.txt b/corba/src/share/classes/com/sun/corba/se/impl/corba/orb_config_design.txt index 6ceeec0bd5f..30cf698cbbc 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/corba/orb_config_design.txt +++ b/corba/src/share/classes/com/sun/corba/se/impl/corba/orb_config_design.txt @@ -318,7 +318,7 @@ ORB classes: 11. RequestHandler and ORB - The RH interface is currently implemented in the ORB class, but migþt better be a separate + The RH interface is currently implemented in the ORB class, but might better be a separate class. The API is currently almost the same as a ServerSubcontract. Should we regularize this? Also, the API would need to be extended to handle shutdown properly. diff --git a/corba/src/share/classes/org/omg/CORBA/ir.idl b/corba/src/share/classes/org/omg/CORBA/ir.idl index 8383443d72a..5ea8a1979dd 100644 --- a/corba/src/share/classes/org/omg/CORBA/ir.idl +++ b/corba/src/share/classes/org/omg/CORBA/ir.idl @@ -774,18 +774,18 @@ module CORBA { // orbos 98-01-18: Objects By Value -- end - enum TCKind { - tk_null, tk_void, + enum TCKind { + tk_null, tk_void, tk_short, tk_long, tk_ushort, tk_ulong, - tk_float, tk_double, tk_boolean, tk_char, - tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref, - tk_struct, tk_union, tk_enum, tk_string, - tk_sequence, tk_array, tk_alias, tk_except, - tk_longlong, tk_ulonglong, tk_longdouble, - tk_wchar, tk_wstring, tk_fixed, - tk_value, tk_value_box, - tk_native, - tk_abstract_interface + tk_float, tk_double, tk_boolean, tk_char, + tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref, + tk_struct, tk_union, tk_enum, tk_string, + tk_sequence, tk_array, tk_alias, tk_except, + tk_longlong, tk_ulonglong, tk_longdouble, + tk_wchar, tk_wstring, tk_fixed, + tk_value, tk_value_box, + tk_native, + tk_abstract_interface }; interface NativeDef : TypedefDef { diff --git a/corba/src/share/classes/org/omg/DynamicAny/DynamicAny.idl b/corba/src/share/classes/org/omg/DynamicAny/DynamicAny.idl index e38d7be01c9..b0149c3e256 100644 --- a/corba/src/share/classes/org/omg/DynamicAny/DynamicAny.idl +++ b/corba/src/share/classes/org/omg/DynamicAny/DynamicAny.idl @@ -1042,24 +1042,24 @@ module DynamicAny { /** * DynValueCommon provides operations supported by both the DynValue and DynValueBox interfaces. */ - interface DynValueCommon : DynAny { + interface DynValueCommon : DynAny { /** * Returns true if the DynValueCommon represents a null value type. */ - boolean is_null(); + boolean is_null(); /** * Changes the representation of a DynValueCommon to a null value type. */ - void set_to_null(); + void set_to_null(); /** * Replaces a null value type with a newly constructed value. Its components are initialized * to default values as in DynAnyFactory.create_dyn_any_from_type_code. * If the DynValueCommon represents a non-null value type, then this operation has no effect. */ - void set_to_value(); - }; + void set_to_value(); + }; /** * DynValue objects support the manipulation of IDL non-boxed value types. @@ -1164,14 +1164,14 @@ module DynamicAny { * of the boxed type. A DynValueBox representing a null value type has no components * and a current position of -1. */ - interface DynValueBox : DynValueCommon { + interface DynValueBox : DynValueCommon { /** * Returns the boxed value as an Any. * * @exception InvalidValue if this object represents a null value box type */ - any get_boxed_value() + any get_boxed_value() raises(InvalidValue); /** @@ -1189,7 +1189,7 @@ module DynamicAny { * * @exception InvalidValue if this object represents a null value box type */ - DynAny get_boxed_value_as_dyn_any() + DynAny get_boxed_value_as_dyn_any() raises(InvalidValue); /** @@ -1199,7 +1199,7 @@ module DynamicAny { * @exception TypeMismatch if this object represents a non-null value box type and the type * of the parameter is not matching the current boxed value type. */ - void set_boxed_value_as_dyn_any(in DynAny boxed) + void set_boxed_value_as_dyn_any(in DynAny boxed) raises(TypeMismatch); }; From e1362bb54d6b3ba3237d66209190a9893462d7ca Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 26 Mar 2008 20:18:22 -0700 Subject: [PATCH 229/274] 6679866: 3/2 portability issues with JLI-batch-200803 on Win* Make minor tweaks to the fix for 6274276 to make the Win* compiler happy... Reviewed-by: sspitsyn, ohair --- jdk/src/share/instrument/JarFacade.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/instrument/JarFacade.c b/jdk/src/share/instrument/JarFacade.c index a60bdbee134..85c5bd30b20 100644 --- a/jdk/src/share/instrument/JarFacade.c +++ b/jdk/src/share/instrument/JarFacade.c @@ -23,6 +23,14 @@ * have any questions. */ +#ifdef _WIN32 +/* + * Win* needs this include. However, Linux and Solaris do not. + * Having this include on Solaris SPARC breaks having non US-ASCII + * characters in the value of the Premain-Class attribute. + */ +#include +#endif /* _WIN32 */ #include #include @@ -45,8 +53,9 @@ doAttribute(const char* name, const char* value, void* user_data) { if (attribute->name == NULL) { free(attribute); } else { - char *begin = value; + char *begin = (char *)value; char *end; + size_t value_len; /* skip any leading white space */ while (isspace(*begin)) { @@ -66,7 +75,7 @@ doAttribute(const char* name, const char* value, void* user_data) { return; } - size_t value_len = (size_t)(end - begin); + value_len = (size_t)(end - begin); attribute->value = malloc(value_len + 1); if (attribute->value == NULL) { free(attribute->name); @@ -74,7 +83,7 @@ doAttribute(const char* name, const char* value, void* user_data) { } else { /* save the value without leading or trailing whitespace */ strncpy(attribute->value, begin, value_len); - attribute->value[value_len] = NULL; + attribute->value[value_len] = '\0'; attribute->next = NULL; if (context->head == NULL) { context->head = attribute; From fb63e2974353b41068277eaafa28a00e10862cf6 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 27 Mar 2008 09:12:54 -0700 Subject: [PATCH 230/274] 6679854: assert in escape.cpp:397 The assert misses the case CastX2P 'base' for an unsafe field reference Reviewed-by: never, jrose --- hotspot/src/share/vm/opto/escape.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index e587cee177f..0ea97731bb2 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -51,21 +51,21 @@ void PointsToNode::remove_edge(uint targIdx, PointsToNode::EdgeType et) { } #ifndef PRODUCT -static char *node_type_names[] = { +static const char *node_type_names[] = { "UnknownType", "JavaObject", "LocalVar", "Field" }; -static char *esc_names[] = { +static const char *esc_names[] = { "UnknownEscape", "NoEscape", "ArgEscape", "GlobalEscape" }; -static char *edge_type_suffix[] = { +static const char *edge_type_suffix[] = { "?", // UnknownEdge "P", // PointsToEdge "D", // DeferredEdge @@ -383,18 +383,25 @@ static Node* get_addp_base(Node *addp) { // | | // AddP ( base == address ) // - // case #6. Constant Pool or ThreadLocal or Raw object's field reference: - // ConP # Object from Constant Pool. + // case #6. Constant Pool, ThreadLocal, CastX2P or + // Raw object's field reference: + // {ConP, ThreadLocal, CastX2P, raw Load} // top | // \ | // AddP ( base == top ) // + // case #7. Klass's field reference. + // LoadKlass + // | | + // AddP ( base == address ) + // Node *base = addp->in(AddPNode::Base)->uncast(); if (base->is_top()) { // The AddP case #3 and #6. base = addp->in(AddPNode::Address)->uncast(); assert(base->Opcode() == Op_ConP || base->Opcode() == Op_ThreadLocal || - base->is_Mem() && base->bottom_type() == TypeRawPtr::NOTNULL || - base->is_Proj() && base->in(0)->is_Allocate(), "sanity"); + base->Opcode() == Op_CastX2P || + (base->is_Mem() && base->bottom_type() == TypeRawPtr::NOTNULL) || + (base->is_Proj() && base->in(0)->is_Allocate()), "sanity"); } return base; } From 2ea233816f40aced7c954571aed19396919a748e Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 28 Mar 2008 11:52:29 -0700 Subject: [PATCH 231/274] 6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments BcEscapeAnalyzer does not analyze methods with no oop arguments. Reviewed-by: rasbold --- hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp | 128 +++++++++---------- hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp | 7 +- hotspot/src/share/vm/oops/methodDataOop.hpp | 5 +- 3 files changed, 73 insertions(+), 67 deletions(-) diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp index 8b9d0d7f31e..fc875ca552d 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp @@ -1247,8 +1247,14 @@ void BCEscapeAnalyzer::compute_escape_info() { initialize(); - // do not scan method if it has no object parameters - if (_arg_local.is_empty()) { + // Do not scan method if it has no object parameters and + // does not returns an object (_return_allocated is set in initialize()). + if (_arg_local.is_empty() && !_return_allocated) { + // Clear all info since method's bytecode was not analysed and + // set pessimistic escape information. + clear_escape_info(); + methodData()->set_eflag(methodDataOopDesc::allocated_escapes); + methodData()->set_eflag(methodDataOopDesc::unknown_modified); methodData()->set_eflag(methodDataOopDesc::estimated); return; } @@ -1259,45 +1265,8 @@ void BCEscapeAnalyzer::compute_escape_info() { success = do_analysis(); } - // dump result of bytecode analysis -#ifndef PRODUCT - if (BCEATraceLevel >= 3) { - tty->print("[EA] estimated escape information for"); - if (iid != vmIntrinsics::_none) - tty->print(" intrinsic"); - method()->print_short_name(); - tty->print_cr(has_dependencies() ? " (not stored)" : ""); - tty->print(" non-escaping args: "); - _arg_local.print_on(tty); - tty->print(" stack-allocatable args: "); - _arg_stack.print_on(tty); - if (_return_local) { - tty->print(" returned args: "); - _arg_returned.print_on(tty); - } else if (is_return_allocated()) { - tty->print_cr(" allocated return values"); - } else { - tty->print_cr(" non-local return values"); - } - tty->print(" modified args: "); - for (int i = 0; i < _arg_size; i++) { - if (_arg_modified[i] == 0) - tty->print(" 0"); - else - tty->print(" 0x%x", _arg_modified[i]); - } - tty->cr(); - tty->print(" flags: "); - if (_unknown_modified) - tty->print(" unknown_modified"); - if (_return_allocated) - tty->print(" return_allocated"); - tty->cr(); - } - -#endif - // don't store interprocedural escape information if it introduces dependencies - // or if method data is empty + // don't store interprocedural escape information if it introduces + // dependencies or if method data is empty // if (!has_dependencies() && !methodData()->is_empty()) { for (i = 0; i < _arg_size; i++) { @@ -1316,6 +1285,15 @@ void BCEscapeAnalyzer::compute_escape_info() { if (_return_local) { methodData()->set_eflag(methodDataOopDesc::return_local); } + if (_return_allocated) { + methodData()->set_eflag(methodDataOopDesc::return_allocated); + } + if (_allocated_escapes) { + methodData()->set_eflag(methodDataOopDesc::allocated_escapes); + } + if (_unknown_modified) { + methodData()->set_eflag(methodDataOopDesc::unknown_modified); + } methodData()->set_eflag(methodDataOopDesc::estimated); } } @@ -1331,33 +1309,47 @@ void BCEscapeAnalyzer::read_escape_info() { _arg_modified[i] = methodData()->arg_modified(i); } _return_local = methodData()->eflag_set(methodDataOopDesc::return_local); - - // dump result of loaded escape information -#ifndef PRODUCT - if (BCEATraceLevel >= 4) { - tty->print(" non-escaping args: "); - _arg_local.print_on(tty); - tty->print(" stack-allocatable args: "); - _arg_stack.print_on(tty); - if (_return_local) { - tty->print(" returned args: "); - _arg_returned.print_on(tty); - } else { - tty->print_cr(" non-local return values"); - } - tty->print(" modified args: "); - for (int i = 0; i < _arg_size; i++) { - if (_arg_modified[i] == 0) - tty->print(" 0"); - else - tty->print(" 0x%x", _arg_modified[i]); - } - tty->cr(); - } -#endif + _return_allocated = methodData()->eflag_set(methodDataOopDesc::return_allocated); + _allocated_escapes = methodData()->eflag_set(methodDataOopDesc::allocated_escapes); + _unknown_modified = methodData()->eflag_set(methodDataOopDesc::unknown_modified); } +#ifndef PRODUCT +void BCEscapeAnalyzer::dump() { + tty->print("[EA] estimated escape information for"); + method()->print_short_name(); + tty->print_cr(has_dependencies() ? " (not stored)" : ""); + tty->print(" non-escaping args: "); + _arg_local.print_on(tty); + tty->print(" stack-allocatable args: "); + _arg_stack.print_on(tty); + if (_return_local) { + tty->print(" returned args: "); + _arg_returned.print_on(tty); + } else if (is_return_allocated()) { + tty->print_cr(" return allocated value"); + } else { + tty->print_cr(" return non-local value"); + } + tty->print(" modified args: "); + for (int i = 0; i < _arg_size; i++) { + if (_arg_modified[i] == 0) + tty->print(" 0"); + else + tty->print(" 0x%x", _arg_modified[i]); + } + tty->cr(); + tty->print(" flags: "); + if (_return_allocated) + tty->print(" return_allocated"); + if (_allocated_escapes) + tty->print(" allocated_escapes"); + if (_unknown_modified) + tty->print(" unknown_modified"); + tty->cr(); +} +#endif BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) : _conservative(method == NULL || !EstimateArgEscape) @@ -1401,6 +1393,12 @@ BCEscapeAnalyzer::BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent) compute_escape_info(); methodData()->update_escape_info(); } +#ifndef PRODUCT + if (BCEATraceLevel >= 3) { + // dump escape information + dump(); + } +#endif } } diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp index 53fe46ad88a..3af67e1fd59 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp @@ -50,9 +50,9 @@ class BCEscapeAnalyzer : public ResourceObj { uint *_arg_modified; bool _return_local; + bool _return_allocated; bool _allocated_escapes; bool _unknown_modified; - bool _return_allocated; ciObjectList _dependencies; @@ -153,4 +153,9 @@ class BCEscapeAnalyzer : public ResourceObj { // Copy dependencies from this analysis into "deps" void copy_dependencies(Dependencies *deps); + +#ifndef PRODUCT + // dump escape information + void dump(); +#endif }; diff --git a/hotspot/src/share/vm/oops/methodDataOop.hpp b/hotspot/src/share/vm/oops/methodDataOop.hpp index bcc1ac27eca..9c19f9b3a70 100644 --- a/hotspot/src/share/vm/oops/methodDataOop.hpp +++ b/hotspot/src/share/vm/oops/methodDataOop.hpp @@ -1253,7 +1253,10 @@ public: // Support for interprocedural escape analysis, from Thomas Kotzmann. enum EscapeFlag { estimated = 1 << 0, - return_local = 1 << 1 + return_local = 1 << 1, + return_allocated = 1 << 2, + allocated_escapes = 1 << 3, + unknown_modified = 1 << 4 }; intx eflags() { return _eflags; } From 5ac01e984f5f1d9f5be34bb1262d68f4f4ea2d5b Mon Sep 17 00:00:00 2001 From: John Coomes Date: Fri, 28 Mar 2008 23:35:42 -0700 Subject: [PATCH 232/274] 6642862: Code cache allocation fails with large pages after 6588638 Reviewed-by: apetrusenko --- hotspot/src/os/linux/vm/os_linux.cpp | 4 ++++ hotspot/src/os/solaris/vm/os_solaris.cpp | 6 ++++++ hotspot/src/os/windows/vm/os_windows.cpp | 6 +++++- .../gc_implementation/parallelScavenge/parMarkBitMap.cpp | 2 +- .../parallelScavenge/psParallelCompact.cpp | 2 +- hotspot/src/share/vm/memory/heap.cpp | 7 ++++--- hotspot/src/share/vm/runtime/os.hpp | 1 + 7 files changed, 22 insertions(+), 6 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 2a18b3423d1..28289bce61c 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -2480,6 +2480,10 @@ bool os::can_commit_large_page_memory() { return false; } +bool os::can_execute_large_page_memory() { + return false; +} + // Reserve memory at an arbitrary address, only if that area is // available (and not reserved for something else). diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index f4462669218..75ad158a9cd 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -3089,6 +3089,8 @@ bool os::large_page_init() { if (UseISM) { // ISM disables MPSS to be compatible with old JDK behavior UseMPSS = false; + _page_sizes[0] = _large_page_size; + _page_sizes[1] = vm_page_size(); } UseMPSS = UseMPSS && @@ -3178,6 +3180,10 @@ bool os::can_commit_large_page_memory() { return UseISM ? false : true; } +bool os::can_execute_large_page_memory() { + return UseISM ? false : true; +} + static int os_sleep(jlong millis, bool interruptible) { const jlong limit = INT_MAX; jlong prevtime; diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 62e1f7a85c4..8794b3f2d4d 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -2516,9 +2516,13 @@ bool os::can_commit_large_page_memory() { return false; } +bool os::can_execute_large_page_memory() { + return true; +} + char* os::reserve_memory_special(size_t bytes) { DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; - char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_READWRITE); + char * res = (char *)VirtualAlloc(NULL, bytes, flag, PAGE_EXECUTE_READWRITE); return res; } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp index 614a16c4aed..7281b10f7db 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp @@ -41,7 +41,7 @@ ParMarkBitMap::initialize(MemRegion covered_region) const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : MAX2(page_sz, granularity); - ReservedSpace rs(bytes, rs_align, false); + ReservedSpace rs(bytes, rs_align, rs_align > 0); os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz, rs.base(), rs.size()); _virtual_space = new PSVirtualSpace(rs, page_sz); diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 81c2d47a647..d7277b14564 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -413,7 +413,7 @@ ParallelCompactData::create_vspace(size_t count, size_t element_size) const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : MAX2(page_sz, granularity); - ReservedSpace rs(bytes, rs_align, false); + ReservedSpace rs(bytes, rs_align, rs_align > 0); os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(), rs.size()); PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz); diff --git a/hotspot/src/share/vm/memory/heap.cpp b/hotspot/src/share/vm/memory/heap.cpp index c271efb0d3e..c1d43d7ea36 100644 --- a/hotspot/src/share/vm/memory/heap.cpp +++ b/hotspot/src/share/vm/memory/heap.cpp @@ -102,8 +102,9 @@ bool CodeHeap::reserve(size_t reserved_size, size_t committed_size, _log2_segment_size = exact_log2(segment_size); // Reserve and initialize space for _memory. - const size_t page_size = os::page_size_for_region(committed_size, - reserved_size, 8); + const size_t page_size = os::can_execute_large_page_memory() ? + os::page_size_for_region(committed_size, reserved_size, 8) : + os::vm_page_size(); const size_t granularity = os::vm_allocation_granularity(); const size_t r_align = MAX2(page_size, granularity); const size_t r_size = align_size_up(reserved_size, r_align); @@ -111,7 +112,7 @@ bool CodeHeap::reserve(size_t reserved_size, size_t committed_size, const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 : MAX2(page_size, granularity); - ReservedSpace rs(r_size, rs_align, false); + ReservedSpace rs(r_size, rs_align, rs_align > 0); os::trace_page_sizes("code heap", committed_size, reserved_size, page_size, rs.base(), rs.size()); if (!_memory.initialize(rs, c_size)) { diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 9cd4eb4763d..59a057193b0 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -228,6 +228,7 @@ class os: AllStatic { static bool large_page_init(); static size_t large_page_size(); static bool can_commit_large_page_memory(); + static bool can_execute_large_page_memory(); // OS interface to polling page static address get_polling_page() { return _polling_page; } From b63d2cdd275e8c485242bef125aae68fff24f41d Mon Sep 17 00:00:00 2001 From: John Coomes Date: Fri, 28 Mar 2008 23:35:42 -0700 Subject: [PATCH 233/274] 6679422: networkStream::connect() in ostream.cpp is not 64-bit clean Reviewed-by: jmasa, xlu --- hotspot/src/share/vm/utilities/ostream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index d5ad211fc01..1543ff7d715 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -829,7 +829,7 @@ bool networkStream::connect(const char *ip, short port) { server.sin_port = htons(port); server.sin_addr.s_addr = inet_addr(ip); - if (server.sin_addr.s_addr == (unsigned long)-1) { + if (server.sin_addr.s_addr == (uint32_t)-1) { #ifdef _WINDOWS struct hostent* host = hpi::get_host_by_name((char*)ip); #else From 3470103a939d299425cf447679e48deb96815a2b Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Mon, 31 Mar 2008 11:09:57 -0700 Subject: [PATCH 234/274] 6681652: Two new regression test failures in pkcs11 code Fixed the test to not assume SunJCE provider being the provider for DES Reviewed-by: wetmore --- jdk/test/javax/crypto/Cipher/TestGetInstance.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/jdk/test/javax/crypto/Cipher/TestGetInstance.java b/jdk/test/javax/crypto/Cipher/TestGetInstance.java index 736bac9bb2f..125fd4fc255 100644 --- a/jdk/test/javax/crypto/Cipher/TestGetInstance.java +++ b/jdk/test/javax/crypto/Cipher/TestGetInstance.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -46,9 +46,7 @@ public class TestGetInstance { Cipher c; - c = Cipher.getInstance("des"); - same(p, c.getProvider()); - c = Cipher.getInstance("des/cbc/pkcs5padding"); + c = Cipher.getInstance("PBEWithMD5AndTripleDES"); same(p, c.getProvider()); c = Cipher.getInstance("des", "SunJCE"); From b9705263ec8ffdcc001ba2702b153cc9fa94e3e7 Mon Sep 17 00:00:00 2001 From: Chris Phillips Date: Mon, 31 Mar 2008 13:27:10 -0700 Subject: [PATCH 235/274] 6469580: 1.5.0_08 JVM crashes in SignatureHandlerLibrary::add on Fujitsu Primepower platform Reviewed-by: andreas, valeriep, wetmore --- jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c b/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c index 40c38e0640f..ea46ea59c9a 100644 --- a/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c +++ b/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c @@ -123,7 +123,10 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr); (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr); } - if ((C_GetFunctionList == NULL) || ((systemErrorMessage = dlerror()) != NULL)){ + if (C_GetFunctionList == NULL) { + throwIOException(env, "ERROR: C_GetFunctionList == NULL"); + return; + } else if ( (systemErrorMessage = dlerror()) != NULL ){ throwIOException(env, systemErrorMessage); return; } From c10465ee58c938b6af0d3504d3d895e342a26da6 Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Mon, 31 Mar 2008 16:12:37 -0700 Subject: [PATCH 236/274] 6682411: JCK test failed w/ ArrayIndexOutOfBoundException (-1) when decrypting with no data Fixed PKCS5Padding class with additional check and throw BadPaddingException if the check failed Reviewed-by: wetmore --- .../classes/sun/security/pkcs11/P11Cipher.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java index 97e0bb5f64b..918c5ad262d 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java @@ -72,7 +72,7 @@ final class P11Cipher extends CipherSpi { // DEC: return the length of trailing padding bytes given the specified // padded data - int unpad(byte[] paddedData, int ofs, int len) + int unpad(byte[] paddedData, int len) throws BadPaddingException; } @@ -94,14 +94,17 @@ final class P11Cipher extends CipherSpi { return padLen; } - public int unpad(byte[] paddedData, int ofs, int len) + public int unpad(byte[] paddedData, int len) throws BadPaddingException { - byte padValue = paddedData[ofs + len - 1]; + if (len < 1 || len > paddedData.length) { + throw new BadPaddingException("Invalid pad array length!"); + } + byte padValue = paddedData[len - 1]; if (padValue < 1 || padValue > blockSize) { throw new BadPaddingException("Invalid pad value!"); } // sanity check padding bytes - int padStartIndex = ofs + len - padValue; + int padStartIndex = len - padValue; for (int i = padStartIndex; i < len; i++) { if (paddedData[i] != padValue) { throw new BadPaddingException("Invalid pad bytes!"); @@ -712,7 +715,7 @@ final class P11Cipher extends CipherSpi { } k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k, padBuffer.length - k); - int actualPadLen = paddingObj.unpad(padBuffer, 0, k); + int actualPadLen = paddingObj.unpad(padBuffer, k); k -= actualPadLen; System.arraycopy(padBuffer, 0, out, outOfs, k); } else { @@ -781,7 +784,7 @@ final class P11Cipher extends CipherSpi { } k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k, padBuffer.length - k); - int actualPadLen = paddingObj.unpad(padBuffer, 0, k); + int actualPadLen = paddingObj.unpad(padBuffer, k); k -= actualPadLen; outArray = padBuffer; outOfs = 0; From 0397417ad8461a77297771a9d8ec912b1aa84ba4 Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Mon, 31 Mar 2008 16:16:12 -0700 Subject: [PATCH 237/274] 6682417: JCK test failed w/ ProviderException when decrypted data is not multiple of blocks Check for CKR_ENCRYPTED_DATA_LEN_RANGE and throw IllegalBlockSizeException Reviewed-by: wetmore --- jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java index 918c5ad262d..f5da56bec64 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java @@ -817,7 +817,8 @@ final class P11Cipher extends CipherSpi { if (errorCode == CKR_BUFFER_TOO_SMALL) { throw (ShortBufferException) (new ShortBufferException().initCause(e)); - } else if (errorCode == CKR_DATA_LEN_RANGE) { + } else if (errorCode == CKR_DATA_LEN_RANGE || + errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) { throw (IllegalBlockSizeException) (new IllegalBlockSizeException(e.toString()).initCause(e)); } From 1a350ad182a4a21c624adda8e20cca988aaf9965 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 31 Mar 2008 16:22:52 -0700 Subject: [PATCH 238/274] 6636352: Unit tests for supplementary character support fail with -XX:+AggressiveOpts Incorrect encoding Reviewed-by: kvn, rasbold, sgoldman, jrose --- hotspot/src/cpu/sparc/vm/sparc.ad | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index d940498efa5..9360631b077 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -6023,7 +6023,7 @@ instruct cmovII_imm(cmpOp cmp, flagsReg icc, iRegI dst, immI11 src) %{ ins_pipe(ialu_imm); %} -instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{ +instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{ match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); ins_cost(150); size(4); @@ -6032,7 +6032,7 @@ instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{ ins_pipe(ialu_reg); %} -instruct cmovII_U_imm(cmpOp cmp, flagsRegU icc, iRegI dst, immI11 src) %{ +instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{ match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); ins_cost(140); size(4); From ea297b80d982963188f6dfe23597e626c9a85427 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Mon, 31 Mar 2008 17:17:18 -0700 Subject: [PATCH 239/274] 6672405: OPENJDK build: jdk7/jdk/make/tools/freetypecheck leaves dirt behind OpenJDK freetype sanity check cleanup. Reviewed-by: tbell --- jdk/make/common/Defs.gmk | 2 + jdk/make/common/shared/Sanity.gmk | 22 ++++----- jdk/make/tools/Makefile | 2 + jdk/make/tools/freetypecheck/Makefile | 69 ++++++++++++++------------- 4 files changed, 49 insertions(+), 46 deletions(-) diff --git a/jdk/make/common/Defs.gmk b/jdk/make/common/Defs.gmk index 268533ba608..e83095ae917 100644 --- a/jdk/make/common/Defs.gmk +++ b/jdk/make/common/Defs.gmk @@ -303,6 +303,8 @@ BUILDTOOLCLASSDIR = $(OUTPUTDIR)/btclasses # for build tool jar files BUILDTOOLJARDIR = $(OUTPUTDIR)/btjars ABS_BUILDTOOLJARDIR = $(ABS_OUTPUTDIR)/btjars +# for generated tool class files +BUILDTOOLBINDIR = $(OUTPUTDIR)/btbins # for generated java source files GENSRCDIR = $(OUTPUTDIR)/gensrc # for generated C source files (not javah) diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk index 9f6bd2a55ab..98bd5b4346c 100644 --- a/jdk/make/common/shared/Sanity.gmk +++ b/jdk/make/common/shared/Sanity.gmk @@ -788,21 +788,17 @@ sane-cacerts: ifdef OPENJDK -#name of test program that prints out "Failed" if freetype is not good enough -FREETYPE_VERSION_CHECK_NAME = freetype_versioncheck -FREETYPE_VERSION_CHECK = $(TEMPDIR)/$(FREETYPE_VERSION_CHECK_NAME)$(EXE_SUFFIX) +# The freetypecheck Makefile prints out "Failed" if not good enough +$(TEMPDIR)/freetypeinfo: FRC + @$(prep-target) + @(($(CD) $(BUILDDIR)/tools/freetypecheck && $(MAKE)) || \ + $(ECHO) "Failed to build freetypecheck." ) > $@ -sane-freetype: - @-($(CD) $(BUILDDIR)/tools/freetypecheck && \ - $(MAKE) REQUIRED_FREETYPE_VERSION=$(REQUIRED_FREETYPE_VERSION) \ - FT_TEST=$(FREETYPE_VERSION_CHECK_NAME) \ - FT_HEADERS=$(FREETYPE_HEADERS_PATH) \ - FT_LIB=$(FREETYPE_LIB_PATH) \ - XARCH=$(XARCH)) - @if [ ! -r $(FREETYPE_VERSION_CHECK) -o \ - "`$(FREETYPE_VERSION_CHECK) | $(GREP) Fail`" != "" ]; then \ +sane-freetype: $(TEMPDIR)/freetypeinfo + @if [ "`$(CAT) $< | $(GREP) Fail`" != "" ]; then \ $(ECHO) "ERROR: FreeType version " $(REQUIRED_FREETYPE_VERSION) \ - "or higher is required. \n" >> $(ERROR_FILE) ; \ + " or higher is required. \n" \ + "`$(CAT) $<` \n" >> $(ERROR_FILE) ; \ fi else diff --git a/jdk/make/tools/Makefile b/jdk/make/tools/Makefile index 0428e3c5585..3bc1cacd0ff 100644 --- a/jdk/make/tools/Makefile +++ b/jdk/make/tools/Makefile @@ -40,6 +40,7 @@ SUBDIRS = \ dir_diff \ dtdbuilder \ fontchecker \ + freetypecheck \ generate_break_iterator \ GenerateCharacter \ generatecurrencydata \ @@ -58,4 +59,5 @@ all build clean clobber:: clean clobber:: $(RM) -r $(BUILDTOOLCLASSDIR) $(RM) -r $(BUILDTOOLJARDIR) + $(RM) -r $(BUILDTOOLBINDIR) diff --git a/jdk/make/tools/freetypecheck/Makefile b/jdk/make/tools/freetypecheck/Makefile index 7bcfe6300c1..c96854309f2 100644 --- a/jdk/make/tools/freetypecheck/Makefile +++ b/jdk/make/tools/freetypecheck/Makefile @@ -22,55 +22,58 @@ # CA 95054 USA or visit www.sun.com if you need additional information or # have any questions. -# Builds test program for freetype sanity check. -# -# Makefile should be called with following input parameters -# FT_TEST - full name of test program -# FT_HEADERS - path to freetype headers -# FT_LIB - location of directory with library -# XARCH - xarch option if required +# Builds and runs test program for freetype sanity check. BUILDDIR = ../.. include $(BUILDDIR)/common/Defs.gmk -#test program is expected in the TEMPDIR -FT_TEST_PATH = $(TEMPDIR)/$(FT_TEST) +# Default name +FT_TEST = $(BUILDTOOLBINDIR)/freetype_versioncheck$(EXE_SUFFIX) -all: $(FT_TEST_PATH) +# Used on openjdk only +ifeq ($(OPENJDK),true) # Start with CFLAGS (which gets us the required -xarch setting on solaris) ifeq ($(PLATFORM), windows) - FT_OPTIONS = + FT_OPTIONS = /nologo $(CC_OBJECT_OUTPUT_FLAG)$(TEMPDIR) + FREETYPE_DLL = $(FREETYPE_LIB_PATH)/freetype.dll + FT_LD_OPTIONS = $(FREETYPE_LIB_PATH)/freetype.lib else FT_OPTIONS = $(CFLAGS) -endif - -FT_OPTIONS += -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2 -FT_OPTIONS += $(XARCH) - -#add runtime library search path -ifeq ($(PLATFORM), windows) - FREETYPE_LIB=$(FT_LIB)/freetype.lib - FREETYPE_DLL=$(FT_LIB)/freetype.dll - DFLAG=/D -else - FT_OPTIONS += -L$(FT_LIB) - DFLAG = -D - - #add runtime lib search path to ensure test will be runnable + FT_LD_OPTIONS = -L$(FREETYPE_LIB_PATH) + # Add runtime lib search path to ensure test will be runnable ifeq ($(PLATFORM), solaris) - FT_OPTIONS += -R $(FT_LIB) -lfreetype + FT_LD_OPTIONS += -R $(FREETYPE_LIB_PATH) -lfreetype else #linux - FT_OPTIONS += -Wl,-rpath -Wl,$(FT_LIB) -lfreetype + FT_LD_OPTIONS += -Wl,-rpath -Wl,$(FREETYPE_LIB_PATH) -lfreetype endif endif +FT_OPTIONS += -I$(FREETYPE_HEADERS_PATH) +FT_OPTIONS += -I$(FREETYPE_HEADERS_PATH)/freetype2 +FT_OPTIONS += -DREQUIRED_FREETYPE_VERSION=$(REQUIRED_FREETYPE_VERSION) +FT_LD_OPTIONS += $(LFLAGS_$(COMPILER_VERSION)) -FT_OPTIONS += $(DFLAG)REQUIRED_FREETYPE_VERSION=$(REQUIRED_FREETYPE_VERSION) +# Create test program +all: $(FT_TEST) + @$(FT_TEST) -# On windows we need to copy dll to test dir -# ti ensure it will be found in runtime -$(FT_TEST_PATH): freetypecheck.c - @$(CC) $(FT_OPTIONS) $(CC_PROGRAM_OUTPUT_FLAG)$@ $< $(FREETYPE_LIB) $(LFLAGS_$(COMPILER_VERSION)) +# On windows we need to copy dll to test dir to ensure it will be found +# at runtime +$(FT_TEST): freetypecheck.c + @$(prep-target) + @$(CC) $(FT_OPTIONS) $(CC_PROGRAM_OUTPUT_FLAG)$@ $< $(FT_LD_OPTIONS) ifeq ($(PLATFORM), windows) @$(CP) $(FREETYPE_DLL) `dirname $@` endif + +else + +# Inform user this is openjdk only +all: + @$(ECHO) "The freetype files are only used with OpenJDK" + +endif + +clean:: + $(RM) $(FT_TEST) + From 298642faa153738786cc08acfd0844111ae6749c Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Mon, 31 Mar 2008 17:19:06 -0700 Subject: [PATCH 240/274] 6482445: j2se/make/java/java/localegen.sh uses 'sort' from PATH, could get system32/sort Making sure the right 'sort' utility is found. Reviewed-by: tbell --- jdk/make/java/java/genlocales.gmk | 3 ++- jdk/make/java/java/localegen.sh | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/jdk/make/java/java/genlocales.gmk b/jdk/make/java/java/genlocales.gmk index 05ad9f36dd5..8ea0a0f2559 100644 --- a/jdk/make/java/java/genlocales.gmk +++ b/jdk/make/java/java/genlocales.gmk @@ -80,7 +80,8 @@ $(LocaleDataMetaInfo_Dest):$(LocaleDataMetaInfo_Src) $(LOCALEGEN_SH) @$(ECHO) $(subst .java,'\n',$(Euro_Resources_java)) >> $@.tmp.euro; @$(ECHO) $(subst .properties,'\n',$(NonEuro_Resources_properties)) > $@.tmp.noneuro; @$(ECHO) $(subst .java,'\n',$(NonEuro_Resources_java)) >> $@.tmp.noneuro; - NAWK=$(NAWK) SED=$(SED) $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.euro \ + NAWK="$(NAWK)" SED="$(SED)" SORT="$(SORT)" \ + $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.euro \ $@.tmp.noneuro $< $@ @$(RM) $@.tmp.euro $@.tmp.noneuro; diff --git a/jdk/make/java/java/localegen.sh b/jdk/make/java/java/localegen.sh index 70e26838bc4..b4506b97854 100644 --- a/jdk/make/java/java/localegen.sh +++ b/jdk/make/java/java/localegen.sh @@ -29,7 +29,7 @@ # This script is to generate the supported locale list string and replace the # LocaleDataMetaInfo-XLocales.java in /src/share/classes/sun/util # -# NAWK & SED is passed in as environment variables. +# SORT, NAWK & SED is passed in as environment variables. # # A list of resource base name list; @@ -47,7 +47,7 @@ OUTPUT_FILE=$5 localelist= getlocalelist() { localelist="" - localelist=`$NAWK -F$1_ '{print $2}' $2 | sort` + localelist=`$NAWK -F$1_ '{print $2}' $2 | $SORT` } sed_script="$SED -e \"s@^#warn .*@// -- This file was mechanically generated: Do not edit! -- //@\" " From 4a807d5ed375231b1eb5f5ad686cf749e5b0f481 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Mon, 31 Mar 2008 17:20:48 -0700 Subject: [PATCH 241/274] 6501543: Username can have non-alphanumeric characters User version string issues, including a L10n issue with month names. Reviewed-by: tbell --- jdk/make/common/shared/Defs.gmk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jdk/make/common/shared/Defs.gmk b/jdk/make/common/shared/Defs.gmk index 6b0adfcb533..811c87df1e8 100644 --- a/jdk/make/common/shared/Defs.gmk +++ b/jdk/make/common/shared/Defs.gmk @@ -265,7 +265,9 @@ ifdef BUILD_NUMBER FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER) else BUILD_NUMBER = b00 - USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`) + BUILD_DATE := $(shell $(DATE) '+%Y_%m_%d_%H_%M') + CLEAN_USERNAME := $(shell $(ECHO) "$(USER)" | $(TR) -d -c '[:alnum:]') + USER_RELEASE_SUFFIX := $(shell $(ECHO) "$(CLEAN_USERNAME)_$(BUILD_DATE)" | $(TR) '[:upper:]' '[:lower:]' ) FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER) endif From 833746644c41b9ca60963c7a9d129571955b5de2 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Mon, 31 Mar 2008 18:37:36 -0700 Subject: [PATCH 242/274] 6682236: C2 hits ideal nodes limit during IGVN optimization with EA Missing check in LoadNode::Ideal() causes infinite generation of a value Phi. Reviewed-by: jrose, never --- hotspot/src/share/vm/opto/memnode.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index d3027cec715..df47ccb0e96 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1122,6 +1122,12 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { } // Split through Phi (see original code in loopopts.cpp). assert(phase->C->have_alias_type(addr_t), "instance should have alias type"); + + // Do nothing here if Identity will find a value + // (to avoid infinite chain of value phis generation). + if ( !phase->eqv(this, this->Identity(phase)) ) + return NULL; + const Type* this_type = this->bottom_type(); int this_index = phase->C->get_alias_index(addr_t); int this_offset = addr_t->offset(); From 332059a5554e9119861041a5e9efa66ec61a0aac Mon Sep 17 00:00:00 2001 From: Eamonn McManus Date: Tue, 1 Apr 2008 14:45:23 +0200 Subject: [PATCH 243/274] 6610917: Define a generic NotificationFilter Adds javax.management.QueryNotificationFilter Reviewed-by: dfuchs --- .../DefaultMBeanServerInterceptor.java | 17 +- .../sun/jmx/mbeanserver/MBeanAnalyzer.java | 20 +- .../jmx/mbeanserver/MBeanIntrospector.java | 14 + .../mbeanserver/NotificationMBeanSupport.java | 81 ++++ .../sun/jmx/mbeanserver/OpenConverter.java | 2 +- .../com/sun/jmx/mbeanserver/Repository.java | 13 +- .../classes/com/sun/jmx/mbeanserver/Util.java | 10 + .../classes/javax/management/ObjectName.java | 17 +- .../management/QueryNotificationFilter.java | 417 ++++++++++++++++++ .../query/QueryNotifFilterTest.java | 347 +++++++++++++++ 10 files changed, 885 insertions(+), 53 deletions(-) create mode 100644 jdk/src/share/classes/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java create mode 100644 jdk/src/share/classes/javax/management/QueryNotificationFilter.java create mode 100644 jdk/test/javax/management/query/QueryNotifFilterTest.java diff --git a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java index a637aa14745..eea8d4309eb 100644 --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java @@ -34,8 +34,6 @@ import java.util.Set; import java.util.HashSet; import java.util.WeakHashMap; import java.lang.ref.WeakReference; -import java.io.PrintWriter; -import java.io.StringWriter; import java.security.AccessControlContext; import java.security.Permission; import java.security.ProtectionDomain; @@ -51,7 +49,6 @@ import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.InvalidAttributeValueException; -import javax.management.JMException; import javax.management.JMRuntimeException; import javax.management.ListenerNotFoundException; import javax.management.MalformedObjectNameException; @@ -84,11 +81,10 @@ import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; import com.sun.jmx.mbeanserver.DynamicMBean2; import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; import com.sun.jmx.mbeanserver.MBeanInstantiator; -import com.sun.jmx.mbeanserver.MXBeanSupport; import com.sun.jmx.mbeanserver.Repository; import com.sun.jmx.mbeanserver.NamedObject; -import com.sun.jmx.defaults.ServiceName; import com.sun.jmx.mbeanserver.Introspector; +import com.sun.jmx.mbeanserver.Util; import com.sun.jmx.remote.util.EnvHelp; /** @@ -623,18 +619,9 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { List result = new ArrayList(domains.length); for (int i = 0; i < domains.length; i++) { try { - ObjectName domain = new ObjectName(domains[i] + ":x=x"); + ObjectName domain = Util.newObjectName(domains[i] + ":x=x"); checkMBeanPermission((String) null, null, domain, "getDomains"); result.add(domains[i]); - } catch (MalformedObjectNameException e) { - // Should never occur... But let's log it just in case. - if (MBEANSERVER_LOGGER.isLoggable(Level.SEVERE)) { - MBEANSERVER_LOGGER.logp(Level.SEVERE, - DefaultMBeanServerInterceptor.class.getName(), - "getDomains", - "Failed to check permission for domain = " + - domains[i], e); - } } catch (SecurityException e) { // OK: Do not add this domain to the list } diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java index f908a352a2b..5975f1a391b 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java @@ -107,10 +107,7 @@ class MBeanAnalyzer { private MBeanAnalyzer(Class mbeanInterface, MBeanIntrospector introspector) throws NotCompliantMBeanException { - if (!mbeanInterface.isInterface()) { - throw new NotCompliantMBeanException("Not an interface: " + - mbeanInterface.getName()); - } + introspector.checkCompliance(mbeanInterface); try { initMaps(mbeanInterface, introspector); @@ -121,11 +118,10 @@ class MBeanAnalyzer { // Introspect the mbeanInterface and initialize this object's maps. // - private void initMaps(Class mbeanInterface, + private void initMaps(Class mbeanType, MBeanIntrospector introspector) throws Exception { - final Method[] methodArray = mbeanInterface.getMethods(); - - final List methods = eliminateCovariantMethods(methodArray); + final List methods1 = introspector.getMethods(mbeanType); + final List methods = eliminateCovariantMethods(methods1); /* Run through the methods to detect inconsistencies and to enable us to give getter and setter together to visitAttribute. */ @@ -234,13 +230,13 @@ class MBeanAnalyzer { but existing code may depend on it and users may be used to seeing operations or attributes appear in a particular order. */ static List - eliminateCovariantMethods(Method[] methodArray) { + eliminateCovariantMethods(List startMethods) { // We are assuming that you never have very many methods with the // same name, so it is OK to use algorithms that are quadratic // in the number of methods with the same name. - final int len = methodArray.length; - final Method[] sorted = methodArray.clone(); + final int len = startMethods.size(); + final Method[] sorted = startMethods.toArray(new Method[len]); Arrays.sort(sorted,MethodOrder.instance); final Set overridden = newSet(); for (int i=1;i { } } - final List methods = newList(Arrays.asList(methodArray)); + final List methods = newList(startMethods); methods.removeAll(overridden); return methods; } diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java index c191005d621..ea7dbdade33 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java @@ -34,6 +34,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.util.Arrays; import java.util.List; import java.util.WeakHashMap; @@ -169,6 +170,19 @@ abstract class MBeanIntrospector { */ abstract Descriptor getMBeanDescriptor(Class resourceClass); + void checkCompliance(Class mbeanType) throws NotCompliantMBeanException { + if (!mbeanType.isInterface()) { + throw new NotCompliantMBeanException("Not an interface: " + + mbeanType.getName()); + } + } + + /** + * Get the methods to be analyzed to build the MBean interface. + */ + List getMethods(final Class mbeanType) throws Exception { + return Arrays.asList(mbeanType.getMethods()); + } final PerInterface getPerInterface(Class mbeanInterface) throws NotCompliantMBeanException { diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java new file mode 100644 index 00000000000..f1e3a13c891 --- /dev/null +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotificationMBeanSupport.java @@ -0,0 +1,81 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package com.sun.jmx.mbeanserver; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import javax.management.NotCompliantMBeanException; +import javax.management.Notification; + +/** + *

    A variant of {@code StandardMBeanSupport} where the only + * methods included are public getters. This is used by + * {@code QueryNotificationFilter} to pretend that a Notification is + * an MBean so it can have a query evaluated on it. Standard queries + * never set attributes or invoke methods but custom queries could and + * we don't want to allow that. Also we don't want to fail if a + * Notification happens to have inconsistent types in a pair of getX and + * setX methods, and we want to include the Object.getClass() method. + */ +public class NotificationMBeanSupport extends StandardMBeanSupport { + public NotificationMBeanSupport(T n) + throws NotCompliantMBeanException { + super(n, Util.>cast(n.getClass())); + } + + @Override + MBeanIntrospector getMBeanIntrospector() { + return introspector; + } + + private static class Introspector extends StandardMBeanIntrospector { + @Override + void checkCompliance(Class mbeanType) {} + + @Override + List getMethods(final Class mbeanType) + throws Exception { + List methods = new ArrayList(); + for (Method m : mbeanType.getMethods()) { + String name = m.getName(); + Class ret = m.getReturnType(); + if (m.getParameterTypes().length == 0) { + if ((name.startsWith("is") && name.length() > 2 && + ret == boolean.class) || + (name.startsWith("get") && name.length() > 3 && + ret != void.class)) { + methods.add(m); + } + } + } + return methods; + } + + } + private static final MBeanIntrospector introspector = + new Introspector(); +} diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/OpenConverter.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/OpenConverter.java index ccd0ed57bf5..25ac0a28e10 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/OpenConverter.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/OpenConverter.java @@ -438,7 +438,7 @@ public abstract class OpenConverter { c.getClassLoader() == null); final List methods = - MBeanAnalyzer.eliminateCovariantMethods(c.getMethods()); + MBeanAnalyzer.eliminateCovariantMethods(Arrays.asList(c.getMethods())); final SortedMap getterMap = newSortedMap(); /* Select public methods that look like "T getX()" or "boolean diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java index e33492d945e..38a1fc6d4f4 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java @@ -415,17 +415,8 @@ public class Repository { boolean to_default_domain = false; // Set domain to default if domain is empty and not already set - if (dom.length() == 0) { - try { - name = new ObjectName(domain + name.toString()); - } catch (MalformedObjectNameException e) { - if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) { - MBEANSERVER_LOGGER.logp(Level.FINEST, - Repository.class.getName(), "addMBean", - "Unexpected MalformedObjectNameException", e); - } - } - } + if (dom.length() == 0) + name = Util.newObjectName(domain + name.toString()); // Do we have default domain ? if (dom == domain) { diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java index 712b4e378a8..f2dbe60bbdf 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java @@ -38,6 +38,8 @@ import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; public class Util { static Map newMap() { @@ -85,6 +87,14 @@ public class Util { return new ArrayList(c); } + public static ObjectName newObjectName(String s) { + try { + return new ObjectName(s); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e); + } + } + /* This method can be used by code that is deliberately violating the * allowed checked casts. Rather than marking the whole method containing * the code with @SuppressWarnings, you can use a call to this method for diff --git a/jdk/src/share/classes/javax/management/ObjectName.java b/jdk/src/share/classes/javax/management/ObjectName.java index cef869510b1..ff11962b666 100644 --- a/jdk/src/share/classes/javax/management/ObjectName.java +++ b/jdk/src/share/classes/javax/management/ObjectName.java @@ -26,6 +26,7 @@ package javax.management; import com.sun.jmx.mbeanserver.GetPropertyAction; +import com.sun.jmx.mbeanserver.Util; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; @@ -1386,12 +1387,7 @@ public class ObjectName extends ToQueryString throws NullPointerException { if (name.getClass().equals(ObjectName.class)) return name; - try { - return new ObjectName(name.getSerializedNameString()); - } catch (MalformedObjectNameException e) { - throw new IllegalArgumentException("Unexpected: " + e); - // can't happen - } + return Util.newObjectName(name.getSerializedNameString()); } /** @@ -1950,14 +1946,7 @@ public class ObjectName extends ToQueryString * * @since 1.6 */ - public static final ObjectName WILDCARD; - static { - try { - WILDCARD = new ObjectName("*:*"); - } catch (MalformedObjectNameException e) { - throw new Error("Can't initialize wildcard name", e); - } - } + public static final ObjectName WILDCARD = Util.newObjectName("*:*"); // Category : Utilities <=================================== diff --git a/jdk/src/share/classes/javax/management/QueryNotificationFilter.java b/jdk/src/share/classes/javax/management/QueryNotificationFilter.java new file mode 100644 index 00000000000..c6c10393902 --- /dev/null +++ b/jdk/src/share/classes/javax/management/QueryNotificationFilter.java @@ -0,0 +1,417 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * 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. + */ + +package javax.management; + +import com.sun.jmx.mbeanserver.NotificationMBeanSupport; +import com.sun.jmx.mbeanserver.Util; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Collections; +import java.util.Set; + +/** + *

    General-purpose notification filter. This filter can be used to + * filter notifications from a possibly-remote MBean. Most filtering + * decisions can be coded using this filter, which avoids having to + * write a custom implementation of the {@link NotificationFilter} + * class. Writing a custom implementation requires you to deploy it + * on both the client and the server in the remote case, so using this class + * instead is recommended where possible.

    + * + * + * + *

    This class uses the {@linkplain Query Query API} to specify the + * filtering logic. For example, to select only notifications where the + * {@linkplain Notification#getType() type} is {@code "com.example.mytype"}, + * you could use

    + * + *
    + * NotificationFilter filter =
    + *     new QueryNotificationFilter("Type = 'com.example.mytype'");
    + * 
    + * + *

    or equivalently

    + * + *
    + * NotificationFilter filter =
    + *     new QueryNotificationFilter(
    + *             Query.eq(Query.attr("Type"), Query.value("com.example.mytype")));
    + * 
    + * + *

    (This particular example could also use + * {@link NotificationFilterSupport}.)

    + * + *

    Here are some other examples of filters you can specify with this class.

    + * + *
    + * + *
    {@code QueryNotificationFilter("Type = 'com.example.type1' or + * Type = 'com.example.type2'")} + *
    Notifications where the type is either of the given strings. + * + *
    {@code QueryNotificationFilter("Type in ('com.example.type1', + * 'com.example.type2')")} + *
    Another way to write the previous example. + * + *
    {@code QueryNotificationFilter("SequenceNumber > 1000")} + *
    Notifications where the {@linkplain Notification#getSequenceNumber() + * sequence number} is greater than 1000. + * + *
    {@code QueryNotificationFilter(AttributeChangeNotification.class, null)} + *
    Notifications where the notification class is + * {@link AttributeChangeNotification} or a subclass of it. + * + *
    {@code QueryNotificationFilter(AttributeChangeNotification.class, + * "AttributeName = 'Size'")} + *
    Notifications where the notification class is + * {@link AttributeChangeNotification} or a subclass, and where the + * {@linkplain AttributeChangeNotification#getAttributeName() name of the + * changed attribute} is {@code Size}. + * + *
    {@code QueryNotificationFilter(AttributeChangeNotification.class, + * "AttributeName = 'Size' and NewValue - OldValue > 100")} + *
    As above, but the difference between the + * {@linkplain AttributeChangeNotification#getNewValue() new value} and the + * {@linkplain AttributeChangeNotification#getOldValue() old value} must be + * greater than 100. + * + *
    {@code QueryNotificationFilter("like 'com.example.mydomain:*'")} + *
    Notifications where the {@linkplain Notification#getSource() source} + * is an ObjectName that matches the pattern. + * + *
    {@code QueryNotificationFilter("Source.canonicalName like + * 'com.example.mydomain:%'")} + *
    Another way to write the previous example. + * + *
    {@code QueryNotificationFilter(MBeanServerNotification.class, + * "Type = 'JMX.mbean.registered' and MBeanName.canonicalName like + * 'com.example.mydomain:%'")} + *
    Notifications of class {@link MBeanServerNotification} representing + * an object registered in the domain {@code com.example.mydomain}. + * + *
    + * + *

    How it works

    + * + *

    Although the examples above are clear, looking closely at the + * Query API reveals a subtlety. A {@link QueryExp} is evaluated on + * an {@link ObjectName}, not a {@code Notification}.

    + * + *

    Every time a {@code Notification} is to be filtered by a + * {@code QueryNotificationFilter}, a special {@link MBeanServer} is created. + * This {@code MBeanServer} contains exactly one MBean, which represents the + * {@code Notification}. If the {@linkplain Notification#getSource() + * source} of the notification is an {@code ObjectName}, which is + * recommended practice, then the name of the MBean representing the + * {@code Notification} will be this {@code ObjectName}. Otherwise the + * name is unspecified.

    + * + *

    The query specified in the {@code QueryNotificationFilter} constructor + * is evaluated against this {@code MBeanServer} and {@code ObjectName}, + * and the filter returns true if and only if the query does. If the + * query throws an exception, then the filter will return false.

    + * + *

    The MBean representing the {@code Notification} has one attribute for + * every property of the {@code Notification}. Specifically, for every public + * method {@code T getX()} in the {@code NotificationClass}, the MBean will + * have an attribute called {@code X} of type {@code T}. For example, if the + * {@code Notification} is an {@code AttributeChangeNotification}, then the + * MBean will have an attribute called {@code AttributeName} of type + * {@code "java.lang.String"}, corresponding to the method {@link + * AttributeChangeNotification#getAttributeName}.

    + * + *

    Query evaluation usually involves calls to the methods of {@code + * MBeanServer}. The methods have the following behavior:

    + * + *
      + *
    • The {@link MBeanServer#getAttribute getAttribute} method returns the + * value of the corresponding property. + *
    • The {@link MBeanServer#getObjectInstance getObjectInstance} + * method returns an {@link ObjectInstance} where the {@link + * ObjectInstance#getObjectName ObjectName} is the name of the MBean and the + * {@link ObjectInstance#getClassName ClassName} is the class name of the + * {@code Notification}. + *
    • The {@link MBeanServer#isInstanceOf isInstanceOf} method returns true + * if and only if the {@code Notification}'s {@code ClassLoader} can load the + * named class, and the {@code Notification} is an {@linkplain Class#isInstance + * instance} of that class. + *
    + * + *

    These are the only {@code MBeanServer} methods that are needed to + * evaluate standard queries. The behavior of the other {@code MBeanServer} + * methods is unspecified.

    + * + * @since 1.7 + */ +public class QueryNotificationFilter implements NotificationFilter { + private static final long serialVersionUID = -8408613922660635231L; + + private static final ObjectName DEFAULT_NAME = + Util.newObjectName(":type=Notification"); + private static final QueryExp trueQuery; + static { + ValueExp zero = Query.value(0); + trueQuery = Query.eq(zero, zero); + } + + private final QueryExp query; + + /** + * Construct a {@code QueryNotificationFilter} that evaluates the given + * {@code QueryExp} to determine whether to accept a notification. + * + * @param query the {@code QueryExp} to evaluate. Can be null, + * in which case all notifications are accepted. + */ + public QueryNotificationFilter(QueryExp query) { + if (query == null) + this.query = trueQuery; + else + this.query = query; + } + + /** + * Construct a {@code QueryNotificationFilter} that evaluates the query + * in the given string to determine whether to accept a notification. + * The string is converted into a {@code QueryExp} using + * {@link Query#fromString Query.fromString}. + * + * @param query the string specifying the query to evaluate. Can be null, + * in which case all notifications are accepted. + * + * @throws IllegalArgumentException if the string is not a valid + * query string. + */ + public QueryNotificationFilter(String query) { + this(Query.fromString(query)); + } + + /** + *

    Construct a {@code QueryNotificationFilter} that evaluates the query + * in the given string to determine whether to accept a notification, + * and where the notification must also be an instance of the given class. + * The string is converted into a {@code QueryExp} using + * {@link Query#fromString Query.fromString}.

    + * + * @param notifClass the class that the notification must be an instance of. + * Cannot be null. + * + * @param query the string specifying the query to evaluate. Can be null, + * in which case all notifications are accepted. + * + * @throws IllegalArgumentException if the string is not a valid + * query string, or if {@code notifClass} is null. + */ + public QueryNotificationFilter( + Class notifClass, String query) { + this(Query.and(Query.isInstanceOf(Query.value(notNull(notifClass).getName())), + Query.fromString(query))); + } + + private static T notNull(T x) { + if (x == null) + throw new IllegalArgumentException("Null argument"); + return x; + } + + /** + * Retrieve the query that this notification filter will evaluate for + * each notification. + * + * @return the query. + */ + public QueryExp getQuery() { + return query; + } + + public boolean isNotificationEnabled(Notification notification) { + ObjectName name; + + Object source = notification.getSource(); + if (source instanceof ObjectName) + name = (ObjectName) source; + else + name = DEFAULT_NAME; + + MBS mbsImpl = new MBS(notification, name); + MBeanServer mbs = (MBeanServer) Proxy.newProxyInstance( + MBeanServer.class.getClassLoader(), + new Class[] {MBeanServer.class}, + new ForwardIH(mbsImpl)); + return evalQuery(query, mbs, name); + } + + private static boolean evalQuery( + QueryExp query, MBeanServer mbs, ObjectName name) { + MBeanServer oldMBS = QueryEval.getMBeanServer(); + try { + if (mbs != null) + query.setMBeanServer(mbs); + return query.apply(name); + } catch (Exception e) { + return false; + } finally { + query.setMBeanServer(oldMBS); + } + } + + private static class ForwardIH implements InvocationHandler { + private final MBS mbs; + + ForwardIH(MBS mbs) { + this.mbs = mbs; + } + + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + Method forward; + try { + forward = MBS.class.getMethod( + method.getName(), method.getParameterTypes()); + } catch (NoSuchMethodException e) { + throw new UnsupportedOperationException(method.getName()); + } + try { + return forward.invoke(mbs, args); + } catch (InvocationTargetException e) { + throw e.getCause(); + } + } + } + + private static class MBS { + private final Notification notification; + private final ObjectName objectName; + private final ObjectInstance objectInstance; + private volatile DynamicMBean mbean; + + MBS(Notification n, ObjectName name) { + this.notification = n; + this.objectName = name; + this.objectInstance = new ObjectInstance(name, n.getClass().getName()); + } + + private void checkName(ObjectName name) throws InstanceNotFoundException { + if (!objectName.equals(name)) + throw new InstanceNotFoundException(String.valueOf(name)); + } + + private DynamicMBean mbean(ObjectName name) + throws InstanceNotFoundException, ReflectionException { + if (mbean == null) { + try { + mbean = new NotificationMBeanSupport(notification); + } catch (NotCompliantMBeanException e) { + throw new ReflectionException(e); + } + } + return mbean; + } + + public ObjectInstance getObjectInstance(ObjectName name) + throws InstanceNotFoundException { + checkName(name); + return objectInstance; + } + + public Set queryMBeans(ObjectName name, QueryExp query) { + Set names = queryNames(name, query); + switch (names.size()) { + case 0: + return Collections.emptySet(); + case 1: + return Collections.singleton(objectInstance); + default: + throw new UnsupportedOperationException("Internal error"); + } + } + + public Set queryNames(ObjectName name, QueryExp query) { + if ((name != null && !name.apply(objectName)) || + (query != null && !evalQuery(query, null, name))) + return Collections.emptySet(); + return Collections.singleton(objectName); + } + + public boolean isRegistered(ObjectName name) { + return objectName.equals(name); + } + + public Integer getMBeanCount() { + return 1; + } + + public Object getAttribute(ObjectName name, String attribute) + throws MBeanException, AttributeNotFoundException, + InstanceNotFoundException, ReflectionException { + return mbean(name).getAttribute(attribute); + } + + public AttributeList getAttributes(ObjectName name, String[] attributes) + throws InstanceNotFoundException, ReflectionException { + return mbean(name).getAttributes(attributes); + } + + public String getDefaultDomain() { + return objectName.getDomain(); + } + + public String[] getDomains() { + return new String[] {objectName.getDomain()}; + } + + public MBeanInfo getMBeanInfo(ObjectName name) + throws InstanceNotFoundException, ReflectionException { + return mbean(name).getMBeanInfo(); + } + + public boolean isInstanceOf(ObjectName name, String className) + throws InstanceNotFoundException { + try { + mbean(name); + ClassLoader loader = notification.getClass().getClassLoader(); + Class c = Class.forName(className, false, loader); + return c.isInstance(notification); + } catch (ReflectionException e) { + return false; + } catch (ClassNotFoundException e) { + return false; + } + } + + public ClassLoader getClassLoaderFor(ObjectName mbeanName) + throws InstanceNotFoundException { + checkName(mbeanName); + return notification.getClass().getClassLoader(); + } + } +} diff --git a/jdk/test/javax/management/query/QueryNotifFilterTest.java b/jdk/test/javax/management/query/QueryNotifFilterTest.java new file mode 100644 index 00000000000..b22bf1baa5f --- /dev/null +++ b/jdk/test/javax/management/query/QueryNotifFilterTest.java @@ -0,0 +1,347 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. 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 QueryNotifFilterTest + * @bug 6610917 + * @summary Test the QueryNotificationFilter class + * @author Eamonn McManus + */ + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.management.Attribute; +import javax.management.AttributeChangeNotification; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.Notification; +import javax.management.NotificationFilter; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.QueryEval; +import javax.management.QueryExp; +import javax.management.QueryNotificationFilter; + +public class QueryNotifFilterTest { + private static class Case { + final Notification notif; + final QueryExp query; + final boolean expect; + final Class notifClass; + Case(Notification notif, String query, boolean expect) { + this(notif, query, notif.getClass(), expect); + } + Case(Notification notif, String query, + Class notifClass, boolean expect) { + this(notif, Query.fromString(query), notifClass, expect); + } + Case(Notification notif, QueryExp query, boolean expect) { + this(notif, query, notif.getClass(), expect); + } + Case(Notification notif, QueryExp query, + Class notifClass, boolean expect) { + this.notif = notif; + this.query = query; + this.expect = expect; + this.notifClass = notifClass; + } + } + + /* In principle users can create their own implementations of QueryExp + * and use them with QueryNotificationFilter. If they do so, then + * they can call any MBeanServer method. Not all of those methods + * will work with the special MBeanServer we concoct to analyze a + * Notification, but some will, including some that are not called + * by the standard queries. So we check each of those cases too. + */ + private static class ExoticCase { + final Notification trueNotif; + final Notification falseNotif; + final QueryExp query; + ExoticCase(Notification trueNotif, Notification falseNotif, QueryExp query) { + this.trueNotif = trueNotif; + this.falseNotif = falseNotif; + this.query = query; + } + } + + private static abstract class ExoticQuery + extends QueryEval implements QueryExp { + private final String queryString; + ExoticQuery(String queryString) { + this.queryString = queryString; + } + abstract boolean apply(MBeanServer mbs, ObjectName name) throws Exception; + @Override + public boolean apply(ObjectName name) { + try { + return apply(getMBeanServer(), name); + } catch (Exception e) { + e.printStackTrace(System.out); + return false; + } + } + @Override + public String toString() { + return queryString; + } + } + + private static ObjectName makeObjectName(String s) { + try { + return new ObjectName(s); + } catch (MalformedObjectNameException e) { + throw new RuntimeException(e); + } + } + + public static class CustomNotification extends Notification { + public CustomNotification(String type, Object source, long seqNo) { + super(type, source, seqNo); + } + + public String getName() { + return "claude"; + } + + public boolean isInteresting() { + return true; + } + } + + private static final Notification simpleNotif = + new Notification("mytype", "source", 0L); + private static final Notification attrChangeNotif = + new AttributeChangeNotification( + "x", 0L, 0L, "msg", "AttrName", "int", 2, 3); + private static final ObjectName testObjectName = makeObjectName("a:b=c"); + private static final Notification sourcedNotif = + new Notification("mytype", testObjectName, 0L); + private static final Notification customNotif = + new CustomNotification("mytype", testObjectName, 0L); + + private static final Case[] testCases = { + new Case(simpleNotif, "Type = 'mytype'", true), + new Case(simpleNotif, "Type = 'mytype'", + Notification.class, true), + new Case(simpleNotif, "Type = 'mytype'", + AttributeChangeNotification.class, false), + new Case(simpleNotif, "Type != 'mytype'", false), + new Case(simpleNotif, "Type = 'somethingelse'", false), + new Case(attrChangeNotif, "AttributeName = 'AttrName'", true), + new Case(attrChangeNotif, + "instanceof 'javax.management.AttributeChangeNotification'", + true), + new Case(attrChangeNotif, + "instanceof 'javax.management.Notification'", + true), + new Case(attrChangeNotif, + "instanceof 'javax.management.relation.MBeanServerNotification'", + false), + new Case(attrChangeNotif, + "class = 'javax.management.AttributeChangeNotification'", + true), + new Case(attrChangeNotif, + "javax.management.AttributeChangeNotification#AttributeName = 'AttrName'", + true), + new Case(sourcedNotif, + testObjectName, + true), + new Case(sourcedNotif, + makeObjectName("a*:b=*"), + true), + new Case(sourcedNotif, + makeObjectName("a*:c=*"), + false), + new Case(customNotif, "Name = 'claude'", true), + new Case(customNotif, "Name = 'tiddly'", false), + new Case(customNotif, "Interesting = true", true), + new Case(customNotif, "Interesting = false", false), + }; + + private static final ExoticCase[] exoticTestCases = { + new ExoticCase( + simpleNotif, new Notification("notmytype", "source", 0L), + new ExoticQuery("getAttributes") { + boolean apply(MBeanServer mbs, ObjectName name) + throws Exception { + List attrs = mbs.getAttributes( + name, new String[] {"Type", "Source"}).asList(); + return (attrs.get(0).equals(new Attribute("Type", "mytype")) && + attrs.get(1).equals(new Attribute("Source", "source"))); + } + }), + new ExoticCase( + new Notification("mytype", "source", 0L) {}, + simpleNotif, + new ExoticQuery("getClassLoaderFor") { + boolean apply(MBeanServer mbs, ObjectName name) + throws Exception { + return (mbs.getClassLoaderFor(name) == + this.getClass().getClassLoader()); + } + }), + new ExoticCase( + sourcedNotif, simpleNotif, + new ExoticQuery("getDomains") { + boolean apply(MBeanServer mbs, ObjectName name) + throws Exception { + return Arrays.equals(mbs.getDomains(), + new String[] {testObjectName.getDomain()}); + } + }), + new ExoticCase( + simpleNotif, attrChangeNotif, + new ExoticQuery("getMBeanInfo") { + boolean apply(MBeanServer mbs, ObjectName name) + throws Exception { + MBeanInfo mbi = mbs.getMBeanInfo(name); + // If we ever add a constructor to Notification then + // we will have to change the 4 below. + if (mbi.getOperations().length > 0 || + mbi.getConstructors().length != 4 || + mbi.getNotifications().length > 0) + return false; + Set expect = new HashSet( + Arrays.asList( + "Class", "Message", "SequenceNumber", "Source", + "TimeStamp", "Type", "UserData")); + Set actual = new HashSet(); + for (MBeanAttributeInfo mbai : mbi.getAttributes()) + actual.add(mbai.getName()); + return actual.equals(expect); + } + }), + new ExoticCase( + simpleNotif, attrChangeNotif, + new ExoticQuery("getObjectInstance") { + boolean apply(MBeanServer mbs, ObjectName name) + throws Exception { + ObjectInstance oi = mbs.getObjectInstance(name); + return oi.getClassName().equals(Notification.class.getName()); + } + }), + new ExoticCase( + sourcedNotif, simpleNotif, + new ExoticQuery("queryNames") { + boolean apply(MBeanServer mbs, ObjectName name) + throws Exception { + Set names = mbs.queryNames(null, + Query.eq(Query.attr("Type"), Query.value("mytype"))); + return names.equals(Collections.singleton(testObjectName)); + } + }), + new ExoticCase( + sourcedNotif, simpleNotif, + new ExoticQuery("queryMBeans") { + boolean apply(MBeanServer mbs, ObjectName name) + throws Exception { + Set insts = mbs.queryMBeans(null, + Query.eq(Query.attr("Type"), Query.value("mytype"))); + if (insts.size() != 1) + return false; + ObjectInstance inst = insts.iterator().next(); + return (inst.getObjectName().equals(testObjectName) && + inst.getClassName().equals(Notification.class.getName())); + } + }), + }; + + private static enum Test { + QUERY_EXP("query"), STRING("string"), STRING_PLUS_CLASS("string with class"); + private final String name; + Test(String name) { + this.name = name; + } + @Override + public String toString() { + return name; + } + } + + public static void main(String[] args) throws Exception { + boolean allok = true; + for (Case testCase : testCases) { + for (Test test : Test.values()) { + QueryNotificationFilter nf; + String queryString; + switch (test) { + case QUERY_EXP: { + QueryExp inst = Query.isInstanceOf( + Query.value(testCase.notifClass.getName())); + QueryExp and = Query.and(inst, testCase.query); + queryString = Query.toString(and); + nf = new QueryNotificationFilter(and); + break; + } + case STRING: { + String s = "instanceof '" + testCase.notifClass.getName() + "'"; + queryString = s + " and " + Query.toString(testCase.query); + nf = new QueryNotificationFilter(queryString); + break; + } + case STRING_PLUS_CLASS: + queryString = null; + nf = new QueryNotificationFilter( + testCase.notifClass, Query.toString(testCase.query)); + break; + default: + throw new AssertionError(); + } + boolean accept = nf.isNotificationEnabled(testCase.notif); + if (queryString != null) { + queryString = Query.toString(Query.fromString(queryString)); + if (!queryString.equals(Query.toString(nf.getQuery()))) { + System.out.println("FAIL: query string mismatch: expected " + + "\"" + queryString + "\", got \"" + + Query.toString(nf.getQuery())); + allok = false; + } + } + boolean ok = (accept == testCase.expect); + System.out.println((ok ? "pass" : "FAIL") + ": " + + testCase.query + " (" + test + ")"); + allok &= ok; + } + } + for (ExoticCase testCase : exoticTestCases) { + NotificationFilter nf = new QueryNotificationFilter(testCase.query); + for (boolean expect : new boolean[] {true, false}) { + Notification n = expect ? testCase.trueNotif : testCase.falseNotif; + boolean accept = nf.isNotificationEnabled(n); + boolean ok = (accept == expect); + System.out.println((ok ? "pass" : "FAIL") + ": " + + testCase.query + ": " + n); + allok &= ok; + } + } + if (!allok) + throw new Exception("TEST FAILED"); + } +} From 3d9e4854d0ac80e98234861d75c7350c101de15e Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 1 Apr 2008 15:14:53 -0700 Subject: [PATCH 244/274] 6482134: JDK 6 build error on Windows, Visual Studio .NET on Japanese locale Fix scanning of cl.exe version output, removed CC_TYPE. Reviewed-by: tbell --- jdk/make/common/shared/Compiler-gcc.gmk | 2 -- jdk/make/common/shared/Compiler-msvc.gmk | 8 +++----- jdk/make/common/shared/Sanity.gmk | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/jdk/make/common/shared/Compiler-gcc.gmk b/jdk/make/common/shared/Compiler-gcc.gmk index 74f9807e09d..d12adac959e 100644 --- a/jdk/make/common/shared/Compiler-gcc.gmk +++ b/jdk/make/common/shared/Compiler-gcc.gmk @@ -45,10 +45,8 @@ ifeq ($(PLATFORM), windows) NMAKE = MFLAGS= MAKEFLAGS= $(COMPILER_PATH)nmake -nologo ifeq ($(ARCH_DATA_MODEL), 32) CC_VER = UNKNOWN - CC_TYPE = UNKNOWN else CC_VER = UNKNOWN - CC_TYPE = UNKNOWN endif _LINK_VER :=$(shell $(LINK) 2>&1 | $(HEAD) -n 1) LINK_VER :=$(call GetVersion,"$(_LINK_VER)") diff --git a/jdk/make/common/shared/Compiler-msvc.gmk b/jdk/make/common/shared/Compiler-msvc.gmk index fbb8e8a5664..41509e51b09 100644 --- a/jdk/make/common/shared/Compiler-msvc.gmk +++ b/jdk/make/common/shared/Compiler-msvc.gmk @@ -47,13 +47,13 @@ ifeq ($(PLATFORM), windows) # unset any GNU Make settings of MFLAGS and MAKEFLAGS which may mess up nmake NMAKE = MFLAGS= MAKEFLAGS= $(COMPILER_PATH)nmake -nologo + # Compiler version and type (Always get word after "Version") + CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(SED) 's/.*\(Version.*\)/\1/' | $(NAWK) '{print $$2}') + # SDK-64 and MSVC6 put REBASE.EXE in a different places - go figure... ifeq ($(ARCH_DATA_MODEL), 32) - CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$8}') LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}') - CC_TYPE := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$5}') CC_MAJORVER :=$(call MajorVersion,$(CC_VER)) - REQUIRED_CCTYPE = Optimizing REQUIRED_CC_VER = 13.10.3077 REQUIRED_LINK_VER = 7.10.3077 ifeq ($(CC_MAJORVER), 12) @@ -85,9 +85,7 @@ ifeq ($(PLATFORM), windows) endif endif else - CC_VER := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$7}') LINK_VER := $(shell $(LINK) | $(HEAD) -n 1 | $(NAWK) '{print $$6}') - CC_TYPE := $(shell $(CC) 2>&1 | $(HEAD) -n 1 | $(NAWK) '{print $$4}') CC_MAJORVER :=$(call MajorVersion,$(CC_VER)) CC_MINORVER :=$(call MinorVersion,$(CC_VER)) CC_MICROVER :=$(call MicroVersion,$(CC_VER)) diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk index 98bd5b4346c..a6b19476c0b 100644 --- a/jdk/make/common/shared/Sanity.gmk +++ b/jdk/make/common/shared/Sanity.gmk @@ -1335,7 +1335,7 @@ sane-compiler: sane-link ifndef OPENJDK @if [ "$(CC_CHECK)" != "same" ]; then \ $(ECHO) "WARNING: The $(PLATFORM) compiler is not version $(COMPILER_VERSION) $(REQUIRED_CC_VER) \n" \ - " Specifically the $(COMPILER_NAME) $(CC_TYPE) compiler. \n " \ + " Specifically the $(COMPILER_NAME) compiler. \n " \ " $(YOU_ARE_USING) compiler version: $(CC_VER) \n" \ " The compiler was obtained from the following location: \n" \ " $(COMPILER_PATH) \n" \ From de514b4b6eb583ef275bb4bdff42908f96b4a864 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 1 Apr 2008 15:41:23 -0700 Subject: [PATCH 245/274] 6627823: Missed whitespace normalization files: jdk/test/java/rmi Just missed a few files being normalized in rev 0. Reviewed-by: xdono --- .../CreatePrivateActivatable.java | 204 ++++---- .../activateFails/ActivateFails.java | 205 ++++---- .../activateFails/ActivateFails_Stub.java | 126 ++--- .../activateFails/ActivateMe.java | 2 +- .../activateFails/ShutdownThread.java | 17 +- .../DownloadActivationGroup.java | 144 +++--- .../DownloadActivationGroup_Stub.java | 54 +- .../MyActivationGroupImpl.java | 10 +- .../CheckDefaultGroupName.java | 26 +- .../activeGroup/IdempotentActiveGroup.java | 134 ++--- .../modifyDescriptor/ActivateMe.java | 2 +- .../modifyDescriptor/ModifyDescriptor.java | 308 +++++------ .../ModifyDescriptor_Stub.java | 262 +++++----- .../stubClassesPermitted/CanCreateStubs.java | 3 +- .../StubClassesPermitted.java | 244 ++++----- .../StubClassesPermitted_Stub.java | 234 ++++----- .../unregisterGroup/ActivateMe.java | 2 +- .../unregisterGroup/CallbackInterface.java | 3 +- .../unregisterGroup/Callback_Stub.java | 138 ++--- .../unregisterGroup/UnregisterGroup.java | 262 +++++----- .../unregisterGroup/UnregisterGroup_Stub.java | 162 +++--- jdk/test/java/rmi/dgc/VMID/CheckVMID.java | 22 +- .../rmi/dgc/dgcAckFailure/DGCAckFailure.java | 194 +++---- .../dgc/dgcAckFailure/DGCAckFailure_Stub.java | 48 +- .../dgcImplInsulation/DGCImplInsulation.java | 86 ++-- .../DGCImplInsulation_Stub.java | 8 +- .../dgc/retryDirtyCalls/RetryDirtyCalls.java | 194 +++---- .../retryDirtyCalls/RetryDirtyCalls_Stub.java | 48 +- .../AltSecurityManager.java | 116 ++--- .../TestSecurityManager.java | 22 +- .../rmi/registry/checkusage/CheckUsage.java | 76 +-- .../classPathCodebase/ClassPathCodebase.java | 204 ++++---- .../rmi/registry/classPathCodebase/Dummy.java | 6 +- .../rmi/registry/emptyName/EmptyName.java | 16 +- .../registry/interfaceHash/InterfaceHash.java | 268 +++++----- .../interfaceHash/ReferenceRegistryStub.java | 260 +++++----- .../MultipleRegistries.java | 68 +-- .../java/rmi/registry/reexport/Reexport.java | 176 +++---- .../benchmark/bench/rmi/BenchServer.java | 23 +- .../benchmark/bench/rmi/BenchServerImpl.java | 51 +- .../bench/rmi/BooleanArrayCalls.java | 51 +- .../benchmark/bench/rmi/BooleanCalls.java | 47 +- .../benchmark/bench/rmi/ByteArrayCalls.java | 51 +- .../benchmark/bench/rmi/ByteCalls.java | 47 +- .../benchmark/bench/rmi/CharArrayCalls.java | 51 +- .../benchmark/bench/rmi/CharCalls.java | 47 +- .../benchmark/bench/rmi/ClassLoading.java | 23 +- .../benchmark/bench/rmi/DoubleArrayCalls.java | 51 +- .../benchmark/bench/rmi/DoubleCalls.java | 47 +- .../benchmark/bench/rmi/ExceptionCalls.java | 53 +- .../benchmark/bench/rmi/ExportObjs.java | 31 +- .../benchmark/bench/rmi/FloatArrayCalls.java | 51 +- .../benchmark/bench/rmi/FloatCalls.java | 47 +- .../benchmark/bench/rmi/IntArrayCalls.java | 51 +- .../benchmark/bench/rmi/IntCalls.java | 47 +- .../benchmark/bench/rmi/LongArrayCalls.java | 51 +- .../benchmark/bench/rmi/LongCalls.java | 47 +- .../reliability/benchmark/bench/rmi/Main.java | 477 +++++++++--------- .../benchmark/bench/rmi/NullCalls.java | 45 +- .../benchmark/bench/rmi/ObjArrayCalls.java | 71 ++- .../benchmark/bench/rmi/ObjTreeCalls.java | 67 ++- .../benchmark/bench/rmi/ProxyArrayCalls.java | 83 ++- .../bench/rmi/RemoteObjArrayCalls.java | 57 +-- .../benchmark/bench/rmi/ShortArrayCalls.java | 53 +- .../benchmark/bench/rmi/ShortCalls.java | 47 +- .../bench/rmi/SmallObjTreeCalls.java | 51 +- .../benchmark/bench/serial/BooleanArrays.java | 60 ++- .../benchmark/bench/serial/Booleans.java | 54 +- .../benchmark/bench/serial/ByteArrays.java | 60 ++- .../benchmark/bench/serial/Bytes.java | 53 +- .../benchmark/bench/serial/CharArrays.java | 60 ++- .../benchmark/bench/serial/Chars.java | 53 +- .../benchmark/bench/serial/ClassDesc.java | 47 +- .../benchmark/bench/serial/Cons.java | 35 +- .../bench/serial/CustomDefaultObjTrees.java | 97 ++-- .../bench/serial/CustomObjTrees.java | 141 +++--- .../benchmark/bench/serial/DoubleArrays.java | 60 ++- .../benchmark/bench/serial/Doubles.java | 53 +- .../bench/serial/ExternObjTrees.java | 157 +++--- .../benchmark/bench/serial/FloatArrays.java | 60 ++- .../benchmark/bench/serial/Floats.java | 53 +- .../bench/serial/GetPutFieldTrees.java | 109 ++-- .../benchmark/bench/serial/IntArrays.java | 60 ++- .../benchmark/bench/serial/Ints.java | 53 +- .../benchmark/bench/serial/LongArrays.java | 60 ++- .../benchmark/bench/serial/Longs.java | 53 +- .../benchmark/bench/serial/Main.java | 201 ++++---- .../benchmark/bench/serial/ObjArrays.java | 92 ++-- .../benchmark/bench/serial/ObjTrees.java | 89 ++-- .../benchmark/bench/serial/ProxyArrays.java | 98 ++-- .../bench/serial/ProxyClassDesc.java | 103 ++-- .../benchmark/bench/serial/RepeatObjs.java | 67 ++- .../benchmark/bench/serial/ReplaceTrees.java | 115 +++-- .../benchmark/bench/serial/ShortArrays.java | 60 ++- .../benchmark/bench/serial/Shorts.java | 53 +- .../benchmark/bench/serial/SmallObjTrees.java | 71 ++- .../benchmark/bench/serial/StreamBuffer.java | 165 +++--- .../benchmark/bench/serial/Strings.java | 75 ++- .../java/rmi/reliability/juicer/Apple.java | 4 +- .../rmi/reliability/juicer/AppleEvent.java | 36 +- .../rmi/reliability/juicer/AppleImpl.java | 44 +- .../rmi/reliability/juicer/AppleUser.java | 2 +- .../rmi/reliability/juicer/AppleUserImpl.java | 422 ++++++++-------- .../reliability/juicer/ApplicationServer.java | 158 +++--- .../java/rmi/reliability/juicer/Orange.java | 8 +- .../rmi/reliability/juicer/OrangeEcho.java | 6 +- .../reliability/juicer/OrangeEchoImpl.java | 30 +- .../rmi/reliability/juicer/OrangeImpl.java | 42 +- .../activatable/CompressConstants.java | 10 +- .../activatable/CompressInputStream.java | 112 ++-- .../activatable/CompressOutputStream.java | 60 +-- .../useSocketFactory/activatable/Echo.java | 2 +- .../activatable/EchoImpl.java | 120 ++--- .../activatable/EchoImpl_Stub.java | 56 +- .../activatable/MultiSocketFactory.java | 301 ++++++----- .../activatable/UseCustomSocketFactory.java | 202 ++++---- .../useSocketFactory/registry/Compress.java | 370 +++++++------- .../useSocketFactory/registry/Hello.java | 2 +- .../useSocketFactory/registry/HelloImpl.java | 72 +-- .../registry/HelloImpl_Stub.java | 104 ++-- .../registry/UseCustomSocketFactory.java | 136 ++--- .../unicast/CompressConstants.java | 10 +- .../unicast/CompressInputStream.java | 112 ++-- .../unicast/CompressOutputStream.java | 60 +-- .../useSocketFactory/unicast/Echo.java | 2 +- .../useSocketFactory/unicast/EchoImpl.java | 68 +-- .../unicast/EchoImpl_Stub.java | 48 +- .../unicast/MultiSocketFactory.java | 301 ++++++----- .../unicast/UseCustomSocketFactory.java | 132 ++--- .../setLogPermission/SetLogPermission.java | 74 +-- .../changeHostName/ChangeHostName.java | 54 +- .../changeHostName/ChangeHostName_Stub.java | 46 +- .../KeepAliveDuringCall.java | 124 ++--- .../KeepAliveDuringCall_Stub.java | 70 +-- .../keepAliveDuringCall/Shutdown.java | 2 +- .../keepAliveDuringCall/ShutdownImpl.java | 76 +-- .../ShutdownImpl_Stub.java | 46 +- .../keepAliveDuringCall/ShutdownMonitor.java | 2 +- .../MarshalAfterUnexport.java | 48 +- .../MarshalAfterUnexport2.java | 60 +-- .../MarshalAfterUnexport2_Stub.java | 46 +- .../MarshalAfterUnexport_Stub.java | 46 +- .../unexportObject/Ping.java | 3 +- .../unexportObject/UnexportLeak.java | 70 ++- .../unexportObject/UnexportLeak_Stub.java | 46 +- .../useDynamicProxies/UseDynamicProxies.java | 110 ++-- .../UseDynamicProxies_Stub.java | 100 ++-- .../CheckUnmarshalOnStopThread.java | 150 +++--- .../CheckUnmarshalOnStopThread_Stub.java | 216 ++++---- .../CheckUnmarshall.java | 5 +- .../PoisonPill.java | 4 +- .../RuntimeExceptionParameter.java | 5 +- .../finiteGCLatency/FiniteGCLatency.java | 106 ++-- .../finiteGCLatency/FiniteGCLatency_Stub.java | 8 +- .../LeaseCheckInterval.java | 108 ++-- .../LeaseCheckInterval_Stub.java | 8 +- .../leaseCheckInterval/SelfTerminator.java | 18 +- .../MarshalledObjectGet.java | 110 ++-- .../MarshalledObjectGet_Stub.java | 8 +- .../UnreferencedContext.java | 210 ++++---- .../UnreferencedContext_Stub.java | 8 +- .../CloseServerSocketOnTermination.java | 122 ++--- .../rmi/transport/checkFQDN/CheckFQDN.java | 180 +++---- .../transport/checkFQDN/CheckFQDNClient.java | 106 ++-- .../transport/checkFQDN/CheckFQDN_Stub.java | 92 ++-- .../transport/checkFQDN/TellServerName.java | 5 +- .../checkLeaseInfoLeak/CheckLeaseLeak.java | 248 ++++----- .../CheckLeaseLeak_Stub.java | 80 +-- .../checkLeaseInfoLeak/LeaseLeak.java | 2 +- .../checkLeaseInfoLeak/LeaseLeakClient.java | 38 +- .../closeServerSocket/CloseServerSocket.java | 120 ++--- .../transport/dgcDeadLock/DGCDeadLock.java | 144 +++--- .../java/rmi/transport/dgcDeadLock/Test.java | 2 +- .../rmi/transport/dgcDeadLock/TestImpl.java | 312 ++++++------ .../transport/dgcDeadLock/TestImpl_Stub.java | 116 ++--- .../handshakeFailure/HandshakeFailure.java | 138 ++--- .../handshakeTimeout/HandshakeTimeout.java | 130 ++--- .../transport/httpSocket/HttpSocketTest.java | 55 +- .../httpSocket/HttpSocketTest_Stub.java | 154 +++--- .../PinClientSocketFactory.java | 160 +++--- .../pinLastArguments/PinLastArguments.java | 62 +-- .../RapidExportUnexport.java | 34 +- .../readTimeout/ReadTimeoutTest.java | 210 ++++---- .../rmi/transport/readTimeout/TestIface.java | 4 +- .../rmi/transport/readTimeout/TestImpl.java | 13 +- .../transport/readTimeout/TestImpl_Stub.java | 48 +- .../reuseDefaultPort/ReuseDefaultPort.java | 50 +- .../RuntimeThreadInheritanceLeak.java | 156 +++--- .../RuntimeThreadInheritanceLeak_Stub.java | 8 +- 189 files changed, 8229 insertions(+), 8318 deletions(-) diff --git a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java index 32d5747cd5e..f91916430fb 100644 --- a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java +++ b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -49,116 +49,116 @@ import java.util.Properties; public class CreatePrivateActivatable { private static class PrivateActivatable extends Activatable - implements ActivateMe, Runnable + implements ActivateMe, Runnable { - private PrivateActivatable(ActivationID id, MarshalledObject obj) - throws ActivationException, RemoteException - { - super(id, 0); - } + private PrivateActivatable(ActivationID id, MarshalledObject obj) + throws ActivationException, RemoteException + { + super(id, 0); + } - public void ping() - {} + public void ping() + {} - /** - * Spawns a thread to deactivate the object. - */ - public void shutdown() throws Exception - { - (new Thread(this, "CreatePrivateActivatable$PrivateActivatable")).start(); - } + /** + * Spawns a thread to deactivate the object. + */ + public void shutdown() throws Exception + { + (new Thread(this, "CreatePrivateActivatable$PrivateActivatable")).start(); + } - /** - * Thread to deactivate object. First attempts to make object - * inactive (via the inactive method). If that fails (the - * object may still have pending/executing calls), then - * unexport the object forcibly. - */ - public void run() { - ActivationLibrary.deactivate(this, getID()); - } + /** + * Thread to deactivate object. First attempts to make object + * inactive (via the inactive method). If that fails (the + * object may still have pending/executing calls), then + * unexport the object forcibly. + */ + public void run() { + ActivationLibrary.deactivate(this, getID()); + } } - + public static void main(String[] args) { - /* - * The following line is required with the JDK 1.2 VM so that the - * VM can exit gracefully when this test completes. Otherwise, the - * conservative garbage collector will find a handle to the server - * object on the native stack and not clear the weak reference to - * it in the RMI runtime's object table. - */ - Object dummy = new Object(); - RMID rmid = null; - ActivateMe obj; + /* + * The following line is required with the JDK 1.2 VM so that the + * VM can exit gracefully when this test completes. Otherwise, the + * conservative garbage collector will find a handle to the server + * object on the native stack and not clear the weak reference to + * it in the RMI runtime's object table. + */ + Object dummy = new Object(); + RMID rmid = null; + ActivateMe obj; - System.err.println("\nRegression test for bug 4164971\n"); - System.err.println("java.security.policy = " + - System.getProperty("java.security.policy", "no policy")); + System.err.println("\nRegression test for bug 4164971\n"); + System.err.println("java.security.policy = " + + System.getProperty("java.security.policy", "no policy")); - CreatePrivateActivatable server; - try { - TestLibrary.suggestSecurityManager(TestParams.defaultSecurityManager); + CreatePrivateActivatable server; + try { + TestLibrary.suggestSecurityManager(TestParams.defaultSecurityManager); - // start an rmid. - RMID.removeLog(); - rmid = RMID.createRMID(); - rmid.start(); - - /* Cause activation groups to have a security policy that will - * allow security managers to be downloaded and installed - */ - Properties p = new Properties(); - // this test must always set policies/managers in its - // activation groups - p.put("java.security.policy", - TestParams.defaultGroupPolicy); - p.put("java.security.manager", - TestParams.defaultSecurityManager); - - /* - * Activate an object by registering its object - * descriptor and invoking a method on the - * stub returned from the register call. - */ - ActivationGroupDesc groupDesc = - new ActivationGroupDesc(p, null); - ActivationSystem system = ActivationGroup.getSystem(); - ActivationGroupID groupID = system.registerGroup(groupDesc); + // start an rmid. + RMID.removeLog(); + rmid = RMID.createRMID(); + rmid.start(); - System.err.println("Creating descriptor"); - ActivationDesc desc = - new ActivationDesc(groupID, - "CreatePrivateActivatable$PrivateActivatable", - null, null); - - System.err.println("Registering descriptor"); - obj = (ActivateMe) Activatable.register(desc); - - /* - * Loop a bunch of times to force activator to - * spawn VMs (groups) - */ - System.err.println("Activate object via method call"); - obj.ping(); - - /* - * Clean up object too. - */ - System.err.println("Deactivate object via method call"); - obj.shutdown(); - - System.err.println("\nsuccess: CreatePrivateActivatable test passed "); - - } catch (Exception e) { - if (e instanceof java.security.PrivilegedActionException) { - e = ((java.security.PrivilegedActionException)e).getException(); - } - TestLibrary.bomb("\nfailure: unexpected exception " + - e.getClass().getName(), e); - - } finally { - ActivationLibrary.rmidCleanup(rmid); - obj = null; - } + /* Cause activation groups to have a security policy that will + * allow security managers to be downloaded and installed + */ + Properties p = new Properties(); + // this test must always set policies/managers in its + // activation groups + p.put("java.security.policy", + TestParams.defaultGroupPolicy); + p.put("java.security.manager", + TestParams.defaultSecurityManager); + + /* + * Activate an object by registering its object + * descriptor and invoking a method on the + * stub returned from the register call. + */ + ActivationGroupDesc groupDesc = + new ActivationGroupDesc(p, null); + ActivationSystem system = ActivationGroup.getSystem(); + ActivationGroupID groupID = system.registerGroup(groupDesc); + + System.err.println("Creating descriptor"); + ActivationDesc desc = + new ActivationDesc(groupID, + "CreatePrivateActivatable$PrivateActivatable", + null, null); + + System.err.println("Registering descriptor"); + obj = (ActivateMe) Activatable.register(desc); + + /* + * Loop a bunch of times to force activator to + * spawn VMs (groups) + */ + System.err.println("Activate object via method call"); + obj.ping(); + + /* + * Clean up object too. + */ + System.err.println("Deactivate object via method call"); + obj.shutdown(); + + System.err.println("\nsuccess: CreatePrivateActivatable test passed "); + + } catch (Exception e) { + if (e instanceof java.security.PrivilegedActionException) { + e = ((java.security.PrivilegedActionException)e).getException(); + } + TestLibrary.bomb("\nfailure: unexpected exception " + + e.getClass().getName(), e); + + } finally { + ActivationLibrary.rmidCleanup(rmid); + obj = null; + } } } diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java index 49c7fbb3c47..b5aa5360317 100644 --- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java +++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,10 +24,10 @@ /* @test * @bug 4097135 * @summary Need a specific subtype of RemoteException for activation failure. - * If activation fails to happen during a call to a remote object, - * then the call should end in an ActivateFailedException. In this - * test, the actual "activatable" remote object fails to activate - * since its * "activation" constructor throws an exception. + * If activation fails to happen during a call to a remote object, + * then the call should end in an ActivateFailedException. In this + * test, the actual "activatable" remote object fails to activate + * since its * "activation" constructor throws an exception. * @author Ann Wollrath * * @library ../../../testlibrary @@ -46,128 +46,127 @@ import java.io.*; import java.util.Properties; public class ActivateFails - extends Activatable - implements ActivateMe + extends Activatable + implements ActivateMe { public ActivateFails(ActivationID id, MarshalledObject obj) - throws ActivationException, RemoteException + throws ActivationException, RemoteException { - super(id, 0); + super(id, 0); - boolean refuseToActivate = false; - try { - refuseToActivate = ((Boolean)obj.get()).booleanValue(); - } catch (Exception impossible) { - } - - if (refuseToActivate) - throw new RemoteException("object refuses to activate"); + boolean refuseToActivate = false; + try { + refuseToActivate = ((Boolean)obj.get()).booleanValue(); + } catch (Exception impossible) { + } + + if (refuseToActivate) + throw new RemoteException("object refuses to activate"); } public void ping() {} - + /** * Spawns a thread to deactivate the object. */ public ShutdownThread shutdown() throws Exception { - ShutdownThread shutdownThread = new ShutdownThread(this, getID()); - shutdownThread.start(); - return(shutdownThread); + ShutdownThread shutdownThread = new ShutdownThread(this, getID()); + shutdownThread.start(); + return(shutdownThread); } - - public static void main(String[] args) + + public static void main(String[] args) { - RMID rmid = null; - ActivateMe obj1, obj2; - ShutdownThread shutdownThread; - - System.err.println("\nRegression test for bug 4097135\n"); - try { - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + RMID rmid = null; + ActivateMe obj1, obj2; + ShutdownThread shutdownThread; - /* - * First run "rmid" and wait for it to start up. - */ - RMID.removeLog(); - rmid = RMID.createRMID(); - rmid.start(); + System.err.println("\nRegression test for bug 4097135\n"); + try { + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - /* Cause activation groups to have a security policy that will - * allow security managers to be downloaded and installed - */ - Properties p = new Properties(); - // this test must always set policies/managers in its - // activation groups - p.put("java.security.policy", - TestParams.defaultGroupPolicy); - p.put("java.security.manager", - TestParams.defaultSecurityManager); + /* + * First run "rmid" and wait for it to start up. + */ + RMID.removeLog(); + rmid = RMID.createRMID(); + rmid.start(); - /* - * Create activation descriptor... - */ - System.err.println("creating activation descriptor..."); - ActivationGroupDesc groupDesc = - new ActivationGroupDesc(p, null); - ActivationGroupID groupID = - ActivationGroup.getSystem().registerGroup(groupDesc); - - ActivationDesc desc1 = - new ActivationDesc(groupID, "ActivateFails", - null, - new MarshalledObject(new Boolean(true))); - - ActivationDesc desc2 = - new ActivationDesc(groupID, "ActivateFails", - null, - new MarshalledObject(new Boolean(false))); - /* - * Register activation descriptor and make a call on - * the stub. Activation should fail with an - * ActivateFailedException. If not, report an - * error as a RuntimeException - */ + /* Cause activation groups to have a security policy that will + * allow security managers to be downloaded and installed + */ + Properties p = new Properties(); + // this test must always set policies/managers in its + // activation groups + p.put("java.security.policy", + TestParams.defaultGroupPolicy); + p.put("java.security.manager", + TestParams.defaultSecurityManager); - System.err.println("registering activation descriptor..."); - obj1 = (ActivateMe)Activatable.register(desc1); - obj2 = (ActivateMe)Activatable.register(desc2); + /* + * Create activation descriptor... + */ + System.err.println("creating activation descriptor..."); + ActivationGroupDesc groupDesc = + new ActivationGroupDesc(p, null); + ActivationGroupID groupID = + ActivationGroup.getSystem().registerGroup(groupDesc); - System.err.println("invoking method on activatable object..."); - try { - obj1.ping(); - - } catch (ActivateFailedException e) { + ActivationDesc desc1 = + new ActivationDesc(groupID, "ActivateFails", + null, + new MarshalledObject(new Boolean(true))); - /* - * This is what is expected so exit with status 0 - */ - System.err.println("\nsuccess: ActivateFailedException " + - "generated"); - e.getMessage(); - } + ActivationDesc desc2 = + new ActivationDesc(groupID, "ActivateFails", + null, + new MarshalledObject(new Boolean(false))); + /* + * Register activation descriptor and make a call on + * the stub. Activation should fail with an + * ActivateFailedException. If not, report an + * error as a RuntimeException + */ - obj2.ping(); - shutdownThread = obj2.shutdown(); + System.err.println("registering activation descriptor..."); + obj1 = (ActivateMe)Activatable.register(desc1); + obj2 = (ActivateMe)Activatable.register(desc2); - // wait for shutdown to work - Thread.sleep(2000); + System.err.println("invoking method on activatable object..."); + try { + obj1.ping(); - shutdownThread = null; - - } catch (Exception e) { - /* - * Test failed; unexpected exception generated. - */ - TestLibrary.bomb("\nfailure: unexpected exception " + - e.getClass().getName() + ": " + e.getMessage(), e); - - } finally { - obj1 = obj2 = null; - ActivationLibrary.rmidCleanup(rmid); - } + } catch (ActivateFailedException e) { + + /* + * This is what is expected so exit with status 0 + */ + System.err.println("\nsuccess: ActivateFailedException " + + "generated"); + e.getMessage(); + } + + obj2.ping(); + shutdownThread = obj2.shutdown(); + + // wait for shutdown to work + Thread.sleep(2000); + + shutdownThread = null; + + } catch (Exception e) { + /* + * Test failed; unexpected exception generated. + */ + TestLibrary.bomb("\nfailure: unexpected exception " + + e.getClass().getName() + ": " + e.getMessage(), e); + + } finally { + obj1 = obj2 = null; + ActivationLibrary.rmidCleanup(rmid); + } } } - diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails_Stub.java b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails_Stub.java index 08bded1f71b..5c1047f7860 100644 --- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails_Stub.java +++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,88 +29,88 @@ public final class ActivateFails_Stub implements ActivateMe, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("void ping()"), - new java.rmi.server.Operation("ShutdownThread shutdown()") + new java.rmi.server.Operation("void ping()"), + new java.rmi.server.Operation("ShutdownThread shutdown()") }; - + private static final long interfaceHash = -6632667923281093978L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_ping_0; private static java.lang.reflect.Method $method_shutdown_1; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_ping_0 = ActivateMe.class.getMethod("ping", new java.lang.Class[] {}); - $method_shutdown_1 = ActivateMe.class.getMethod("shutdown", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_ping_0 = ActivateMe.class.getMethod("ping", new java.lang.Class[] {}); + $method_shutdown_1 = ActivateMe.class.getMethod("shutdown", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public ActivateFails_Stub() { - super(); + super(); } public ActivateFails_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of ping() public void ping() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_ping_0, null, 5866401369815527589L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_ping_0, null, 5866401369815527589L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of shutdown() public ShutdownThread shutdown() - throws java.lang.Exception + throws java.lang.Exception { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_shutdown_1, null, -3616843253114182719L); - return ((ShutdownThread) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - ref.invoke(call); - ShutdownThread $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (ShutdownThread) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_shutdown_1, null, -3616843253114182719L); + return ((ShutdownThread) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + ref.invoke(call); + ShutdownThread $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (ShutdownThread) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } } } diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateMe.java b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateMe.java index fb29e0925b7..92d7df3faf6 100644 --- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateMe.java +++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateMe.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ShutdownThread.java b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ShutdownThread.java index 3636c2877bc..a902289234b 100644 --- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ShutdownThread.java +++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ShutdownThread.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,21 +31,20 @@ public class ShutdownThread extends Thread implements Serializable { ActivationID activationID = null; public ShutdownThread(Remote remoteObject, ActivationID activationID) { - remoteObject = remoteObject; - activationID = activationID; + remoteObject = remoteObject; + activationID = activationID; } public void run() { - try { + try { - Activatable.unexportObject(remoteObject, true); - Activatable.inactive(activationID); + Activatable.unexportObject(remoteObject, true); + Activatable.inactive(activationID); - } catch (Exception e) { - } + } catch (Exception e) { + } } } - diff --git a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java index df4121f819f..a60a6b2f99e 100644 --- a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java +++ b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,7 +23,7 @@ /* * @test - * @bug 4510355 + * @bug 4510355 * @summary ActivationGroup implementations cannot be downloaded by default; * Creates a custom activation group without setting a security manager * in activation group's descriptor. The custom activation group @@ -49,28 +49,28 @@ import java.util.Vector; import java.util.Properties; public class DownloadActivationGroup - implements Ping, Runnable + implements Ping, Runnable { private ActivationID id; public DownloadActivationGroup(ActivationID id, MarshalledObject mobj) - throws ActivationException, RemoteException + throws ActivationException, RemoteException { - this.id = id; - Activatable.exportObject(this, id, 0); - System.err.println("object activated in group"); + this.id = id; + Activatable.exportObject(this, id, 0); + System.err.println("object activated in group"); } public DownloadActivationGroup() throws RemoteException { - UnicastRemoteObject.exportObject(this, 0); + UnicastRemoteObject.exportObject(this, 0); } /** * Used to activate object. */ public void ping() { - System.err.println("received ping"); + System.err.println("received ping"); } /** @@ -79,87 +79,87 @@ public class DownloadActivationGroup */ public void shutdown() throws Exception { - (new Thread(this,"DownloadActivationGroup")).start(); + (new Thread(this,"DownloadActivationGroup")).start(); } /** * Thread to deactivate object. */ public void run() { - ActivationLibrary.deactivate(this, getID()); + ActivationLibrary.deactivate(this, getID()); } - + public ActivationID getID() { - return id; + return id; } public static void main(String[] args) { - RMID rmid = null; - - System.out.println("\nRegression test for bug 4510355\n"); - - try { - TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); + RMID rmid = null; - /* - * Install group class file in codebase. - */ - System.err.println("install class file in codebase"); - URL groupURL = TestLibrary.installClassInCodebase( - "MyActivationGroupImpl", "group"); - System.err.println("class file installed"); + System.out.println("\nRegression test for bug 4510355\n"); - /* - * Start rmid. - */ - RMID.removeLog(); - rmid = RMID.createRMID(); - String execPolicyOption = "-Dsun.rmi.activation.execPolicy=none"; - rmid.addOptions(new String[] { execPolicyOption }); - rmid.start(); + try { + TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); - /* - * Create and register descriptors for custom group and an - * activatable object in that group. - */ - System.err.println("register group"); - - Properties p = new Properties(); - p.put("java.security.policy", TestParams.defaultGroupPolicy); - - ActivationGroupDesc groupDesc = - new ActivationGroupDesc("MyActivationGroupImpl", - groupURL.toExternalForm(), - null, p, null); - ActivationGroupID groupID = - ActivationGroup.getSystem().registerGroup(groupDesc); - - - System.err.println("register activatable object"); - ActivationDesc desc = - new ActivationDesc(groupID, "DownloadActivationGroup", - null, null); - Ping obj = (Ping) Activatable.register(desc); + /* + * Install group class file in codebase. + */ + System.err.println("install class file in codebase"); + URL groupURL = TestLibrary.installClassInCodebase( + "MyActivationGroupImpl", "group"); + System.err.println("class file installed"); - /* - * Start group (by calling ping). - */ - System.err.println( - "ping object (forces download of group's class)"); - obj.ping(); - System.err.println( - "TEST PASSED: group's class downloaded successfully"); - System.err.println("shutdown object"); - obj.shutdown(); - System.err.println("TEST PASSED"); + /* + * Start rmid. + */ + RMID.removeLog(); + rmid = RMID.createRMID(); + String execPolicyOption = "-Dsun.rmi.activation.execPolicy=none"; + rmid.addOptions(new String[] { execPolicyOption }); + rmid.start(); - } catch (Exception e) { - TestLibrary.bomb(e); - } finally { - ActivationLibrary.rmidCleanup(rmid); - } + /* + * Create and register descriptors for custom group and an + * activatable object in that group. + */ + System.err.println("register group"); + + Properties p = new Properties(); + p.put("java.security.policy", TestParams.defaultGroupPolicy); + + ActivationGroupDesc groupDesc = + new ActivationGroupDesc("MyActivationGroupImpl", + groupURL.toExternalForm(), + null, p, null); + ActivationGroupID groupID = + ActivationGroup.getSystem().registerGroup(groupDesc); + + + System.err.println("register activatable object"); + ActivationDesc desc = + new ActivationDesc(groupID, "DownloadActivationGroup", + null, null); + Ping obj = (Ping) Activatable.register(desc); + + /* + * Start group (by calling ping). + */ + System.err.println( + "ping object (forces download of group's class)"); + obj.ping(); + System.err.println( + "TEST PASSED: group's class downloaded successfully"); + System.err.println("shutdown object"); + obj.shutdown(); + System.err.println("TEST PASSED"); + + } catch (Exception e) { + TestLibrary.bomb(e); + } finally { + ActivationLibrary.rmidCleanup(rmid); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup_Stub.java b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup_Stub.java index 0d366dee98a..0ce899c6f08 100644 --- a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup_Stub.java +++ b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,46 +29,46 @@ public final class DownloadActivationGroup_Stub implements Ping { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_ping_0; private static java.lang.reflect.Method $method_shutdown_1; - + static { - try { - $method_ping_0 = Ping.class.getMethod("ping", new java.lang.Class[] {}); - $method_shutdown_1 = Ping.class.getMethod("shutdown", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_ping_0 = Ping.class.getMethod("ping", new java.lang.Class[] {}); + $method_shutdown_1 = Ping.class.getMethod("shutdown", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public DownloadActivationGroup_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of ping() public void ping() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_ping_0, null, 5866401369815527589L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_ping_0, null, 5866401369815527589L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of shutdown() public void shutdown() - throws java.lang.Exception + throws java.lang.Exception { - ref.invoke(this, $method_shutdown_1, null, -7207851917985848402L); + ref.invoke(this, $method_shutdown_1, null, -7207851917985848402L); } } diff --git a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/MyActivationGroupImpl.java b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/MyActivationGroupImpl.java index cc43f4f2ee1..f4392af2fcf 100644 --- a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/MyActivationGroupImpl.java +++ b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/MyActivationGroupImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,11 +27,11 @@ import java.rmi.activation.*; public class MyActivationGroupImpl extends ActivationGroupImpl { - + public MyActivationGroupImpl(ActivationGroupID id, MarshalledObject mobj) - throws RemoteException, ActivationException + throws RemoteException, ActivationException { - super(id, mobj); - System.err.println("custom group implementation created"); + super(id, mobj); + System.err.println("custom group implementation created"); } } diff --git a/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java b/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java index 040253d1383..eed889c0e38 100644 --- a/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java +++ b/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -42,19 +42,19 @@ import java.rmi.activation.*; */ public class CheckDefaultGroupName { public static void main(String[] args) { - System.out.println("\n\nRegression test for, 4252236\n\n"); + System.out.println("\n\nRegression test for, 4252236\n\n"); - ActivationGroupDesc groupDesc = - new ActivationGroupDesc(null, null); + ActivationGroupDesc groupDesc = + new ActivationGroupDesc(null, null); - String className = groupDesc.getClassName(); - if (className != null) { - TestLibrary.bomb("ActivationGroupDesc had incorrect default" + - " group implementation class name: " + className); - } else { - System.err.println("test passed, had correct default group" + - " implementation class name: " + className + - "\n\n"); - } + String className = groupDesc.getClassName(); + if (className != null) { + TestLibrary.bomb("ActivationGroupDesc had incorrect default" + + " group implementation class name: " + className); + } else { + System.err.println("test passed, had correct default group" + + " implementation class name: " + className + + "\n\n"); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java b/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java index c9e901b8779..589b93bb6c0 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -49,81 +49,81 @@ import java.rmi.activation.ActivationSystem; import java.rmi.server.UnicastRemoteObject; public class IdempotentActiveGroup { - + public static void main(String[] args) { - System.err.println("\nRegression test for bug 4720528\n"); - - TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); - RMID rmid = null; - ActivationInstantiator inst1 = null; - ActivationInstantiator inst2 = null; - - try { - RMID.removeLog(); - rmid = RMID.createRMID(); - rmid.start(); + System.err.println("\nRegression test for bug 4720528\n"); - System.err.println("Create group descriptor"); - ActivationGroupDesc groupDesc = - new ActivationGroupDesc(null, null); - ActivationSystem system = ActivationGroup.getSystem(); - System.err.println("Register group descriptor"); - ActivationGroupID groupID = system.registerGroup(groupDesc); - inst1 = new FakeInstantiator(); - inst2 = new FakeInstantiator(); - - System.err.println("Invoke activeGroup with inst1"); - system.activeGroup(groupID, inst1, 0); + TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); + RMID rmid = null; + ActivationInstantiator inst1 = null; + ActivationInstantiator inst2 = null; - try { - System.err.println("Invoke activeGroup with inst2"); - system.activeGroup(groupID, inst2, 0); - throw new RuntimeException( - "TEST FAILED: activeGroup with unequal groups succeeded!"); - } catch (ActivationException expected) { - System.err.println("Caught expected ActivationException"); - System.err.println("Test 1 (of 2) passed"); - } + try { + RMID.removeLog(); + rmid = RMID.createRMID(); + rmid.start(); - try { - System.err.println("Invoke activeGroup with inst1"); - system.activeGroup(groupID, inst1, 0); - System.err.println("activeGroup call succeeded"); - System.err.println("Test 2 (of 2) passed"); - } catch (ActivationException unexpected) { - throw new RuntimeException( - "TEST FAILED: activeGroup with equal groups failed!", - unexpected); - } - - } catch (Exception e) { - TestLibrary.bomb("test failed", e); - } finally { - try { - if (inst1 != null) { - UnicastRemoteObject.unexportObject(inst1, true); - } - if (inst2 != null) { - UnicastRemoteObject.unexportObject(inst2, true); - } - } catch (NoSuchObjectException unexpected) { - throw new AssertionError(unexpected); - } - ActivationLibrary.rmidCleanup(rmid); - } + System.err.println("Create group descriptor"); + ActivationGroupDesc groupDesc = + new ActivationGroupDesc(null, null); + ActivationSystem system = ActivationGroup.getSystem(); + System.err.println("Register group descriptor"); + ActivationGroupID groupID = system.registerGroup(groupDesc); + inst1 = new FakeInstantiator(); + inst2 = new FakeInstantiator(); + + System.err.println("Invoke activeGroup with inst1"); + system.activeGroup(groupID, inst1, 0); + + try { + System.err.println("Invoke activeGroup with inst2"); + system.activeGroup(groupID, inst2, 0); + throw new RuntimeException( + "TEST FAILED: activeGroup with unequal groups succeeded!"); + } catch (ActivationException expected) { + System.err.println("Caught expected ActivationException"); + System.err.println("Test 1 (of 2) passed"); + } + + try { + System.err.println("Invoke activeGroup with inst1"); + system.activeGroup(groupID, inst1, 0); + System.err.println("activeGroup call succeeded"); + System.err.println("Test 2 (of 2) passed"); + } catch (ActivationException unexpected) { + throw new RuntimeException( + "TEST FAILED: activeGroup with equal groups failed!", + unexpected); + } + + } catch (Exception e) { + TestLibrary.bomb("test failed", e); + } finally { + try { + if (inst1 != null) { + UnicastRemoteObject.unexportObject(inst1, true); + } + if (inst2 != null) { + UnicastRemoteObject.unexportObject(inst2, true); + } + } catch (NoSuchObjectException unexpected) { + throw new AssertionError(unexpected); + } + ActivationLibrary.rmidCleanup(rmid); + } } private static class FakeInstantiator - extends UnicastRemoteObject - implements ActivationInstantiator + extends UnicastRemoteObject + implements ActivationInstantiator { - FakeInstantiator() throws RemoteException {} + FakeInstantiator() throws RemoteException {} - public MarshalledObject newInstance(ActivationID id, - ActivationDesc desc) - { - throw new AssertionError(); - } + public MarshalledObject newInstance(ActivationID id, + ActivationDesc desc) + { + throw new AssertionError(); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ActivateMe.java b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ActivateMe.java index c59f34a8451..c6a55411edd 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ActivateMe.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ActivateMe.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java index b166890cbc2..3f9ef2b2fe6 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,7 @@ * @bug 4127754 * * @summary synopsis: need to modify registered ActivationDesc and - * ActivationGroupDesc + * ActivationGroupDesc * @author Ann Wollrath * * @library ../../../testlibrary @@ -43,7 +43,7 @@ import java.rmi.registry.*; import java.util.*; public class ModifyDescriptor - implements ActivateMe, Runnable + implements ActivateMe, Runnable { private ActivationID id; @@ -54,28 +54,28 @@ public class ModifyDescriptor public ModifyDescriptor(ActivationID id, MarshalledObject mobj) - throws ActivationException, RemoteException + throws ActivationException, RemoteException { - this.id = id; - Activatable.exportObject(this, id, 0); - - try { - message = (String) mobj.get(); - } catch (Exception e) { - System.err.println("unable to get message from marshalled object"); - } + this.id = id; + Activatable.exportObject(this, id, 0); + + try { + message = (String) mobj.get(); + } catch (Exception e) { + System.err.println("unable to get message from marshalled object"); + } } public String getMessage() { - return message; + return message; } public String getProperty(String name) { - return TestLibrary.getProperty(name, null); + return TestLibrary.getProperty(name, null); } public ActivationID getID() { - return id; + return id; } /** @@ -83,7 +83,7 @@ public class ModifyDescriptor */ public void shutdown() throws Exception { - (new Thread(this,"ModifyDescriptor")).start(); + (new Thread(this,"ModifyDescriptor")).start(); } /** @@ -93,165 +93,165 @@ public class ModifyDescriptor * unexport the object forcibly. */ public void run() { - ActivationLibrary.deactivate(this, getID()); + ActivationLibrary.deactivate(this, getID()); } - + public static void main(String[] args) { - System.out.println("\nRegression test for bug 4127754\n"); - - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + System.out.println("\nRegression test for bug 4127754\n"); - RMID rmid = null; - - try { - RMID.removeLog(); - rmid = RMID.createRMID(); - rmid.start(); + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - /* - * Create and register a group and activatable object - */ + RMID rmid = null; - System.err.println("Creating group descriptor"); - Properties props = new Properties(); - props.put("java.security.policy", - TestParams.defaultGroupPolicy); - props.put("java.security.manager", - TestParams.defaultSecurityManager); - props.put("test.message", MESSAGE1); - ActivationGroupDesc initialGroupDesc = - new ActivationGroupDesc(props, null); - System.err.println("Registering group"); - ActivationSystem system = ActivationGroup.getSystem(); - ActivationGroupID groupID = system.registerGroup(initialGroupDesc); - - System.err.println("Creating descriptor"); - ActivationDesc initialDesc = - new ActivationDesc(groupID, "ModifyDescriptor", null, - new MarshalledObject(MESSAGE1), false); - - System.err.println("Registering descriptor"); - ActivateMe obj = (ActivateMe) Activatable.register(initialDesc); + try { + RMID.removeLog(); + rmid = RMID.createRMID(); + rmid.start(); - /* - * Ping object and verify that MarshalledObject is okay. - */ - System.err.println("Ping object"); - String message1 = obj.getMessage(); - System.err.println("message = " + message1); + /* + * Create and register a group and activatable object + */ - if (message1.equals(MESSAGE1)) { - System.err.println("Test1a passed: initial MarshalledObject " + - "correct"); - } else { - TestLibrary.bomb("Test1 failed: unexpected MarshalledObject passed to " + - "constructor", null); - } + System.err.println("Creating group descriptor"); + Properties props = new Properties(); + props.put("java.security.policy", + TestParams.defaultGroupPolicy); + props.put("java.security.manager", + TestParams.defaultSecurityManager); + props.put("test.message", MESSAGE1); + ActivationGroupDesc initialGroupDesc = + new ActivationGroupDesc(props, null); + System.err.println("Registering group"); + ActivationSystem system = ActivationGroup.getSystem(); + ActivationGroupID groupID = system.registerGroup(initialGroupDesc); - /* - * Get property from remote group and make sure it's okay - */ - message1 = obj.getProperty("test.message"); - if (message1.equals(MESSAGE1)) { - System.err.println("Test1b passed: initial group property " + - "correct"); - } else { - TestLibrary.bomb("Test1 failed: unexpected property passed to " + - "group", null); - } + System.err.println("Creating descriptor"); + ActivationDesc initialDesc = + new ActivationDesc(groupID, "ModifyDescriptor", null, + new MarshalledObject(MESSAGE1), false); - /* - * Update activation descriptor for object and group - */ - System.err.println("Update activation descriptor"); - ActivationDesc newDesc = - new ActivationDesc(groupID, "ModifyDescriptor", null, - new MarshalledObject(MESSAGE2), false); - ActivationID id = obj.getID(); - ActivationDesc oldDesc = system.setActivationDesc(id, newDesc); + System.err.println("Registering descriptor"); + ActivateMe obj = (ActivateMe) Activatable.register(initialDesc); - if (oldDesc.equals(initialDesc)) { - System.err.println("Test2a passed: desc returned from " + - "setActivationDesc is okay"); - } else { - TestLibrary.bomb("Test2a failed: desc returned from setActivationDesc " + - "is not the initial descriptor!", null); - } + /* + * Ping object and verify that MarshalledObject is okay. + */ + System.err.println("Ping object"); + String message1 = obj.getMessage(); + System.err.println("message = " + message1); + + if (message1.equals(MESSAGE1)) { + System.err.println("Test1a passed: initial MarshalledObject " + + "correct"); + } else { + TestLibrary.bomb("Test1 failed: unexpected MarshalledObject passed to " + + "constructor", null); + } + + /* + * Get property from remote group and make sure it's okay + */ + message1 = obj.getProperty("test.message"); + if (message1.equals(MESSAGE1)) { + System.err.println("Test1b passed: initial group property " + + "correct"); + } else { + TestLibrary.bomb("Test1 failed: unexpected property passed to " + + "group", null); + } + + /* + * Update activation descriptor for object and group + */ + System.err.println("Update activation descriptor"); + ActivationDesc newDesc = + new ActivationDesc(groupID, "ModifyDescriptor", null, + new MarshalledObject(MESSAGE2), false); + ActivationID id = obj.getID(); + ActivationDesc oldDesc = system.setActivationDesc(id, newDesc); + + if (oldDesc.equals(initialDesc)) { + System.err.println("Test2a passed: desc returned from " + + "setActivationDesc is okay"); + } else { + TestLibrary.bomb("Test2a failed: desc returned from setActivationDesc " + + "is not the initial descriptor!", null); + } - Properties props2 = new Properties(); - props2.put("test.message", MESSAGE2); - props2.put("java.security.policy", - TestParams.defaultGroupPolicy); - props2.put("java.security.manager", - TestParams.defaultSecurityManager); - ActivationGroupDesc newGroupDesc = - new ActivationGroupDesc(props2, null); + Properties props2 = new Properties(); + props2.put("test.message", MESSAGE2); + props2.put("java.security.policy", + TestParams.defaultGroupPolicy); + props2.put("java.security.manager", + TestParams.defaultSecurityManager); + ActivationGroupDesc newGroupDesc = + new ActivationGroupDesc(props2, null); - ActivationGroupDesc oldGroupDesc = - system.setActivationGroupDesc(groupID, newGroupDesc); + ActivationGroupDesc oldGroupDesc = + system.setActivationGroupDesc(groupID, newGroupDesc); - if (oldGroupDesc.equals(initialGroupDesc)) { - System.err.println("Test2b passed: group desc returned from " + - "setActivationGroupDesc is okay"); - } else { - TestLibrary.bomb("Test2b failed: group desc returned from " + - "setActivationGroupDesc is not the initial descriptor!", - null); - } - - /* - * Restart rmid; and ping object to make sure that it has - * new message. - */ - rmid.restart(); + if (oldGroupDesc.equals(initialGroupDesc)) { + System.err.println("Test2b passed: group desc returned from " + + "setActivationGroupDesc is okay"); + } else { + TestLibrary.bomb("Test2b failed: group desc returned from " + + "setActivationGroupDesc is not the initial descriptor!", + null); + } - System.err.println("Ping object after restart"); - String message2 = obj.getMessage(); + /* + * Restart rmid; and ping object to make sure that it has + * new message. + */ + rmid.restart(); - if (message2.equals(MESSAGE2)) { - System.err.println("Test3a passed: setActivationDesc takes " + - "effect after a restart"); - } else { - TestLibrary.bomb("Test3a failed: setActivationDesc did not take effect " + - "after a restart", null); - } + System.err.println("Ping object after restart"); + String message2 = obj.getMessage(); - message2 = obj.getProperty("test.message"); - - if (message2.equals(MESSAGE2)) { - System.err.println("Test3b passed: setActivationGroupDesc " + - "takes effect after a restart"); - } else { - TestLibrary.bomb("Test3b failed: setActivationGroupDesc did not take " + - "effect after a restart", null); - } + if (message2.equals(MESSAGE2)) { + System.err.println("Test3a passed: setActivationDesc takes " + + "effect after a restart"); + } else { + TestLibrary.bomb("Test3a failed: setActivationDesc did not take effect " + + "after a restart", null); + } - System.err.println("Get activation descriptor"); - ActivationDesc latestDesc = system.getActivationDesc(id); + message2 = obj.getProperty("test.message"); - if (latestDesc.equals(newDesc)) { - System.err.println("Test4a passed: desc is same as latest"); - } else { - TestLibrary.bomb("Test4a failed: there is no way this would happen", null); - } + if (message2.equals(MESSAGE2)) { + System.err.println("Test3b passed: setActivationGroupDesc " + + "takes effect after a restart"); + } else { + TestLibrary.bomb("Test3b failed: setActivationGroupDesc did not take " + + "effect after a restart", null); + } - System.err.println("Get activation group descriptor"); - ActivationGroupDesc latestGroupDesc = - system.getActivationGroupDesc(groupID); + System.err.println("Get activation descriptor"); + ActivationDesc latestDesc = system.getActivationDesc(id); - if (latestGroupDesc.equals(newGroupDesc)) { - System.err.println("Test4b passed: group desc is same as " + - "latest"); - } else { - TestLibrary.bomb("Test4b failed: there is no way this would happen", null); - } - - } catch (Exception e) { - TestLibrary.bomb("test failed", e); - } finally { - ActivationLibrary.rmidCleanup(rmid); - } + if (latestDesc.equals(newDesc)) { + System.err.println("Test4a passed: desc is same as latest"); + } else { + TestLibrary.bomb("Test4a failed: there is no way this would happen", null); + } + + System.err.println("Get activation group descriptor"); + ActivationGroupDesc latestGroupDesc = + system.getActivationGroupDesc(groupID); + + if (latestGroupDesc.equals(newGroupDesc)) { + System.err.println("Test4b passed: group desc is same as " + + "latest"); + } else { + TestLibrary.bomb("Test4b failed: there is no way this would happen", null); + } + + } catch (Exception e) { + TestLibrary.bomb("test failed", e); + } finally { + ActivationLibrary.rmidCleanup(rmid); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor_Stub.java b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor_Stub.java index bcf33b65bfb..d7f9080c278 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor_Stub.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,166 +29,166 @@ public final class ModifyDescriptor_Stub implements ActivateMe { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("java.rmi.activation.ActivationID getID()"), - new java.rmi.server.Operation("java.lang.String getMessage()"), - new java.rmi.server.Operation("java.lang.String getProperty(java.lang.String)"), - new java.rmi.server.Operation("void shutdown()") + new java.rmi.server.Operation("java.rmi.activation.ActivationID getID()"), + new java.rmi.server.Operation("java.lang.String getMessage()"), + new java.rmi.server.Operation("java.lang.String getProperty(java.lang.String)"), + new java.rmi.server.Operation("void shutdown()") }; - + private static final long interfaceHash = 7998207954486691383L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_getID_0; private static java.lang.reflect.Method $method_getMessage_1; private static java.lang.reflect.Method $method_getProperty_2; private static java.lang.reflect.Method $method_shutdown_3; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_getID_0 = ActivateMe.class.getMethod("getID", new java.lang.Class[] {}); - $method_getMessage_1 = ActivateMe.class.getMethod("getMessage", new java.lang.Class[] {}); - $method_getProperty_2 = ActivateMe.class.getMethod("getProperty", new java.lang.Class[] {java.lang.String.class}); - $method_shutdown_3 = ActivateMe.class.getMethod("shutdown", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_getID_0 = ActivateMe.class.getMethod("getID", new java.lang.Class[] {}); + $method_getMessage_1 = ActivateMe.class.getMethod("getMessage", new java.lang.Class[] {}); + $method_getProperty_2 = ActivateMe.class.getMethod("getProperty", new java.lang.Class[] {java.lang.String.class}); + $method_shutdown_3 = ActivateMe.class.getMethod("shutdown", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public ModifyDescriptor_Stub() { - super(); + super(); } public ModifyDescriptor_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of getID() public java.rmi.activation.ActivationID getID() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getID_0, null, -7795865521150345044L); - return ((java.rmi.activation.ActivationID) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - java.rmi.activation.ActivationID $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.rmi.activation.ActivationID) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getID_0, null, -7795865521150345044L); + return ((java.rmi.activation.ActivationID) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + java.rmi.activation.ActivationID $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.rmi.activation.ActivationID) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of getMessage() public java.lang.String getMessage() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getMessage_1, null, 5353407034680111516L); - return ((java.lang.String) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - ref.invoke(call); - java.lang.String $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.lang.String) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getMessage_1, null, 5353407034680111516L); + return ((java.lang.String) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + ref.invoke(call); + java.lang.String $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.String) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of getProperty(String) public java.lang.String getProperty(java.lang.String $param_String_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getProperty_2, new java.lang.Object[] {$param_String_1}, 77249282285080913L); - return ((java.lang.String) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_String_1); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - java.lang.String $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.lang.String) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getProperty_2, new java.lang.Object[] {$param_String_1}, 77249282285080913L); + return ((java.lang.String) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_String_1); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + java.lang.String $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.String) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of shutdown() public void shutdown() - throws java.lang.Exception + throws java.lang.Exception { - if (useNewInvoke) { - ref.invoke(this, $method_shutdown_3, null, -7207851917985848402L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); - ref.invoke(call); - ref.done(call); - } + if (useNewInvoke) { + ref.invoke(this, $method_shutdown_3, null, -7207851917985848402L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); + ref.invoke(call); + ref.done(call); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/CanCreateStubs.java b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/CanCreateStubs.java index ed12d06ed88..7ee66f59c95 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/CanCreateStubs.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/CanCreateStubs.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,4 +34,3 @@ interface CanCreateStubs extends java.rmi.Remote { Object getForbiddenClass() throws Exception; ActivationGroupID returnGroupID() throws RemoteException; } - diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java index ab3f28eaf41..8b47547f8a0 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -20,7 +20,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ - + /* @test * @bug 4179055 * @summary Some java apps need to have access to read "accessClassInPackage.sun.rmi.server" @@ -55,151 +55,151 @@ import java.util.StringTokenizer; * * The test causes the activation system to need to create each of * these classes in turn. The test will fail if the activation system - * does not allow these classes to be created. + * does not allow these classes to be created. */ public class StubClassesPermitted extends Activatable implements Runnable, CanCreateStubs { public static boolean sameGroup = false; - + private static CanCreateStubs canCreateStubs = null; private static Registry registry = null; - public static void main(String args[]) { + public static void main(String args[]) { - sameGroup = true; - - RMID rmid = null; + sameGroup = true; - System.err.println("\nRegression test for bug/rfe 4179055\n"); - - try { - TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); + RMID rmid = null; - registry = java.rmi.registry.LocateRegistry. - createRegistry(TestLibrary.REGISTRY_PORT); + System.err.println("\nRegression test for bug/rfe 4179055\n"); - // must run with java.lang.SecurityManager or the test - // result will be nullified if running with a build where - // 4180392 has not been fixed. - String smClassName = - System.getSecurityManager().getClass().getName(); - if (!smClassName.equals("java.lang.SecurityManager")) { - TestLibrary.bomb("Test must run with java.lang.SecurityManager"); - } + try { + TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); - // start an rmid. - RMID.removeLog(); - rmid = RMID.createRMID(); - rmid.start(); + registry = java.rmi.registry.LocateRegistry. + createRegistry(TestLibrary.REGISTRY_PORT); - //rmid.addOptions(new String[] {"-C-Djava.rmi.server.logCalls=true"}); + // must run with java.lang.SecurityManager or the test + // result will be nullified if running with a build where + // 4180392 has not been fixed. + String smClassName = + System.getSecurityManager().getClass().getName(); + if (!smClassName.equals("java.lang.SecurityManager")) { + TestLibrary.bomb("Test must run with java.lang.SecurityManager"); + } - // Ensure that activation groups run with the correct - // security manager. - // - Properties p = new Properties(); - p.put("java.security.policy", - TestParams.defaultGroupPolicy); - p.put("java.security.manager", - "java.lang.SecurityManager"); + // start an rmid. + RMID.removeLog(); + rmid = RMID.createRMID(); + rmid.start(); - // This action causes the following classes to be created - // in this VM (RMI must permit the creation of these classes): - // - // sun.rmi.server.Activation$ActivationSystemImpl_Stub - // sun.rmi.server.Activation$ActivationMonitorImpl_Stub - // - System.err.println("Create activation group, in a new VM"); - ActivationGroupDesc groupDesc = - new ActivationGroupDesc(p, null); - ActivationSystem system = ActivationGroup.getSystem(); - ActivationGroupID groupID = system.registerGroup(groupDesc); - - System.err.println("register activatable"); - // Fix for: 4271615: make sure activation group runs in a new VM - ActivationDesc desc = new ActivationDesc - (groupID, "StubClassesPermitted", null, null); - canCreateStubs = (CanCreateStubs) Activatable.register(desc); + //rmid.addOptions(new String[] {"-C-Djava.rmi.server.logCalls=true"}); - // ensure registry stub can be passed in a remote call - System.err.println("getting the registry"); - registry = canCreateStubs.getRegistry(); + // Ensure that activation groups run with the correct + // security manager. + // + Properties p = new Properties(); + p.put("java.security.policy", + TestParams.defaultGroupPolicy); + p.put("java.security.manager", + "java.lang.SecurityManager"); - // make sure a client cant load just any sun.* class, just - // as a sanity check, try to create a class we are not - // allowed to access but which was passed in a remote call - try { - System.err.println("accessing forbidden class"); - Object secureRandom = canCreateStubs.getForbiddenClass(); - - TestLibrary.bomb("test allowed to access forbidden class," + - " sun.security.provider.SecureRandom"); - } catch (java.security.AccessControlException e) { + // This action causes the following classes to be created + // in this VM (RMI must permit the creation of these classes): + // + // sun.rmi.server.Activation$ActivationSystemImpl_Stub + // sun.rmi.server.Activation$ActivationMonitorImpl_Stub + // + System.err.println("Create activation group, in a new VM"); + ActivationGroupDesc groupDesc = + new ActivationGroupDesc(p, null); + ActivationSystem system = ActivationGroup.getSystem(); + ActivationGroupID groupID = system.registerGroup(groupDesc); - // Make sure we received a *local* AccessControlException - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(bout); - e.printStackTrace(ps); - ps.flush(); - String trace = new String(bout.toByteArray()); - if ((trace.indexOf("exceptionReceivedFromServer") >= 0) || - trace.equals("")) + System.err.println("register activatable"); + // Fix for: 4271615: make sure activation group runs in a new VM + ActivationDesc desc = new ActivationDesc + (groupID, "StubClassesPermitted", null, null); + canCreateStubs = (CanCreateStubs) Activatable.register(desc); + + // ensure registry stub can be passed in a remote call + System.err.println("getting the registry"); + registry = canCreateStubs.getRegistry(); + + // make sure a client cant load just any sun.* class, just + // as a sanity check, try to create a class we are not + // allowed to access but which was passed in a remote call + try { + System.err.println("accessing forbidden class"); + Object secureRandom = canCreateStubs.getForbiddenClass(); + + TestLibrary.bomb("test allowed to access forbidden class," + + " sun.security.provider.SecureRandom"); + } catch (java.security.AccessControlException e) { + + // Make sure we received a *local* AccessControlException + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(bout); + e.printStackTrace(ps); + ps.flush(); + String trace = new String(bout.toByteArray()); + if ((trace.indexOf("exceptionReceivedFromServer") >= 0) || + trace.equals("")) { - throw e; - } - System.err.println("received expected local access control exception"); - } + throw e; + } + System.err.println("received expected local access control exception"); + } - // make sure that an ActivationGroupID can be passed in a - // remote call; this is slightly more inclusive than - // just passing a reference to the activation system - System.err.println("returning group desc"); - canCreateStubs.returnGroupID(); - - // Clean up object - System.err.println - ("Deactivate object via method call"); - canCreateStubs.shutdown(); + // make sure that an ActivationGroupID can be passed in a + // remote call; this is slightly more inclusive than + // just passing a reference to the activation system + System.err.println("returning group desc"); + canCreateStubs.returnGroupID(); - System.err.println - ("\nsuccess: StubClassesPermitted test passed "); - - } catch (Exception e) { - TestLibrary.bomb("\nfailure: unexpected exception ", e); - } finally { - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - } - - canCreateStubs = null; - ActivationLibrary.rmidCleanup(rmid); - System.err.println("rmid shut down"); - } + // Clean up object + System.err.println + ("Deactivate object via method call"); + canCreateStubs.shutdown(); + + System.err.println + ("\nsuccess: StubClassesPermitted test passed "); + + } catch (Exception e) { + TestLibrary.bomb("\nfailure: unexpected exception ", e); + } finally { + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + } + + canCreateStubs = null; + ActivationLibrary.rmidCleanup(rmid); + System.err.println("rmid shut down"); + } } - + static ActivationGroupID GroupID = null; /** - * implementation of CanCreateStubs + * implementation of CanCreateStubs */ public StubClassesPermitted - (ActivationID id, MarshalledObject mo) throws RemoteException + (ActivationID id, MarshalledObject mo) throws RemoteException { - // register/export anonymously - super(id, 0); + // register/export anonymously + super(id, 0); - // obtain reference to the test registry - registry = java.rmi.registry.LocateRegistry. - getRegistry(TestLibrary.REGISTRY_PORT); + // obtain reference to the test registry + registry = java.rmi.registry.LocateRegistry. + getRegistry(TestLibrary.REGISTRY_PORT); } - + /** * Spawns a thread to deactivate the object. */ public void shutdown() throws Exception { - (new Thread(this,"StubClassesPermitted")).start(); + (new Thread(this,"StubClassesPermitted")).start(); } /** @@ -209,7 +209,7 @@ public class StubClassesPermitted * unexport the object forcibly. */ public void run() { - ActivationLibrary.deactivate(this, getID()); + ActivationLibrary.deactivate(this, getID()); } /** @@ -217,12 +217,12 @@ public class StubClassesPermitted * the stub for it can be deserialized in the test client VM. */ public Registry getRegistry() throws RemoteException { - if (sameGroup) { - System.out.println("in same group"); - } else { - System.out.println("not in same group"); - } - return registry; + if (sameGroup) { + System.out.println("in same group"); + } else { + System.out.println("not in same group"); + } + return registry; } /** @@ -232,8 +232,8 @@ public class StubClassesPermitted * can be resolved in a remote call. */ public Object getForbiddenClass() throws RemoteException { - System.err.println("creating sun class"); - return new sun.security.provider.SecureRandom(); + System.err.println("creating sun class"); + return new sun.security.provider.SecureRandom(); } /** @@ -242,6 +242,6 @@ public class StubClassesPermitted * system implementation). */ public ActivationGroupID returnGroupID() throws RemoteException { - return ActivationGroup.currentGroupID(); + return ActivationGroup.currentGroupID(); } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted_Stub.java b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted_Stub.java index 829e2abf695..a8cb2d81f5f 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted_Stub.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,152 +29,152 @@ public final class StubClassesPermitted_Stub implements CanCreateStubs, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("java.lang.Object getForbiddenClass()"), - new java.rmi.server.Operation("java.rmi.registry.Registry getRegistry()"), - new java.rmi.server.Operation("java.rmi.activation.ActivationGroupID returnGroupID()"), - new java.rmi.server.Operation("void shutdown()") + new java.rmi.server.Operation("java.lang.Object getForbiddenClass()"), + new java.rmi.server.Operation("java.rmi.registry.Registry getRegistry()"), + new java.rmi.server.Operation("java.rmi.activation.ActivationGroupID returnGroupID()"), + new java.rmi.server.Operation("void shutdown()") }; - + private static final long interfaceHash = 1677779850431817575L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_getForbiddenClass_0; private static java.lang.reflect.Method $method_getRegistry_1; private static java.lang.reflect.Method $method_returnGroupID_2; private static java.lang.reflect.Method $method_shutdown_3; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_getForbiddenClass_0 = CanCreateStubs.class.getMethod("getForbiddenClass", new java.lang.Class[] {}); - $method_getRegistry_1 = CanCreateStubs.class.getMethod("getRegistry", new java.lang.Class[] {}); - $method_returnGroupID_2 = CanCreateStubs.class.getMethod("returnGroupID", new java.lang.Class[] {}); - $method_shutdown_3 = CanCreateStubs.class.getMethod("shutdown", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_getForbiddenClass_0 = CanCreateStubs.class.getMethod("getForbiddenClass", new java.lang.Class[] {}); + $method_getRegistry_1 = CanCreateStubs.class.getMethod("getRegistry", new java.lang.Class[] {}); + $method_returnGroupID_2 = CanCreateStubs.class.getMethod("returnGroupID", new java.lang.Class[] {}); + $method_shutdown_3 = CanCreateStubs.class.getMethod("shutdown", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public StubClassesPermitted_Stub() { - super(); + super(); } public StubClassesPermitted_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of getForbiddenClass() public java.lang.Object getForbiddenClass() - throws java.lang.Exception + throws java.lang.Exception { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getForbiddenClass_0, null, -658265783646674294L); - return ((java.lang.Object) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - java.lang.Object $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.lang.Object) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getForbiddenClass_0, null, -658265783646674294L); + return ((java.lang.Object) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + java.lang.Object $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.Object) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } } - + // implementation of getRegistry() public java.rmi.registry.Registry getRegistry() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getRegistry_1, null, 255311215504696981L); - return ((java.rmi.registry.Registry) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - ref.invoke(call); - java.rmi.registry.Registry $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.rmi.registry.Registry) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getRegistry_1, null, 255311215504696981L); + return ((java.rmi.registry.Registry) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + ref.invoke(call); + java.rmi.registry.Registry $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.rmi.registry.Registry) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of returnGroupID() public java.rmi.activation.ActivationGroupID returnGroupID() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_returnGroupID_2, null, 6267304638191237098L); - return ((java.rmi.activation.ActivationGroupID) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); - ref.invoke(call); - java.rmi.activation.ActivationGroupID $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.rmi.activation.ActivationGroupID) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_returnGroupID_2, null, 6267304638191237098L); + return ((java.rmi.activation.ActivationGroupID) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); + ref.invoke(call); + java.rmi.activation.ActivationGroupID $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.rmi.activation.ActivationGroupID) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of shutdown() public void shutdown() - throws java.lang.Exception + throws java.lang.Exception { - if (useNewInvoke) { - ref.invoke(this, $method_shutdown_3, null, -7207851917985848402L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); - ref.invoke(call); - ref.done(call); - } + if (useNewInvoke) { + ref.invoke(this, $method_shutdown_3, null, -7207851917985848402L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); + ref.invoke(call); + ref.done(call); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/ActivateMe.java b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/ActivateMe.java index cf165fb3141..d9848e3c815 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/ActivateMe.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/ActivateMe.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/CallbackInterface.java b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/CallbackInterface.java index 287346fa031..e737ac91603 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/CallbackInterface.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/CallbackInterface.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,4 +27,3 @@ public interface CallbackInterface extends Remote { public void inc() throws RemoteException; public int getNumDeactivated() throws RemoteException; } - diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/Callback_Stub.java b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/Callback_Stub.java index 8e77ed15094..4e8a85d759b 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/Callback_Stub.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/Callback_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,94 +29,94 @@ public final class Callback_Stub implements CallbackInterface, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("int getNumDeactivated()"), - new java.rmi.server.Operation("void inc()") + new java.rmi.server.Operation("int getNumDeactivated()"), + new java.rmi.server.Operation("void inc()") }; - + private static final long interfaceHash = -1008194523112388035L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_getNumDeactivated_0; private static java.lang.reflect.Method $method_inc_1; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_getNumDeactivated_0 = CallbackInterface.class.getMethod("getNumDeactivated", new java.lang.Class[] {}); - $method_inc_1 = CallbackInterface.class.getMethod("inc", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_getNumDeactivated_0 = CallbackInterface.class.getMethod("getNumDeactivated", new java.lang.Class[] {}); + $method_inc_1 = CallbackInterface.class.getMethod("inc", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public Callback_Stub() { - super(); + super(); } public Callback_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of getNumDeactivated() public int getNumDeactivated() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getNumDeactivated_0, null, -761062487639949912L); - return ((java.lang.Integer) $result).intValue(); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - int $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = in.readInt(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getNumDeactivated_0, null, -761062487639949912L); + return ((java.lang.Integer) $result).intValue(); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + int $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = in.readInt(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of inc() public void inc() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_inc_1, null, 4394985085384332959L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_inc_1, null, 4394985085384332959L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java index 6498f738ffa..605b66b1ec8 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -65,8 +65,8 @@ class Callback extends UnicastRemoteObject implements CallbackInterface { } public class UnregisterGroup - extends Activatable - implements ActivateMe, Runnable + extends Activatable + implements ActivateMe, Runnable { private static Exception exception = null; @@ -77,30 +77,30 @@ public class UnregisterGroup private static int PORT = 2006; public UnregisterGroup(ActivationID id, MarshalledObject mobj) - throws Exception + throws Exception { - super(id, 0); + super(id, 0); } public void ping() {} public void unregister() throws Exception { - super.unregister(super.getID()); + super.unregister(super.getID()); } - + /** * Spawns a thread to deactivate the object. */ public void shutdown() throws Exception { - (new Thread(this,"UnregisterGroup")).start(); + (new Thread(this,"UnregisterGroup")).start(); } /** * To support exiting of group VM as a last resort */ public void justGoAway() { - System.exit(0); + System.exit(0); } /** @@ -111,151 +111,151 @@ public class UnregisterGroup */ public void run() { - ActivationLibrary.deactivate(this, getID()); - System.err.println("\tActivationLibrary.deactivate returned"); + ActivationLibrary.deactivate(this, getID()); + System.err.println("\tActivationLibrary.deactivate returned"); - try { - CallbackInterface cobj = - (CallbackInterface)Naming.lookup("//:" + PORT + "/Callback"); - cobj.inc(); - } catch (Exception e) { - System.err.println("cobj.inc exception"); - e.printStackTrace(); - } + try { + CallbackInterface cobj = + (CallbackInterface)Naming.lookup("//:" + PORT + "/Callback"); + cobj.inc(); + } catch (Exception e) { + System.err.println("cobj.inc exception"); + e.printStackTrace(); + } } public static void main(String[] args) { - Registry registry; + Registry registry; - System.err.println("\nRegression test for bug 4134233\n"); - - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - RMID rmid = null; - - try { - RMID.removeLog(); - rmid = RMID.createRMID(); - rmid.start(); + System.err.println("\nRegression test for bug 4134233\n"); - /* Cause activation groups to have a security policy that will - * allow security managers to be downloaded and installed - */ - final Properties p = new Properties(); - // this test must always set policies/managers in its - // activation groups - p.put("java.security.policy", - TestParams.defaultGroupPolicy); - p.put("java.security.manager", - TestParams.defaultSecurityManager); + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + RMID rmid = null; - //final int NUM_OBJECTS = 10; - - Thread t = new Thread() { - public void run () { - try { - System.err.println("Creating group descriptor"); - ActivationGroupDesc groupDesc = - new ActivationGroupDesc(p, null); - ActivationSystem system = ActivationGroup.getSystem(); - ActivationGroupID groupID = - system.registerGroup(groupDesc); + try { + RMID.removeLog(); + rmid = RMID.createRMID(); + rmid.start(); - ActivateMe[] obj = new ActivateMe[NUM_OBJECTS]; + /* Cause activation groups to have a security policy that will + * allow security managers to be downloaded and installed + */ + final Properties p = new Properties(); + // this test must always set policies/managers in its + // activation groups + p.put("java.security.policy", + TestParams.defaultGroupPolicy); + p.put("java.security.manager", + TestParams.defaultSecurityManager); - for (int i = 0; i < NUM_OBJECTS; i++) { - System.err.println("Creating descriptor: " + i); - ActivationDesc desc = - new ActivationDesc(groupID, "UnregisterGroup", - null, null); - System.err.println("Registering descriptor: " + i); - obj[i] = (ActivateMe) Activatable.register(desc); - System.err.println("Activating object: " + i); - obj[i].ping(); - } - lastResortExitObj = obj[0]; + //final int NUM_OBJECTS = 10; - System.err.println("Unregistering group"); - system.unregisterGroup(groupID); + Thread t = new Thread() { + public void run () { + try { + System.err.println("Creating group descriptor"); + ActivationGroupDesc groupDesc = + new ActivationGroupDesc(p, null); + ActivationSystem system = ActivationGroup.getSystem(); + ActivationGroupID groupID = + system.registerGroup(groupDesc); - try { - System.err.println("Get the group descriptor"); - system.getActivationGroupDesc(groupID); - error = "test failed: group still registered"; - } catch (UnknownGroupException e) { - System.err.println("Test passed: " + - "group unregistered"); - } + ActivateMe[] obj = new ActivateMe[NUM_OBJECTS]; + + for (int i = 0; i < NUM_OBJECTS; i++) { + System.err.println("Creating descriptor: " + i); + ActivationDesc desc = + new ActivationDesc(groupID, "UnregisterGroup", + null, null); + System.err.println("Registering descriptor: " + i); + obj[i] = (ActivateMe) Activatable.register(desc); + System.err.println("Activating object: " + i); + obj[i].ping(); + } + lastResortExitObj = obj[0]; + + System.err.println("Unregistering group"); + system.unregisterGroup(groupID); + + try { + System.err.println("Get the group descriptor"); + system.getActivationGroupDesc(groupID); + error = "test failed: group still registered"; + } catch (UnknownGroupException e) { + System.err.println("Test passed: " + + "group unregistered"); + } - /* - * Deactivate objects so group VM will exit. - */ - for (int i = 0; i < NUM_OBJECTS; i++) { - System.err.println("Deactivating object: " + i); - obj[i].shutdown(); - obj[i] = null; - } - lastResortExitObj = null; + /* + * Deactivate objects so group VM will exit. + */ + for (int i = 0; i < NUM_OBJECTS; i++) { + System.err.println("Deactivating object: " + i); + obj[i].shutdown(); + obj[i] = null; + } + lastResortExitObj = null; - } catch (Exception e) { - exception = e; - } + } catch (Exception e) { + exception = e; + } - done = true; - } - }; + done = true; + } + }; - t.start(); - t.join(120000); + t.start(); + t.join(120000); - if (exception != null) { - TestLibrary.bomb("test failed", exception); - } else if (error != null) { - TestLibrary.bomb(error, null); - } else if (!done) { - TestLibrary.bomb("test failed: not completed before timeout", null); - } else { - System.err.println("Test passed"); - } + if (exception != null) { + TestLibrary.bomb("test failed", exception); + } else if (error != null) { + TestLibrary.bomb(error, null); + } else if (!done) { + TestLibrary.bomb("test failed: not completed before timeout", null); + } else { + System.err.println("Test passed"); + } - - } catch (Exception e) { - TestLibrary.bomb("test failed", e); - } finally { - if (lastResortExitObj != null) { - try { - lastResortExitObj.justGoAway(); - } catch (Exception munch) { - } - } - // Wait for the object deactivation to take place first - try { + } catch (Exception e) { + TestLibrary.bomb("test failed", e); + } finally { + if (lastResortExitObj != null) { + try { + lastResortExitObj.justGoAway(); + } catch (Exception munch) { + } + } - // create reg and export callback object - registry = LocateRegistry.createRegistry(PORT); - Callback robj = new Callback(); - registry.bind("Callback", robj); + // Wait for the object deactivation to take place first + try { - //get the callback object - int maxwait=30; - int nd = robj.getNumDeactivated(); - while ((nd < NUM_OBJECTS) && (maxwait> 0)) { - System.err.println("num_deactivated="+nd); - try { - Thread.sleep(1000); - } catch (InterruptedException ie) {} - maxwait--; - nd = robj.getNumDeactivated(); - } - } catch (Exception ce) { - System.err.println("E:"+ce); - ce.printStackTrace(); - } + // create reg and export callback object + registry = LocateRegistry.createRegistry(PORT); + Callback robj = new Callback(); + registry.bind("Callback", robj); - ActivationLibrary.rmidCleanup(rmid); - } + //get the callback object + int maxwait=30; + int nd = robj.getNumDeactivated(); + while ((nd < NUM_OBJECTS) && (maxwait> 0)) { + System.err.println("num_deactivated="+nd); + try { + Thread.sleep(1000); + } catch (InterruptedException ie) {} + maxwait--; + nd = robj.getNumDeactivated(); + } + } catch (Exception ce) { + System.err.println("E:"+ce); + ce.printStackTrace(); + } + + ActivationLibrary.rmidCleanup(rmid); + } } } diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup_Stub.java b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup_Stub.java index 16a3278505b..e9a5bcfb141 100644 --- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup_Stub.java +++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,116 +29,116 @@ public final class UnregisterGroup_Stub implements ActivateMe, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("void justGoAway()"), - new java.rmi.server.Operation("void ping()"), - new java.rmi.server.Operation("void shutdown()"), - new java.rmi.server.Operation("void unregister()") + new java.rmi.server.Operation("void justGoAway()"), + new java.rmi.server.Operation("void ping()"), + new java.rmi.server.Operation("void shutdown()"), + new java.rmi.server.Operation("void unregister()") }; - + private static final long interfaceHash = -4733924075192691630L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_justGoAway_0; private static java.lang.reflect.Method $method_ping_1; private static java.lang.reflect.Method $method_shutdown_2; private static java.lang.reflect.Method $method_unregister_3; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_justGoAway_0 = ActivateMe.class.getMethod("justGoAway", new java.lang.Class[] {}); - $method_ping_1 = ActivateMe.class.getMethod("ping", new java.lang.Class[] {}); - $method_shutdown_2 = ActivateMe.class.getMethod("shutdown", new java.lang.Class[] {}); - $method_unregister_3 = ActivateMe.class.getMethod("unregister", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_justGoAway_0 = ActivateMe.class.getMethod("justGoAway", new java.lang.Class[] {}); + $method_ping_1 = ActivateMe.class.getMethod("ping", new java.lang.Class[] {}); + $method_shutdown_2 = ActivateMe.class.getMethod("shutdown", new java.lang.Class[] {}); + $method_unregister_3 = ActivateMe.class.getMethod("unregister", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public UnregisterGroup_Stub() { - super(); + super(); } public UnregisterGroup_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of justGoAway() public void justGoAway() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_justGoAway_0, null, -5382478058620783904L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_justGoAway_0, null, -5382478058620783904L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of ping() public void ping() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_ping_1, null, 5866401369815527589L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_ping_1, null, 5866401369815527589L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of shutdown() public void shutdown() - throws java.lang.Exception + throws java.lang.Exception { - if (useNewInvoke) { - ref.invoke(this, $method_shutdown_2, null, -7207851917985848402L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); - ref.invoke(call); - ref.done(call); - } + if (useNewInvoke) { + ref.invoke(this, $method_shutdown_2, null, -7207851917985848402L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); + ref.invoke(call); + ref.done(call); + } } - + // implementation of unregister() public void unregister() - throws java.lang.Exception + throws java.lang.Exception { - if (useNewInvoke) { - ref.invoke(this, $method_unregister_3, null, -5366864281862648102L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); - ref.invoke(call); - ref.done(call); - } + if (useNewInvoke) { + ref.invoke(this, $method_unregister_3, null, -5366864281862648102L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); + ref.invoke(call); + ref.done(call); + } } } diff --git a/jdk/test/java/rmi/dgc/VMID/CheckVMID.java b/jdk/test/java/rmi/dgc/VMID/CheckVMID.java index ae32872b943..09e4cbec91e 100644 --- a/jdk/test/java/rmi/dgc/VMID/CheckVMID.java +++ b/jdk/test/java/rmi/dgc/VMID/CheckVMID.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,17 +41,17 @@ public class CheckVMID { public static void main(String[] args) { - System.err.println("\nRegression test for bug 4171370\n"); + System.err.println("\nRegression test for bug 4171370\n"); - TestLibrary.suggestSecurityManager(null); + TestLibrary.suggestSecurityManager(null); - try { - System.err.println("Create a VMID"); - VMID vmid = new VMID(); - System.err.println("vmid = " + vmid); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("TEST FAILED: " + e.toString()); - } + try { + System.err.println("Create a VMID"); + VMID vmid = new VMID(); + System.err.println("vmid = " + vmid); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("TEST FAILED: " + e.toString()); + } } } diff --git a/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java b/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java index 446b2405ccf..2a0e4309be2 100644 --- a/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java +++ b/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -51,123 +51,123 @@ public class DGCAckFailure implements ReturnRemote { private static final long TIMEOUT = 20000; public Object returnRemote() { - return new Wrapper(this); + return new Wrapper(this); } public static void main(String[] args) throws Exception { - System.setProperty("sun.rmi.dgc.ackTimeout", "10000"); + System.setProperty("sun.rmi.dgc.ackTimeout", "10000"); - /* - * Set a socket factory that has a hook for shutting down all client - * output (writes from client-created sockets and new connection - * attempts). We then use this hook right before a remote stub gets - * deserialized, so that the client will not be able to send a DGC - * dirty call, or a DGC acknowledgment. Without the DGC ack, we - * hope that the RMI runtime will still eventually allow the remote - * object to be garbage collected. - */ - RMISocketFactory.setSocketFactory(new TestSF()); - System.err.println("test socket factory set"); + /* + * Set a socket factory that has a hook for shutting down all client + * output (writes from client-created sockets and new connection + * attempts). We then use this hook right before a remote stub gets + * deserialized, so that the client will not be able to send a DGC + * dirty call, or a DGC acknowledgment. Without the DGC ack, we + * hope that the RMI runtime will still eventually allow the remote + * object to be garbage collected. + */ + RMISocketFactory.setSocketFactory(new TestSF()); + System.err.println("test socket factory set"); - Remote impl = new DGCAckFailure(); - ReferenceQueue refQueue = new ReferenceQueue(); - Reference weakRef = new WeakReference(impl, refQueue); - ReturnRemote stub = - (ReturnRemote) UnicastRemoteObject.exportObject(impl); - System.err.println("remote object exported; stub = " + stub); + Remote impl = new DGCAckFailure(); + ReferenceQueue refQueue = new ReferenceQueue(); + Reference weakRef = new WeakReference(impl, refQueue); + ReturnRemote stub = + (ReturnRemote) UnicastRemoteObject.exportObject(impl); + System.err.println("remote object exported; stub = " + stub); - try { - Object wrappedStub = stub.returnRemote(); - System.err.println("invocation returned: " + wrappedStub); + try { + Object wrappedStub = stub.returnRemote(); + System.err.println("invocation returned: " + wrappedStub); - impl = null; - stub = null; // in case 4114579 ever gets fixed - System.err.println("strong references to impl cleared"); + impl = null; + stub = null; // in case 4114579 ever gets fixed + System.err.println("strong references to impl cleared"); - System.err.println("waiting for weak reference notification:"); - Reference ref = null; - for (int i = 0; i < 6; i++) { - System.gc(); - ref = refQueue.remove(TIMEOUT / 5); - if (ref != null) { - break; - } - } - if (ref == weakRef) { - System.err.println("TEST PASSED"); - } else { - throw new RuntimeException("TEST FAILED: " + - "timed out, remote object not garbage collected"); - } - } finally { - try { - UnicastRemoteObject.unexportObject((Remote) weakRef.get(), - true); - } catch (Exception e) { - } - } + System.err.println("waiting for weak reference notification:"); + Reference ref = null; + for (int i = 0; i < 6; i++) { + System.gc(); + ref = refQueue.remove(TIMEOUT / 5); + if (ref != null) { + break; + } + } + if (ref == weakRef) { + System.err.println("TEST PASSED"); + } else { + throw new RuntimeException("TEST FAILED: " + + "timed out, remote object not garbage collected"); + } + } finally { + try { + UnicastRemoteObject.unexportObject((Remote) weakRef.get(), + true); + } catch (Exception e) { + } + } } private static class Wrapper implements Serializable { - private final Remote obj; - Wrapper(Remote obj) { this.obj = obj; } + private final Remote obj; + Wrapper(Remote obj) { this.obj = obj; } - private void readObject(ObjectInputStream in) - throws IOException, ClassNotFoundException - { - TestSF.shutdownClientOutput(); - System.err.println( - "Wrapper.readObject: SHUTTING DOWN CLIENT OUTPUT"); - in.defaultReadObject(); - } + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + TestSF.shutdownClientOutput(); + System.err.println( + "Wrapper.readObject: SHUTTING DOWN CLIENT OUTPUT"); + in.defaultReadObject(); + } - public String toString() { return "Wrapper[" + obj + "]"; } + public String toString() { return "Wrapper[" + obj + "]"; } } private static class TestSF extends RMISocketFactory { - private static volatile boolean shutdown = false; - static void shutdownClientOutput() { shutdown = true; } + private static volatile boolean shutdown = false; + static void shutdownClientOutput() { shutdown = true; } - public Socket createSocket(String host, int port) throws IOException { - if (shutdown) { - IOException e = new java.net.ConnectException( - "test socket factory rejecting client connection"); - System.err.println(e); -// e.printStackTrace(); - throw e; - } else { - return new TestSocket(host, port); - } - } + public Socket createSocket(String host, int port) throws IOException { + if (shutdown) { + IOException e = new java.net.ConnectException( + "test socket factory rejecting client connection"); + System.err.println(e); +// e.printStackTrace(); + throw e; + } else { + return new TestSocket(host, port); + } + } - public ServerSocket createServerSocket(int port) throws IOException { - return new ServerSocket(port); - } + public ServerSocket createServerSocket(int port) throws IOException { + return new ServerSocket(port); + } - private static class TestSocket extends Socket { - TestSocket(String host, int port) throws IOException { - super(host, port); - } - public OutputStream getOutputStream() throws IOException { - return new TestOutputStream(super.getOutputStream()); - } - } + private static class TestSocket extends Socket { + TestSocket(String host, int port) throws IOException { + super(host, port); + } + public OutputStream getOutputStream() throws IOException { + return new TestOutputStream(super.getOutputStream()); + } + } - private static class TestOutputStream extends FilterOutputStream { - TestOutputStream(OutputStream out) { super(out); } - public void write(int b) throws IOException { - if (shutdown) { - IOException e = new IOException( - "connection broken by test socket factory"); - System.err.println(e); -// e.printStackTrace(); - throw e; - } else { - super.write(b); - } - } - } + private static class TestOutputStream extends FilterOutputStream { + TestOutputStream(OutputStream out) { super(out); } + public void write(int b) throws IOException { + if (shutdown) { + IOException e = new IOException( + "connection broken by test socket factory"); + System.err.println(e); +// e.printStackTrace(); + throw e; + } else { + super.write(b); + } + } + } } } diff --git a/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure_Stub.java b/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure_Stub.java index 1a9ecee6bea..b5819050111 100644 --- a/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure_Stub.java +++ b/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,38 +29,38 @@ public final class DGCAckFailure_Stub implements ReturnRemote { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_returnRemote_0; - + static { - try { - $method_returnRemote_0 = ReturnRemote.class.getMethod("returnRemote", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_returnRemote_0 = ReturnRemote.class.getMethod("returnRemote", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public DGCAckFailure_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of returnRemote() public java.lang.Object returnRemote() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - Object $result = ref.invoke(this, $method_returnRemote_0, null, -8981544221566403070L); - return ((java.lang.Object) $result); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_returnRemote_0, null, -8981544221566403070L); + return ((java.lang.Object) $result); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java b/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java index 83520d217b2..3f06432f352 100644 --- a/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java +++ b/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -57,55 +57,55 @@ public class DGCImplInsulation implements java.rmi.Remote { public static void main(String[] args) throws Exception { - TestLibrary.suggestSecurityManager(null); + TestLibrary.suggestSecurityManager(null); - Permissions perms = new Permissions(); - perms.add(new SocketPermission("*:1024-", "listen")); - AccessControlContext acc = - new AccessControlContext(new ProtectionDomain[] { - new ProtectionDomain( - new CodeSource(null, (Certificate[]) null), perms) }); + Permissions perms = new Permissions(); + perms.add(new SocketPermission("*:1024-", "listen")); + AccessControlContext acc = + new AccessControlContext(new ProtectionDomain[] { + new ProtectionDomain( + new CodeSource(null, (Certificate[]) null), perms) }); - Remote impl = new DGCImplInsulation();; + Remote impl = new DGCImplInsulation();; - try { - Remote stub = (Remote) java.security.AccessController.doPrivileged( - new ExportAction(impl)); - System.err.println("exported remote object; local stub: " + stub); + try { + Remote stub = (Remote) java.security.AccessController.doPrivileged( + new ExportAction(impl)); + System.err.println("exported remote object; local stub: " + stub); - MarshalledObject mobj = new MarshalledObject(stub); - stub = (Remote) mobj.get(); - System.err.println("marshalled/unmarshalled stub: " + stub); + MarshalledObject mobj = new MarshalledObject(stub); + stub = (Remote) mobj.get(); + System.err.println("marshalled/unmarshalled stub: " + stub); - ReferenceQueue refQueue = new ReferenceQueue(); - Reference weakRef = new WeakReference(impl, refQueue); - impl = null; - System.gc(); - if (refQueue.remove(TIMEOUT) == weakRef) { - throw new RuntimeException( - "TEST FAILED: remote object garbage collected"); - } else { - System.err.println("TEST PASSED"); - stub = null; - System.gc(); - Thread.sleep(2000); - System.gc(); - } - } finally { - try { - UnicastRemoteObject.unexportObject(impl, true); - } catch (Exception e) { - } - } + ReferenceQueue refQueue = new ReferenceQueue(); + Reference weakRef = new WeakReference(impl, refQueue); + impl = null; + System.gc(); + if (refQueue.remove(TIMEOUT) == weakRef) { + throw new RuntimeException( + "TEST FAILED: remote object garbage collected"); + } else { + System.err.println("TEST PASSED"); + stub = null; + System.gc(); + Thread.sleep(2000); + System.gc(); + } + } finally { + try { + UnicastRemoteObject.unexportObject(impl, true); + } catch (Exception e) { + } + } } private static class ExportAction implements PrivilegedExceptionAction { - private final Remote impl; - ExportAction(Remote impl) { - this.impl = impl; - } - public Object run() throws Exception { - return UnicastRemoteObject.exportObject(impl); - } + private final Remote impl; + ExportAction(Remote impl) { + this.impl = impl; + } + public Object run() throws Exception { + return UnicastRemoteObject.exportObject(impl); + } } } diff --git a/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation_Stub.java b/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation_Stub.java index e77edf0948e..b73581aa1de 100644 --- a/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation_Stub.java +++ b/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,10 +29,10 @@ public final class DGCImplInsulation_Stub implements java.rmi.Remote { private static final long serialVersionUID = 2; - + // constructors public DGCImplInsulation_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + } diff --git a/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java b/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java index 954615d0f0b..b74931a0943 100644 --- a/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java +++ b/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -55,108 +55,108 @@ public class RetryDirtyCalls implements Self, Unreferenced { * Return this object. The need for this method is explained below. */ public Self getSelf() { - return this; + return this; } public void unreferenced() { - synchronized (this) { - unreferenced = true; - notifyAll(); - } + synchronized (this) { + unreferenced = true; + notifyAll(); + } } public static void main(String[] args) { - System.err.println("\nRegression test for bug 4268258\n"); + System.err.println("\nRegression test for bug 4268258\n"); - /* - * Set properties to tweak DGC behavior so that this test will execute - * quickly: set the granted lease duration to 10 seconds, the interval - * that leases are checked to 3 seconds. - */ - System.setProperty("java.rmi.dgc.leaseValue", "10000"); - System.setProperty("sun.rmi.dgc.checkInterval", "3000"); + /* + * Set properties to tweak DGC behavior so that this test will execute + * quickly: set the granted lease duration to 10 seconds, the interval + * that leases are checked to 3 seconds. + */ + System.setProperty("java.rmi.dgc.leaseValue", "10000"); + System.setProperty("sun.rmi.dgc.checkInterval", "3000"); - /* - * Make idle connections time out almost instantly (0.1 seconds) so - * that the DGC implementation will have to make a new connection for - * each dirty call, thus going through the socket factory, where we - * can easily cause the operation to fail. - */ - System.setProperty("sun.rmi.transport.connectionTimeout", "100"); + /* + * Make idle connections time out almost instantly (0.1 seconds) so + * that the DGC implementation will have to make a new connection for + * each dirty call, thus going through the socket factory, where we + * can easily cause the operation to fail. + */ + System.setProperty("sun.rmi.transport.connectionTimeout", "100"); - RetryDirtyCalls impl = new RetryDirtyCalls(); + RetryDirtyCalls impl = new RetryDirtyCalls(); - try { - TestSF sf = new TestSF(); - RMISocketFactory.setSocketFactory(sf); + try { + TestSF sf = new TestSF(); + RMISocketFactory.setSocketFactory(sf); - /* - * The stub returned by UnicastRemoteObject.exportObject() does - * not participate in DGC, but it does allow us to invoke a method - * on the remote object through RMI. Therefore, we invoke the - * getSelf() method through RMI, which returns an equivalent stub - * that does participate in DGC. - */ - Self stub = (Self) UnicastRemoteObject.exportObject(impl); - Self dgcStub = stub.getSelf(); - stub = null; // in case 4114579 has been fixed + /* + * The stub returned by UnicastRemoteObject.exportObject() does + * not participate in DGC, but it does allow us to invoke a method + * on the remote object through RMI. Therefore, we invoke the + * getSelf() method through RMI, which returns an equivalent stub + * that does participate in DGC. + */ + Self stub = (Self) UnicastRemoteObject.exportObject(impl); + Self dgcStub = stub.getSelf(); + stub = null; // in case 4114579 has been fixed - /* - * Set the socket factory to cause 3 connections attempts in a row - * to fail before allowing a connection to succeed, expecting the - * client-side DGC implementation to make at least four attempts. - */ - final int FLAKE_FACTOR = 3; - sf.setFlakeFactor(FLAKE_FACTOR); + /* + * Set the socket factory to cause 3 connections attempts in a row + * to fail before allowing a connection to succeed, expecting the + * client-side DGC implementation to make at least four attempts. + */ + final int FLAKE_FACTOR = 3; + sf.setFlakeFactor(FLAKE_FACTOR); - long deadline = System.currentTimeMillis() + TIMEOUT; - boolean unreferenced; + long deadline = System.currentTimeMillis() + TIMEOUT; + boolean unreferenced; - synchronized (impl) { - while (!(unreferenced = impl.unreferenced)) { - long timeToWait = deadline - System.currentTimeMillis(); - if (timeToWait > 0) { - impl.wait(timeToWait); - } else { - break; - } - } - } + synchronized (impl) { + while (!(unreferenced = impl.unreferenced)) { + long timeToWait = deadline - System.currentTimeMillis(); + if (timeToWait > 0) { + impl.wait(timeToWait); + } else { + break; + } + } + } - if (unreferenced) { - throw new RuntimeException("remote object unreferenced"); - } + if (unreferenced) { + throw new RuntimeException("remote object unreferenced"); + } - int createCount = sf.getCreateCount(); - if (createCount == 0) { - throw new RuntimeException("test socket factory never used"); - } else if (createCount < (FLAKE_FACTOR + 3)) { - /* - * The unreferenced method was not invoked for some reason, - * but the dirty calls were clearly not retried well enough. - */ - throw new RuntimeException( - "test failed because dirty calls not retried enough, " + - "but remote object not unreferenced"); - } + int createCount = sf.getCreateCount(); + if (createCount == 0) { + throw new RuntimeException("test socket factory never used"); + } else if (createCount < (FLAKE_FACTOR + 3)) { + /* + * The unreferenced method was not invoked for some reason, + * but the dirty calls were clearly not retried well enough. + */ + throw new RuntimeException( + "test failed because dirty calls not retried enough, " + + "but remote object not unreferenced"); + } - System.err.println( - "TEST PASSED: remote object not unreferenced"); + System.err.println( + "TEST PASSED: remote object not unreferenced"); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("TEST FAILED: " + e.toString()); - } finally { - /* - * When all is said and done, try to unexport the remote object - * so that the VM has a chance to exit. - */ - try { - UnicastRemoteObject.unexportObject(impl, true); - } catch (Exception e) { - } - } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("TEST FAILED: " + e.toString()); + } finally { + /* + * When all is said and done, try to unexport the remote object + * so that the VM has a chance to exit. + */ + try { + UnicastRemoteObject.unexportObject(impl, true); + } catch (Exception e) { + } + } } } @@ -169,30 +169,30 @@ class TestSF extends RMISocketFactory { private int createCount = 0; public synchronized void setFlakeFactor(int newFlakeFactor) { - flakeFactor = newFlakeFactor; + flakeFactor = newFlakeFactor; } public synchronized int getCreateCount() { - return createCount; + return createCount; } public synchronized Socket createSocket(String host, int port) - throws IOException + throws IOException { - createCount++; + createCount++; - if (++flakeState > flakeFactor) { - flakeState = 0; - } + if (++flakeState > flakeFactor) { + flakeState = 0; + } - if (flakeState == 0) { - return new Socket(host, port); - } else { - throw new IOException("random network failure"); - } + if (flakeState == 0) { + return new Socket(host, port); + } else { + throw new IOException("random network failure"); + } } public ServerSocket createServerSocket(int port) throws IOException { - return new ServerSocket(port); + return new ServerSocket(port); } } diff --git a/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls_Stub.java b/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls_Stub.java index 4007980eff6..f35e8dccbef 100644 --- a/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls_Stub.java +++ b/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,38 +29,38 @@ public final class RetryDirtyCalls_Stub implements Self { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_getSelf_0; - + static { - try { - $method_getSelf_0 = Self.class.getMethod("getSelf", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_getSelf_0 = Self.class.getMethod("getSelf", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public RetryDirtyCalls_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of getSelf() public Self getSelf() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - Object $result = ref.invoke(this, $method_getSelf_0, null, 2868857108246021904L); - return ((Self) $result); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_getSelf_0, null, 2868857108246021904L); + return ((Self) $result); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java index 56234cfb3a7..4263351b2fb 100644 --- a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java +++ b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,8 +26,8 @@ * @summary rmid and rmiregistry could allow alternate security manager * @author Laird Dornin * - * @library ../../testlibrary - * @build StreamPipe TestParams TestLibrary JavaVM + * @library ../../testlibrary + * @build StreamPipe TestParams TestLibrary JavaVM * @build AltSecurityManager TestSecurityManager * @run main/othervm AltSecurityManager */ @@ -38,7 +38,7 @@ * that throws a runtime exception in its checkListen method, this * will cause rmiregistry and rmid to exit early because those * utilities will be unable to export any remote objects; test fails - * if registry and rmid take too long to exit. + * if registry and rmid take too long to exit. */ public class AltSecurityManager implements Runnable { @@ -54,74 +54,74 @@ public class AltSecurityManager implements Runnable { static long TIME_OUT = 15000; public void run() { - try { - vm = new JavaVM(utilityToStart, - " -Djava.security.manager=TestSecurityManager", - ""); - System.err.println("starting " + utilityToStart); - vm.start(); - vm.getVM().waitFor(); + try { + vm = new JavaVM(utilityToStart, + " -Djava.security.manager=TestSecurityManager", + ""); + System.err.println("starting " + utilityToStart); + vm.start(); + vm.getVM().waitFor(); - } catch (Exception e) { - TestLibrary.bomb(e); - } + } catch (Exception e) { + TestLibrary.bomb(e); + } } - + /** * Wait to make sure that the registry and rmid exit after * their security manager is set. */ public static void ensureExit(String utility) throws Exception { - utilityToStart = utility; - - try { - Thread thread = new Thread(new AltSecurityManager()); - System.err.println("expecting RuntimeException for " + - "checkListen in child process"); - long start = System.currentTimeMillis(); - thread.start(); - thread.join(TIME_OUT); - - long time = System.currentTimeMillis() - start; - System.err.println("waited " + time + " millis for " + - utilityToStart + " to die"); + utilityToStart = utility; - if (time >= TIME_OUT) { - - // dont pollute other tests; increase the likelihood + try { + Thread thread = new Thread(new AltSecurityManager()); + System.err.println("expecting RuntimeException for " + + "checkListen in child process"); + long start = System.currentTimeMillis(); + thread.start(); + thread.join(TIME_OUT); + + long time = System.currentTimeMillis() - start; + System.err.println("waited " + time + " millis for " + + utilityToStart + " to die"); + + if (time >= TIME_OUT) { + + // dont pollute other tests; increase the likelihood // that rmid will go away if it did not exit already. - if (utility.equals(rmid)) { - RMID.shutdown(); - } - - TestLibrary.bomb(utilityToStart + - " took too long to die..."); - } else { - System.err.println(utilityToStart + - " terminated on time"); - } - } finally { - vm.destroy(); - vm = null; - } + if (utility.equals(rmid)) { + RMID.shutdown(); + } + + TestLibrary.bomb(utilityToStart + + " took too long to die..."); + } else { + System.err.println(utilityToStart + + " terminated on time"); + } + } finally { + vm.destroy(); + vm = null; + } } - + public static void main(String[] args) { - try { - System.err.println("\nRegression test for bug 4183202\n"); + try { + System.err.println("\nRegression test for bug 4183202\n"); - // make sure the registry exits early. - ensureExit(registry); + // make sure the registry exits early. + ensureExit(registry); - // make sure rmid exits early - ensureExit(rmid); + // make sure rmid exits early + ensureExit(rmid); - System.err.println("test passed"); + System.err.println("test passed"); - } catch (Exception e) { - TestLibrary.bomb(e); - } finally { - RMID.removeLog(); - } + } catch (Exception e) { + TestLibrary.bomb(e); + } finally { + RMID.removeLog(); + } } } diff --git a/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java b/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java index 4619540b0dd..5d9e16253d0 100644 --- a/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java +++ b/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,18 +28,18 @@ public class TestSecurityManager extends SecurityManager { } public void checkListen(int port) { - // 4269910: ok, now rmid and the regsitry will *really* go - // away... - // - // rmid and the registry need to listen on sockets so they - // will exit when they try to do so... this is used as a sign - // by the main test process to detect that the proper security - // manager has been installed in the relevant VMs. - // - System.exit(1); + // 4269910: ok, now rmid and the regsitry will *really* go + // away... + // + // rmid and the registry need to listen on sockets so they + // will exit when they try to do so... this is used as a sign + // by the main test process to detect that the proper security + // manager has been installed in the relevant VMs. + // + System.exit(1); } public void checkExit(int status) { - // permit check exit for all code + // permit check exit for all code } } diff --git a/jdk/test/java/rmi/registry/checkusage/CheckUsage.java b/jdk/test/java/rmi/registry/checkusage/CheckUsage.java index dbf9a9517e3..37556efb820 100644 --- a/jdk/test/java/rmi/registry/checkusage/CheckUsage.java +++ b/jdk/test/java/rmi/registry/checkusage/CheckUsage.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,48 +36,48 @@ import java.io.ByteArrayOutputStream; /** * Make sure that the rmiregistry prints out a correct usage statement * when run with an incorrect command line; test written to conform to - * new tighter bug fix/regression test guidelines. + * new tighter bug fix/regression test guidelines. */ public class CheckUsage { public static void main(String[] args) { - System.err.println("\nregression test for 4151966\n"); + System.err.println("\nregression test for 4151966\n"); - JavaVM registryVM = null; + JavaVM registryVM = null; - try { - // make sure the registry exits with a proper usage statement - ByteArrayOutputStream berr = new ByteArrayOutputStream(); - - // run a VM to start the registry - registryVM = new JavaVM("sun.rmi.registry.RegistryImpl", - "", "foo", - System.out, berr); - System.err.println("starting registry"); - registryVM.start(); - - // wait for registry exit - System.err.println(" registry exited with status: " + - registryVM.getVM().waitFor()); - try { - Thread.sleep(7000); - } catch (InterruptedException ie) { - } - - String usage = new String(berr.toByteArray()); - - System.err.println("rmiregistry usage: " + usage); - - if (usage.indexOf("-J") < 0) { - TestLibrary.bomb("rmiregistry has incorrect usage statement"); - } else { - System.err.println("test passed"); - } - } catch (Exception e) { - TestLibrary.bomb(e); - } finally { - registryVM.destroy(); - registryVM = null; - } + try { + // make sure the registry exits with a proper usage statement + ByteArrayOutputStream berr = new ByteArrayOutputStream(); + + // run a VM to start the registry + registryVM = new JavaVM("sun.rmi.registry.RegistryImpl", + "", "foo", + System.out, berr); + System.err.println("starting registry"); + registryVM.start(); + + // wait for registry exit + System.err.println(" registry exited with status: " + + registryVM.getVM().waitFor()); + try { + Thread.sleep(7000); + } catch (InterruptedException ie) { + } + + String usage = new String(berr.toByteArray()); + + System.err.println("rmiregistry usage: " + usage); + + if (usage.indexOf("-J") < 0) { + TestLibrary.bomb("rmiregistry has incorrect usage statement"); + } else { + System.err.println("test passed"); + } + } catch (Exception e) { + TestLibrary.bomb(e); + } finally { + registryVM.destroy(); + registryVM = null; + } } } diff --git a/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java b/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java index f94ff8696a9..ad7ba02d35d 100644 --- a/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java +++ b/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -55,121 +55,121 @@ public class ClassPathCodebase { public static void main(String[] args) { - System.err.println("\nRegression test for bug 4242317\n"); + System.err.println("\nRegression test for bug 4242317\n"); - TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); + TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); - Process rmiregistry = null; + Process rmiregistry = null; - try { - /* - * Install a dummy class in two codebases: one that will be in - * the rmiregistry's CLASSPATH (the "import" codebase) and one - * that will be in the rmiregistry's "java.rmi.server.codebase" - * property (the "export" codebase). - */ - URL importCodebaseURL = TestLibrary.installClassInCodebase( - dummyClassName, importCodebase, false); - URL exportCodebaseURL = TestLibrary.installClassInCodebase( - dummyClassName, exportCodebase, true); + try { + /* + * Install a dummy class in two codebases: one that will be in + * the rmiregistry's CLASSPATH (the "import" codebase) and one + * that will be in the rmiregistry's "java.rmi.server.codebase" + * property (the "export" codebase). + */ + URL importCodebaseURL = TestLibrary.installClassInCodebase( + dummyClassName, importCodebase, false); + URL exportCodebaseURL = TestLibrary.installClassInCodebase( + dummyClassName, exportCodebase, true); - /* - * Spawn an rmiregistry in the "import" codebase directory. - */ - File rmiregistryDir = - new File(System.getProperty("user.dir", "."), importCodebase); + /* + * Spawn an rmiregistry in the "import" codebase directory. + */ + File rmiregistryDir = + new File(System.getProperty("user.dir", "."), importCodebase); - String rmiregistryCommand = - System.getProperty("java.home") + File.separator + - "bin" + File.separator + "rmiregistry"; - - String cmdarray[] = new String[] { - rmiregistryCommand, - "-J-Denv.class.path=.", - "-J-Djava.rmi.server.codebase=" + exportCodebaseURL, - Integer.toString(TestLibrary.REGISTRY_PORT) }; + String rmiregistryCommand = + System.getProperty("java.home") + File.separator + + "bin" + File.separator + "rmiregistry"; - System.err.println("\nCommand used to spawn rmiregistry process:"); - System.err.println("\t" + Arrays.asList(cmdarray).toString()); + String cmdarray[] = new String[] { + rmiregistryCommand, + "-J-Denv.class.path=.", + "-J-Djava.rmi.server.codebase=" + exportCodebaseURL, + Integer.toString(TestLibrary.REGISTRY_PORT) }; - rmiregistry = Runtime.getRuntime().exec(cmdarray, null, rmiregistryDir); + System.err.println("\nCommand used to spawn rmiregistry process:"); + System.err.println("\t" + Arrays.asList(cmdarray).toString()); - // pipe rmiregistry output to our output, for debugging failures - StreamPipe.plugTogether(rmiregistry.getInputStream(), System.err); - StreamPipe.plugTogether(rmiregistry.getErrorStream(), System.err); + rmiregistry = Runtime.getRuntime().exec(cmdarray, null, rmiregistryDir); - /* - * Wait for the registry to initialize and be ready to call. - */ - Thread.sleep(REGISTRY_WAIT); - System.err.println(); + // pipe rmiregistry output to our output, for debugging failures + StreamPipe.plugTogether(rmiregistry.getInputStream(), System.err); + StreamPipe.plugTogether(rmiregistry.getErrorStream(), System.err); - /* - * Create an instance of the dummy class, finding it from the - * "import" codebase. - */ - ClassLoader loader = URLClassLoader.newInstance( - new URL[] { importCodebaseURL }); - Class dummyClass = Class.forName(dummyClassName, false, loader); - Remote dummyObject = (Remote) dummyClass.newInstance(); + /* + * Wait for the registry to initialize and be ready to call. + */ + Thread.sleep(REGISTRY_WAIT); + System.err.println(); - /* - * Find the registry that we created and bind the - * dummy object to it. - */ - Registry registry = LocateRegistry.getRegistry( - "localhost", TestLibrary.REGISTRY_PORT); + /* + * Create an instance of the dummy class, finding it from the + * "import" codebase. + */ + ClassLoader loader = URLClassLoader.newInstance( + new URL[] { importCodebaseURL }); + Class dummyClass = Class.forName(dummyClassName, false, loader); + Remote dummyObject = (Remote) dummyClass.newInstance(); - try { - registry.bind(dummyBinding, dummyObject); - System.err.println("Bound dummy object in registry"); - } catch (java.rmi.ConnectException e) { - System.err.println("Error: rmiregistry not started in time"); - throw e; - } catch (ServerException e) { - if (e.detail instanceof UnmarshalException && - ((UnmarshalException) e.detail).detail instanceof - ClassNotFoundException) - { - System.err.println( - "Error: another registry running on port " + - TestLibrary.REGISTRY_PORT + "?"); - } - throw e; - } + /* + * Find the registry that we created and bind the + * dummy object to it. + */ + Registry registry = LocateRegistry.getRegistry( + "localhost", TestLibrary.REGISTRY_PORT); - /* - * Look up the dummy object from our registry and make sure - * that its class was annotated with the "export" codebase. - */ - Remote dummyLookup = registry.lookup(dummyBinding); - System.err.println( - "Looked up dummy object from registry: " + dummyLookup); - Class dummyLookupClass = dummyLookup.getClass(); - String dummyLookupAnnotation = - RMIClassLoader.getClassAnnotation(dummyLookupClass); - System.err.println( - "Class annotation from registry: " + dummyLookupAnnotation); + try { + registry.bind(dummyBinding, dummyObject); + System.err.println("Bound dummy object in registry"); + } catch (java.rmi.ConnectException e) { + System.err.println("Error: rmiregistry not started in time"); + throw e; + } catch (ServerException e) { + if (e.detail instanceof UnmarshalException && + ((UnmarshalException) e.detail).detail instanceof + ClassNotFoundException) + { + System.err.println( + "Error: another registry running on port " + + TestLibrary.REGISTRY_PORT + "?"); + } + throw e; + } - System.err.println(); - if (dummyLookupAnnotation.indexOf(exportCodebase) >= 0) { - System.err.println("TEST PASSED"); - } else if (dummyLookupAnnotation.indexOf(importCodebase) >= 0) { - throw new RuntimeException( - "rmiregistry annotated with CLASSPATH element URL"); - } else { - throw new RuntimeException( - "rmiregistry used unexpected annotation: \"" + - dummyLookupAnnotation + "\""); - } + /* + * Look up the dummy object from our registry and make sure + * that its class was annotated with the "export" codebase. + */ + Remote dummyLookup = registry.lookup(dummyBinding); + System.err.println( + "Looked up dummy object from registry: " + dummyLookup); + Class dummyLookupClass = dummyLookup.getClass(); + String dummyLookupAnnotation = + RMIClassLoader.getClassAnnotation(dummyLookupClass); + System.err.println( + "Class annotation from registry: " + dummyLookupAnnotation); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("TEST FAILED: " + e.toString()); - } finally { - if (rmiregistry != null) { - rmiregistry.destroy(); - } - } + System.err.println(); + if (dummyLookupAnnotation.indexOf(exportCodebase) >= 0) { + System.err.println("TEST PASSED"); + } else if (dummyLookupAnnotation.indexOf(importCodebase) >= 0) { + throw new RuntimeException( + "rmiregistry annotated with CLASSPATH element URL"); + } else { + throw new RuntimeException( + "rmiregistry used unexpected annotation: \"" + + dummyLookupAnnotation + "\""); + } + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("TEST FAILED: " + e.toString()); + } finally { + if (rmiregistry != null) { + rmiregistry.destroy(); + } + } } } diff --git a/jdk/test/java/rmi/registry/classPathCodebase/Dummy.java b/jdk/test/java/rmi/registry/classPathCodebase/Dummy.java index 9b57cf18cf4..ad40244578a 100644 --- a/jdk/test/java/rmi/registry/classPathCodebase/Dummy.java +++ b/jdk/test/java/rmi/registry/classPathCodebase/Dummy.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,12 +36,12 @@ public class Dummy } public void writeExternal(java.io.ObjectOutput out) - throws java.io.IOException + throws java.io.IOException { } public void readExternal(java.io.ObjectInput in) - throws java.io.IOException, ClassNotFoundException + throws java.io.IOException, ClassNotFoundException { } } diff --git a/jdk/test/java/rmi/registry/emptyName/EmptyName.java b/jdk/test/java/rmi/registry/emptyName/EmptyName.java index fd6cf64a913..7507dc7fa63 100644 --- a/jdk/test/java/rmi/registry/emptyName/EmptyName.java +++ b/jdk/test/java/rmi/registry/emptyName/EmptyName.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,12 +32,12 @@ import java.rmi.server.RemoteObject; public class EmptyName { public static void main(String[] args) throws Exception { - Registry impl = LocateRegistry.createRegistry(0); - Registry stub = (Registry) RemoteObject.toStub(impl); - stub.bind("", stub); - stub.lookup(""); - stub.rebind("", stub); - stub.lookup(""); - stub.unbind(""); + Registry impl = LocateRegistry.createRegistry(0); + Registry stub = (Registry) RemoteObject.toStub(impl); + stub.bind("", stub); + stub.lookup(""); + stub.rebind("", stub); + stub.lookup(""); + stub.unbind(""); } } diff --git a/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java b/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java index 011022e753f..8ab80dd26f3 100644 --- a/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java +++ b/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -62,157 +62,157 @@ public class InterfaceHash { private static final String NAME = "WMM"; public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 4472769"); + System.err.println("\nRegression test for bug 4472769"); - System.err.println( - "\n=== verifying that J2SE registry's skeleton uses" + - "\ncorrect interface hash and operation numbers:"); + System.err.println( + "\n=== verifying that J2SE registry's skeleton uses" + + "\ncorrect interface hash and operation numbers:"); - Registry testImpl = LocateRegistry.createRegistry(PORT); - System.err.println("created test registry on port " + PORT); + Registry testImpl = LocateRegistry.createRegistry(PORT); + System.err.println("created test registry on port " + PORT); - RemoteRef ref = new UnicastRef( - new LiveRef(new ObjID(ObjID.REGISTRY_ID), - new TCPEndpoint("", PORT), false)); - Registry referenceStub = new ReferenceRegistryStub(ref); - System.err.println("created reference registry stub: " + - referenceStub); + RemoteRef ref = new UnicastRef( + new LiveRef(new ObjID(ObjID.REGISTRY_ID), + new TCPEndpoint("", PORT), false)); + Registry referenceStub = new ReferenceRegistryStub(ref); + System.err.println("created reference registry stub: " + + referenceStub); - referenceStub.bind(NAME, referenceStub); - System.err.println("bound name \"" + NAME + "\" in registry"); + referenceStub.bind(NAME, referenceStub); + System.err.println("bound name \"" + NAME + "\" in registry"); - String[] list = referenceStub.list(); - System.err.println("list of registry contents: " + - Arrays.asList(list)); - if (list.length != 1 || !list[0].equals(NAME)) { - throw new RuntimeException( - "TEST FAILED: unexpected list contents"); - } + String[] list = referenceStub.list(); + System.err.println("list of registry contents: " + + Arrays.asList(list)); + if (list.length != 1 || !list[0].equals(NAME)) { + throw new RuntimeException( + "TEST FAILED: unexpected list contents"); + } - Registry result = (Registry) referenceStub.lookup(NAME); - System.err.println("lookup of name \"" + NAME + "\" returned: " + - result); - if (!result.equals(referenceStub)) { - throw new RuntimeException( - "TEST FAILED: unexpected lookup result"); - } + Registry result = (Registry) referenceStub.lookup(NAME); + System.err.println("lookup of name \"" + NAME + "\" returned: " + + result); + if (!result.equals(referenceStub)) { + throw new RuntimeException( + "TEST FAILED: unexpected lookup result"); + } - referenceStub.rebind(NAME, referenceStub); - referenceStub.unbind(NAME); - System.err.println("unbound name \"" + NAME + "\""); + referenceStub.rebind(NAME, referenceStub); + referenceStub.unbind(NAME); + System.err.println("unbound name \"" + NAME + "\""); - list = referenceStub.list(); - System.err.println("list of registry contents: " + - Arrays.asList(list)); - if (list.length != 0) { - throw new RuntimeException("TEST FAILED: list not empty"); - } + list = referenceStub.list(); + System.err.println("list of registry contents: " + + Arrays.asList(list)); + if (list.length != 0) { + throw new RuntimeException("TEST FAILED: list not empty"); + } - System.err.println("\n=== verifying that J2SE registry's stub uses" + - "correct interface hash:"); + System.err.println("\n=== verifying that J2SE registry's stub uses" + + "correct interface hash:"); - class FakeRemoteRef implements RemoteRef { - long hash; - int opnum; - public RemoteCall newCall(RemoteObject obj, Operation[] op, - int opnum, long hash) - { - this.hash = hash; - this.opnum = opnum; - throw new UnsupportedOperationException(); - } - public void invoke(RemoteCall call) { } - public void done(RemoteCall call) { } - public Object invoke(Remote obj, Method method, - Object[] args, long hash) - { - throw new UnsupportedOperationException(); - } - public String getRefClass(java.io.ObjectOutput out) { - return "FakeRemoteRef"; - } - public int remoteHashCode() { return 1013; } - public boolean remoteEquals(RemoteRef obj) { return false; } - public String remoteToString() { return "FakeRemoteRef"; } - public void writeExternal(java.io.ObjectOutput out) { } - public void readExternal(java.io.ObjectInput in) { } - } - FakeRemoteRef f = new FakeRemoteRef(); + class FakeRemoteRef implements RemoteRef { + long hash; + int opnum; + public RemoteCall newCall(RemoteObject obj, Operation[] op, + int opnum, long hash) + { + this.hash = hash; + this.opnum = opnum; + throw new UnsupportedOperationException(); + } + public void invoke(RemoteCall call) { } + public void done(RemoteCall call) { } + public Object invoke(Remote obj, Method method, + Object[] args, long hash) + { + throw new UnsupportedOperationException(); + } + public String getRefClass(java.io.ObjectOutput out) { + return "FakeRemoteRef"; + } + public int remoteHashCode() { return 1013; } + public boolean remoteEquals(RemoteRef obj) { return false; } + public String remoteToString() { return "FakeRemoteRef"; } + public void writeExternal(java.io.ObjectOutput out) { } + public void readExternal(java.io.ObjectInput in) { } + } + FakeRemoteRef f = new FakeRemoteRef(); - Registry testRegistry = LocateRegistry.getRegistry(PORT); - System.err.println("created original test registry stub: " + - testRegistry); + Registry testRegistry = LocateRegistry.getRegistry(PORT); + System.err.println("created original test registry stub: " + + testRegistry); - Class stubClass = testRegistry.getClass(); - System.err.println("test registry stub class: " + stubClass); + Class stubClass = testRegistry.getClass(); + System.err.println("test registry stub class: " + stubClass); - Constructor cons = stubClass.getConstructor( - new Class[] { RemoteRef.class }); - Registry testStub = (Registry) cons.newInstance( - new Object[] { f }); - System.err.println("created new instrumented test registry stub: " + - testStub); + Constructor cons = stubClass.getConstructor( + new Class[] { RemoteRef.class }); + Registry testStub = (Registry) cons.newInstance( + new Object[] { f }); + System.err.println("created new instrumented test registry stub: " + + testStub); - System.err.println("invoking bind:"); - try { - testStub.bind(NAME, referenceStub); - } catch (UnsupportedOperationException e) { - } - System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); - if (f.hash != 4905912898345647071L) { - throw new RuntimeException("TEST FAILED: wrong interface hash"); - } else if (f.opnum != 0) { - throw new RuntimeException("TEST FAILED: wrong operation number"); - } + System.err.println("invoking bind:"); + try { + testStub.bind(NAME, referenceStub); + } catch (UnsupportedOperationException e) { + } + System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); + if (f.hash != 4905912898345647071L) { + throw new RuntimeException("TEST FAILED: wrong interface hash"); + } else if (f.opnum != 0) { + throw new RuntimeException("TEST FAILED: wrong operation number"); + } - System.err.println("invoking list:"); - try { - testStub.list(); - } catch (UnsupportedOperationException e) { - } - System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); - if (f.hash != 4905912898345647071L) { - throw new RuntimeException("TEST FAILED: wrong interface hash"); - } else if (f.opnum != 1) { - throw new RuntimeException("TEST FAILED: wrong operation number"); - } + System.err.println("invoking list:"); + try { + testStub.list(); + } catch (UnsupportedOperationException e) { + } + System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); + if (f.hash != 4905912898345647071L) { + throw new RuntimeException("TEST FAILED: wrong interface hash"); + } else if (f.opnum != 1) { + throw new RuntimeException("TEST FAILED: wrong operation number"); + } - System.err.println("invoking lookup:"); - try { - testStub.lookup(NAME); - } catch (UnsupportedOperationException e) { - } - System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); - if (f.hash != 4905912898345647071L) { - throw new RuntimeException("TEST FAILED: wrong interface hash"); - } else if (f.opnum != 2) { - throw new RuntimeException("TEST FAILED: wrong operation number"); - } + System.err.println("invoking lookup:"); + try { + testStub.lookup(NAME); + } catch (UnsupportedOperationException e) { + } + System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); + if (f.hash != 4905912898345647071L) { + throw new RuntimeException("TEST FAILED: wrong interface hash"); + } else if (f.opnum != 2) { + throw new RuntimeException("TEST FAILED: wrong operation number"); + } - System.err.println("invoking rebind:"); - try { - testStub.rebind(NAME, referenceStub); - } catch (UnsupportedOperationException e) { - } - System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); - if (f.hash != 4905912898345647071L) { - throw new RuntimeException("TEST FAILED: wrong interface hash"); - } else if (f.opnum != 3) { - throw new RuntimeException("TEST FAILED: wrong operation number"); - } + System.err.println("invoking rebind:"); + try { + testStub.rebind(NAME, referenceStub); + } catch (UnsupportedOperationException e) { + } + System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); + if (f.hash != 4905912898345647071L) { + throw new RuntimeException("TEST FAILED: wrong interface hash"); + } else if (f.opnum != 3) { + throw new RuntimeException("TEST FAILED: wrong operation number"); + } - System.err.println("invoking unbind:"); - try { - testStub.unbind(NAME); - } catch (UnsupportedOperationException e) { - } - System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); - if (f.hash != 4905912898345647071L) { - throw new RuntimeException("TEST FAILED: wrong interface hash"); - } else if (f.opnum != 4) { - throw new RuntimeException("TEST FAILED: wrong operation number"); - } + System.err.println("invoking unbind:"); + try { + testStub.unbind(NAME); + } catch (UnsupportedOperationException e) { + } + System.err.println("hash == " + f.hash + ", opnum == " + f.opnum); + if (f.hash != 4905912898345647071L) { + throw new RuntimeException("TEST FAILED: wrong interface hash"); + } else if (f.opnum != 4) { + throw new RuntimeException("TEST FAILED: wrong operation number"); + } - System.err.println("TEST PASSED"); + System.err.println("TEST PASSED"); } } diff --git a/jdk/test/java/rmi/registry/interfaceHash/ReferenceRegistryStub.java b/jdk/test/java/rmi/registry/interfaceHash/ReferenceRegistryStub.java index 2e4a1df143d..9db88da5939 100644 --- a/jdk/test/java/rmi/registry/interfaceHash/ReferenceRegistryStub.java +++ b/jdk/test/java/rmi/registry/interfaceHash/ReferenceRegistryStub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,161 +26,161 @@ public final class ReferenceRegistryStub implements java.rmi.registry.Registry, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote)"), - new java.rmi.server.Operation("java.lang.String list()[]"), - new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String)"), - new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote)"), - new java.rmi.server.Operation("void unbind(java.lang.String)") + new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote)"), + new java.rmi.server.Operation("java.lang.String list()[]"), + new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String)"), + new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote)"), + new java.rmi.server.Operation("void unbind(java.lang.String)") }; - + private static final long interfaceHash = 4905912898345647071L; - + // constructors public ReferenceRegistryStub() { - super(); + super(); } public ReferenceRegistryStub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of bind(String, Remote) public void bind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2) - throws java.rmi.AccessException, java.rmi.AlreadyBoundException, java.rmi.RemoteException + throws java.rmi.AccessException, java.rmi.AlreadyBoundException, java.rmi.RemoteException { - try { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_String_1); - out.writeObject($param_Remote_2); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - ref.done(call); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.rmi.AlreadyBoundException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_String_1); + out.writeObject($param_Remote_2); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + ref.done(call); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.rmi.AlreadyBoundException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of list() public java.lang.String[] list() - throws java.rmi.AccessException, java.rmi.RemoteException + throws java.rmi.AccessException, java.rmi.RemoteException { - try { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - ref.invoke(call); - java.lang.String[] $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.lang.String[]) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + ref.invoke(call); + java.lang.String[] $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.String[]) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of lookup(String) public java.rmi.Remote lookup(java.lang.String $param_String_1) - throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException + throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException { - try { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_String_1); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - java.rmi.Remote $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.rmi.Remote) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.rmi.NotBoundException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_String_1); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + java.rmi.Remote $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.rmi.Remote) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.rmi.NotBoundException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of rebind(String, Remote) public void rebind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2) - throws java.rmi.AccessException, java.rmi.RemoteException + throws java.rmi.AccessException, java.rmi.RemoteException { - try { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_String_1); - out.writeObject($param_Remote_2); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - ref.done(call); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_String_1); + out.writeObject($param_Remote_2); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + ref.done(call); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of unbind(String) public void unbind(java.lang.String $param_String_1) - throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException + throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException { - try { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 4, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_String_1); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - ref.done(call); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.rmi.NotBoundException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 4, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_String_1); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + ref.done(call); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.rmi.NotBoundException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java b/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java index bdfb87c87ed..8bca932dda3 100644 --- a/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java +++ b/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,49 +41,49 @@ public class MultipleRegistries implements RemoteInterface { private static final String NAME = "MultipleRegistries"; public Object passObject(Object obj) { - return obj; + return obj; } - + public static void main(String[] args) throws Exception { - - RemoteInterface server = null; - RemoteInterface proxy = null; - - try { - System.err.println("export object"); - server = new MultipleRegistries(); - proxy = - (RemoteInterface) UnicastRemoteObject.exportObject(server, 0); - System.err.println("proxy = " + proxy); + RemoteInterface server = null; + RemoteInterface proxy = null; - System.err.println("export registries"); - Registry registryImpl1 = LocateRegistry.createRegistry(2030); - Registry registryImpl2 = LocateRegistry.createRegistry(2040); + try { + System.err.println("export object"); + server = new MultipleRegistries(); + proxy = + (RemoteInterface) UnicastRemoteObject.exportObject(server, 0); - System.err.println("bind remote object in registries"); - Registry registry1 = LocateRegistry.getRegistry(2030); - Registry registry2 = LocateRegistry.getRegistry(2040); + System.err.println("proxy = " + proxy); - registry1.bind(NAME, proxy); - registry2.bind(NAME, proxy); + System.err.println("export registries"); + Registry registryImpl1 = LocateRegistry.createRegistry(2030); + Registry registryImpl2 = LocateRegistry.createRegistry(2040); - System.err.println("lookup remote object in registries"); + System.err.println("bind remote object in registries"); + Registry registry1 = LocateRegistry.getRegistry(2030); + Registry registry2 = LocateRegistry.getRegistry(2040); - RemoteInterface remote1 = (RemoteInterface) registry1.lookup(NAME); - RemoteInterface remote2 = (RemoteInterface) registry2.lookup(NAME); + registry1.bind(NAME, proxy); + registry2.bind(NAME, proxy); - System.err.println("invoke methods on remote objects"); - remote1.passObject(remote1); - remote2.passObject(remote2); + System.err.println("lookup remote object in registries"); - System.err.println("TEST PASSED"); - - } finally { - if (proxy != null) { - UnicastRemoteObject.unexportObject(server, true); - } - } + RemoteInterface remote1 = (RemoteInterface) registry1.lookup(NAME); + RemoteInterface remote2 = (RemoteInterface) registry2.lookup(NAME); + + System.err.println("invoke methods on remote objects"); + remote1.passObject(remote1); + remote2.passObject(remote2); + + System.err.println("TEST PASSED"); + + } finally { + if (proxy != null) { + UnicastRemoteObject.unexportObject(server, true); + } + } } } diff --git a/jdk/test/java/rmi/registry/reexport/Reexport.java b/jdk/test/java/rmi/registry/reexport/Reexport.java index 23f10e890a4..5c88736d4f0 100644 --- a/jdk/test/java/rmi/registry/reexport/Reexport.java +++ b/jdk/test/java/rmi/registry/reexport/Reexport.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,13 +25,13 @@ * @bug 4120329 * @summary RMI registry creation is impossible if first attempt fails. * @library ../../testlibrary - * @build StreamPipe TestParams TestLibrary JavaVM + * @build StreamPipe TestParams TestLibrary JavaVM * @build RegistryRunner RegistryRunner_Stub * @build Reexport * @run main/othervm Reexport */ -/* +/* * If a VM could not create an RMI registry because another registry * usually in another process, was using the registry port, the next * time the VM tried to create a registry (after the other registry @@ -40,7 +40,7 @@ * use when it should never have been allocated. * * The test creates this conflict using Runtime.exec and ensures that - * a registry can still be created after the conflict is resolved. + * a registry can still be created after the conflict is resolved. */ import java.io.*; @@ -50,106 +50,106 @@ import java.rmi.server.*; public class Reexport { static public final int regport = TestLibrary.REGISTRY_PORT; - + static public void main(String[] argv) { - Registry reg = null; + Registry reg = null; - try { - System.err.println("\nregression test for 4120329\n"); - - // establish the registry (we hope) - System.err.println("Starting registry on port " + regport); - Reexport.makeRegistry(regport); - - // Get a handle to the registry - System.err.println("Creating duplicate registry, this should fail..."); - reg = createReg(true); - - if (reg != null) { - TestLibrary.bomb("failed was able to duplicate the registry?!?"); - } - - // Kill the first registry. - System.err.println("Bringing down the first registry"); - try { - Reexport.killRegistry(); - } catch (Exception foo) { - } - - // start another registry now that the first is gone; this should work - System.err.println("Trying again to start our own " + - "registry... this should work"); - - reg = createReg(false); - - if (reg == null) { - TestLibrary.bomb("Could not create registry on second try"); - } - - System.err.println("Test passed"); - - } catch (Exception e) { - TestLibrary.bomb(e); - } finally { - // dont leave the registry around to affect other tests. - killRegistry(); + try { + System.err.println("\nregression test for 4120329\n"); - reg = null; - } + // establish the registry (we hope) + System.err.println("Starting registry on port " + regport); + Reexport.makeRegistry(regport); + + // Get a handle to the registry + System.err.println("Creating duplicate registry, this should fail..."); + reg = createReg(true); + + if (reg != null) { + TestLibrary.bomb("failed was able to duplicate the registry?!?"); + } + + // Kill the first registry. + System.err.println("Bringing down the first registry"); + try { + Reexport.killRegistry(); + } catch (Exception foo) { + } + + // start another registry now that the first is gone; this should work + System.err.println("Trying again to start our own " + + "registry... this should work"); + + reg = createReg(false); + + if (reg == null) { + TestLibrary.bomb("Could not create registry on second try"); + } + + System.err.println("Test passed"); + + } catch (Exception e) { + TestLibrary.bomb(e); + } finally { + // dont leave the registry around to affect other tests. + killRegistry(); + + reg = null; + } } - + static Registry createReg(boolean remoteOk) { - Registry reg = null; + Registry reg = null; - try { - reg = LocateRegistry.createRegistry(regport); - } catch (Throwable e) { - if (remoteOk) { - System.err.println("EXPECTING PORT IN USE EXCEPTION:"); - System.err.println(e.getMessage()); - e.printStackTrace(); - } else { - TestLibrary.bomb((Exception) e); - } - } + try { + reg = LocateRegistry.createRegistry(regport); + } catch (Throwable e) { + if (remoteOk) { + System.err.println("EXPECTING PORT IN USE EXCEPTION:"); + System.err.println(e.getMessage()); + e.printStackTrace(); + } else { + TestLibrary.bomb((Exception) e); + } + } - return reg; + return reg; } public static void makeRegistry(int p) { - // sadly, we can't kill a registry if we have too-close control - // over it. We must make it in a subprocess, and then kill the - // subprocess when it has served our needs. + // sadly, we can't kill a registry if we have too-close control + // over it. We must make it in a subprocess, and then kill the + // subprocess when it has served our needs. - try { - JavaVM jvm = new JavaVM("RegistryRunner", "", Integer.toString(p)); - jvm.start(); - Reexport.subreg = jvm.getVM(); + try { + JavaVM jvm = new JavaVM("RegistryRunner", "", Integer.toString(p)); + jvm.start(); + Reexport.subreg = jvm.getVM(); - } catch (IOException e) { - // one of these is summarily dropped, can't remember which one - System.out.println ("Test setup failed - cannot run rmiregistry"); - TestLibrary.bomb("Test setup failed - cannot run test", e); - } - // Slop - wait for registry to come up. This is stupid. - try { - Thread.sleep (5000); - } catch (Exception whatever) { - } + } catch (IOException e) { + // one of these is summarily dropped, can't remember which one + System.out.println ("Test setup failed - cannot run rmiregistry"); + TestLibrary.bomb("Test setup failed - cannot run test", e); + } + // Slop - wait for registry to come up. This is stupid. + try { + Thread.sleep (5000); + } catch (Exception whatever) { + } } private static Process subreg = null; - + public static void killRegistry() { - if (Reexport.subreg != null) { + if (Reexport.subreg != null) { - RegistryRunner.requestExit(); + RegistryRunner.requestExit(); - try { - Reexport.subreg.waitFor(); - } catch (InterruptedException ie) { - } - } - Reexport.subreg = null; - } + try { + Reexport.subreg.waitFor(); + } catch (InterruptedException ie) { + } + } + Reexport.subreg = null; + } } diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServer.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServer.java index 167a3515684..a57d614e94a 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServer.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServer.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,7 +33,7 @@ import java.rmi.RemoteException; /** * The RMI benchmark server is a simple compute-engine-like server which allows - * client benchmarks to create/export and unexport objects off of the server, + * client benchmarks to create/export and unexport objects off of the server, * or run arbitrary tasks. */ public interface BenchServer extends Remote { @@ -41,41 +41,40 @@ public interface BenchServer extends Remote { * Interface used for creating server-side remote objects. */ public interface RemoteObjectFactory extends Serializable { - Remote create() throws RemoteException; + Remote create() throws RemoteException; } - + /** * Interface used for server-side tasks. */ public interface Task extends Serializable { - Object execute() throws Exception; + Object execute() throws Exception; } /** - * Uses the given remote object factory to create a new remote object on + * Uses the given remote object factory to create a new remote object on * the server side. */ Remote create(RemoteObjectFactory factory) throws RemoteException; - + /** - * Unexports the specified remote object. Returns true if successful, + * Unexports the specified remote object. Returns true if successful, * false otherwise. */ boolean unexport(Remote obj, boolean force) throws RemoteException; - + /** * Execute given task. */ Object execute(Task task) throws Exception; - + /** * Invoke the garbage collector. */ void gc() throws RemoteException; - + /** * Terminate the server. */ void terminate(int delay) throws RemoteException; } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServerImpl.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServerImpl.java index 099e13d35ef..a0133f523d9 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServerImpl.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BenchServerImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -37,8 +37,8 @@ import java.util.HashMap; /** * Benchmark server implementation. */ -public class BenchServerImpl - extends UnicastRemoteObject implements BenchServer +public class BenchServerImpl + extends UnicastRemoteObject implements BenchServer { HashMap implTable = new HashMap(); @@ -47,52 +47,51 @@ public class BenchServerImpl */ public BenchServerImpl() throws RemoteException { } - + /** - * Uses the given remote object factory to create a new remote object on + * Uses the given remote object factory to create a new remote object on * the server side. */ - public Remote create(BenchServer.RemoteObjectFactory factory) - throws RemoteException + public Remote create(BenchServer.RemoteObjectFactory factory) + throws RemoteException { - Remote impl = factory.create(); - implTable.put(RemoteObject.toStub(impl), new WeakReference(impl)); - return impl; + Remote impl = factory.create(); + implTable.put(RemoteObject.toStub(impl), new WeakReference(impl)); + return impl; } - + /** - * Unexports the specified remote object. Returns true if successful, + * Unexports the specified remote object. Returns true if successful, * false otherwise. */ public boolean unexport(Remote obj, boolean force) throws RemoteException { - WeakReference iref = (WeakReference) implTable.get(obj); - if (iref == null) - return false; - Remote impl = (Remote) iref.get(); - if (impl == null) - return false; - return UnicastRemoteObject.unexportObject(impl, force); + WeakReference iref = (WeakReference) implTable.get(obj); + if (iref == null) + return false; + Remote impl = (Remote) iref.get(); + if (impl == null) + return false; + return UnicastRemoteObject.unexportObject(impl, force); } - + /** * Execute given task. */ public Object execute(BenchServer.Task task) throws Exception { - return task.execute(); + return task.execute(); } - + /** * Invoke the garbage collector. */ public void gc() throws RemoteException { - System.gc(); + System.gc(); } - + /** * Terminate the server. */ public void terminate(int delay) throws RemoteException { - System.exit(0); + System.exit(0); } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanArrayCalls.java index cf444f6a57c..a9005d980e0 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class BooleanArrayCalls implements Benchmark { interface Server extends Remote { - public boolean[] call(boolean[] a) throws RemoteException; + public boolean[] call(boolean[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public boolean[] call(boolean[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public boolean[] call(boolean[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue boolean array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - boolean[] array = new boolean[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + boolean[] array = new boolean[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanCalls.java index 20eef614505..52d2810b79e 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/BooleanCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class BooleanCalls implements Benchmark { interface Server extends Remote { - public boolean call(boolean val) throws RemoteException; + public boolean call(boolean val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public boolean call(boolean val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public boolean call(boolean val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue boolean calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call(true); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call(true); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteArrayCalls.java index 26d2dc342c1..d0401315c48 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class ByteArrayCalls implements Benchmark { interface Server extends Remote { - public byte[] call(byte[] a) throws RemoteException; + public byte[] call(byte[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public byte[] call(byte[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public byte[] call(byte[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue byte array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - byte[] array = new byte[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + byte[] array = new byte[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteCalls.java index e8ef1186792..8368c2ea0ee 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ByteCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class ByteCalls implements Benchmark { interface Server extends Remote { - public byte call(byte val) throws RemoteException; + public byte call(byte val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public byte call(byte val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public byte call(byte val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue byte calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call((byte) 0); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call((byte) 0); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharArrayCalls.java index 15c3e3b897e..65903070436 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class CharArrayCalls implements Benchmark { interface Server extends Remote { - public char[] call(char[] a) throws RemoteException; + public char[] call(char[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public char[] call(char[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public char[] call(char[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue char array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - char[] array = new char[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + char[] array = new char[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharCalls.java index eaea4164d85..eeeb836be4a 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/CharCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class CharCalls implements Benchmark { interface Server extends Remote { - public char call(char val) throws RemoteException; + public char call(char val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public char call(char val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public char call(char val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue char calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call('0'); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call('0'); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ClassLoading.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ClassLoading.java index 303fe00502d..e6451c36ef3 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ClassLoading.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ClassLoading.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -45,16 +45,15 @@ public class ClassLoading implements Benchmark { * Arguments: <# reps> */ public long run(String[] args) throws Exception { - int reps = Integer.parseInt(args[0]); - CodeSource csrc = getClass().getProtectionDomain().getCodeSource(); - String url = "jar:" + csrc.getLocation().toString() + ALTROOT; - - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - RMIClassLoader.loadClass(url, CLASSNAME); - long time = System.currentTimeMillis() - start; - - return time; + int reps = Integer.parseInt(args[0]); + CodeSource csrc = getClass().getProtectionDomain().getCodeSource(); + String url = "jar:" + csrc.getLocation().toString() + ALTROOT; + + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + RMIClassLoader.loadClass(url, CLASSNAME); + long time = System.currentTimeMillis() - start; + + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleArrayCalls.java index 6aef1593858..44f12010e94 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class DoubleArrayCalls implements Benchmark { interface Server extends Remote { - public double[] call(double[] a) throws RemoteException; + public double[] call(double[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public double[] call(double[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public double[] call(double[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue double array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - double[] array = new double[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + double[] array = new double[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleCalls.java index 4bde6166ae4..c847391f666 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/DoubleCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class DoubleCalls implements Benchmark { interface Server extends Remote { - public double call(double val) throws RemoteException; + public double call(double val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public double call(double val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public double call(double val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue double calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call(0.0); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call(0.0); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExceptionCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExceptionCalls.java index 7664fe647bc..f7f521ae357 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExceptionCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExceptionCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,43 +41,42 @@ public class ExceptionCalls implements Benchmark { } interface Server extends Remote { - public void call() throws RemoteException, FooException; + public void call() throws RemoteException, FooException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public void call() throws RemoteException, FooException { - throw new FooException(); - } + public ServerImpl() throws RemoteException { + } + + public void call() throws RemoteException, FooException { + throw new FooException(); + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue calls which throw exceptions. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int reps = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int reps = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) { - try { - stub.call(); - } catch (FooException e) {} - } - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) { + try { + stub.call(); + } catch (FooException e) {} + } + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExportObjs.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExportObjs.java index a3e8c8b03a5..72071177abf 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExportObjs.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ExportObjs.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.rmi.server.UnicastRemoteObject; * Benchmark for testing speed of UnicastRemoteObject.exportObject(). */ public class ExportObjs implements Benchmark { - + static class RemoteObj implements Remote { } @@ -44,19 +44,18 @@ public class ExportObjs implements Benchmark { * Arguments: <# objects> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - Remote[] objs = new Remote[size]; - for (int i = 0; i < size; i++) - objs[i] = new RemoteObj(); - - long start = System.currentTimeMillis(); - for (int i = 0; i < size; i++) - UnicastRemoteObject.exportObject(objs[i],0); - long time = System.currentTimeMillis() - start; - - for (int i = 0; i < size; i++) - UnicastRemoteObject.unexportObject(objs[i], true); - return time; + int size = Integer.parseInt(args[0]); + Remote[] objs = new Remote[size]; + for (int i = 0; i < size; i++) + objs[i] = new RemoteObj(); + + long start = System.currentTimeMillis(); + for (int i = 0; i < size; i++) + UnicastRemoteObject.exportObject(objs[i],0); + long time = System.currentTimeMillis() - start; + + for (int i = 0; i < size; i++) + UnicastRemoteObject.unexportObject(objs[i], true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatArrayCalls.java index 5905b11e9d4..d044f06ebbe 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class FloatArrayCalls implements Benchmark { interface Server extends Remote { - public float[] call(float[] a) throws RemoteException; + public float[] call(float[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public float[] call(float[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public float[] call(float[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue float array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - float[] array = new float[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + float[] array = new float[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatCalls.java index 5ff7bcebff7..564a81c1c6b 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/FloatCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class FloatCalls implements Benchmark { interface Server extends Remote { - public float call(float val) throws RemoteException; + public float call(float val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public float call(float val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public float call(float val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue float calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call((float) 0.0); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call((float) 0.0); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntArrayCalls.java index ebd2668e095..f8897639ea9 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class IntArrayCalls implements Benchmark { interface Server extends Remote { - public int[] call(int[] a) throws RemoteException; + public int[] call(int[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public int[] call(int[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public int[] call(int[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue int array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - int[] array = new int[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + int[] array = new int[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntCalls.java index fb85488083f..e1777c3ac24 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/IntCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class IntCalls implements Benchmark { interface Server extends Remote { - public int call(int val) throws RemoteException; + public int call(int val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public int call(int val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public int call(int val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue int calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call(0); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call(0); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongArrayCalls.java index 1f86e5b4a1e..15cbeb799f5 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class LongArrayCalls implements Benchmark { interface Server extends Remote { - public long[] call(long[] a) throws RemoteException; + public long[] call(long[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public long[] call(long[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public long[] call(long[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue long array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - long[] array = new long[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + long[] array = new long[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongCalls.java index 864349c9f68..109ec952609 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/LongCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class LongCalls implements Benchmark { interface Server extends Remote { - public long call(long val) throws RemoteException; + public long call(long val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public long call(long val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public long call(long val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue long calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call(0L); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call(0L); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/Main.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/Main.java index de81a09f2b5..3e06a8887d3 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/Main.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/Main.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -47,35 +47,35 @@ import java.rmi.server.RemoteObject; import java.util.Timer; import java.util.TimerTask; -/* +/* * RMI/Serialization benchmark tests. */ public class Main { - + /** * RMI-specific benchmark harness. */ static class RMIHarness extends Harness { - /** - * Construct new RMI benchmark harness. - */ - RMIHarness(InputStream in) throws IOException, ConfigFormatException { - super(in); - } - - /** - * Cleanup both client and server side in between each benchmark. - */ - protected void cleanup() { - System.gc(); - if (Main.runmode == CLIENT) { - try { - Main.server.gc(); - } catch (Exception e) { - System.err.println("Warning: server gc failed: " + e); - } - } - } + /** + * Construct new RMI benchmark harness. + */ + RMIHarness(InputStream in) throws IOException, ConfigFormatException { + super(in); + } + + /** + * Cleanup both client and server side in between each benchmark. + */ + protected void cleanup() { + System.gc(); + if (Main.runmode == CLIENT) { + try { + Main.server.gc(); + } catch (Exception e) { + System.err.println("Warning: server gc failed: " + e); + } + } + } } static final String CONFFILE = "/bench/rmi/config"; @@ -85,7 +85,7 @@ public class Main { static final int SAMEVM = 0; static final int CLIENT = 1; static final int SERVER = 2; - + static final int TEXT = 0; static final int HTML = 1; static final int XML = 2; @@ -111,7 +111,7 @@ public class Main { * Returns reference to benchmark server. */ public static BenchServer getBenchServer() { - return server; + return server; } /** @@ -127,252 +127,252 @@ public class Main { p.println(" -t repeat benchmarks for specified number of hours"); p.println(" -o specify output file"); p.println(" -c specify (non-default) " + - "configuration file"); + "configuration file"); p.println(" -html format output as html " + - "(default is text)"); + "(default is text)"); p.println(" -xml format output as xml"); - p.println(" -client run benchmark client using server " + - "on specified host/port"); - p.println(" -server run benchmark server on given port"); + p.println(" -client run benchmark client using server " + + "on specified host/port"); + p.println(" -server run benchmark server on given port"); } - + /** * Print error message and exit. */ static void die(String mesg) { - System.err.println(mesg); - System.exit(1); + System.err.println(mesg); + System.exit(1); } /** * Stop server and exit. */ public static void exit() { - switch (runmode) { - case CLIENT: - if (server != null) { - try { - server.terminate(0); - } catch (RemoteException re) { - // ignore - } - } - default: - System.exit(0); - } + switch (runmode) { + case CLIENT: + if (server != null) { + try { + server.terminate(0); + } catch (RemoteException re) { + // ignore + } + } + default: + System.exit(0); + } } /** * Benchmark mainline. */ public static void main(String[] args) { - setupSecurity(); - parseArgs(args); - setupStreams(); - if (list) { - listConfig(); - } else { - setupServer(); - if (runmode != SERVER) { - setupHarness(); - setupReporter(); - if (exitOnTimer) { - setupTimer(testDurationSeconds); - while (true) { - runBenchmarks(); - if (exitRequested) { - exit(); - } - } - } else { - runBenchmarks(); - exit(); - } - } - } + setupSecurity(); + parseArgs(args); + setupStreams(); + if (list) { + listConfig(); + } else { + setupServer(); + if (runmode != SERVER) { + setupHarness(); + setupReporter(); + if (exitOnTimer) { + setupTimer(testDurationSeconds); + while (true) { + runBenchmarks(); + if (exitRequested) { + exit(); + } + } + } else { + runBenchmarks(); + exit(); + } + } + } } - + /** * Parse command-line arguments. */ static void parseArgs(String[] args) { - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-h")) { - usage(); - System.exit(0); - } else if (args[i].equals("-v")) { - verbose = true; - } else if (args[i].equals("-l")) { - list = true; - } else if (args[i].equals("-t")) { - if (++i >= args.length) - die("Error: no timeout value specified"); - try { - exitOnTimer = true; - testDurationSeconds = Integer.parseInt(args[i]) * 3600; - } catch (Exception e) { - die("Error: unable to determine timeout value"); - } - } else if (args[i].equals("-o")) { - if (++i >= args.length) - die("Error: no output file specified"); - try { - repstr = new FileOutputStream(args[i]); - } catch (IOException e) { - die("Error: unable to open \"" + args[i] + "\""); - } - } else if (args[i].equals("-c")) { - if (++i >= args.length) - die("Error: no config file specified"); - try { - confstr = new FileInputStream(args[i]); - } catch (IOException e) { - die("Error: unable to open \"" + args[i] + "\""); - } - } else if (args[i].equals("-html")) { - if (format != TEXT) - die("Error: conflicting formats"); - format = HTML; - } else if (args[i].equals("-xml")) { - if (format != TEXT) - die("Error: conflicting formats"); - format = XML; - } else if (args[i].equals("-client")) { - if (runmode == CLIENT) - die("Error: multiple -client options"); - if (runmode == SERVER) - die("Error: -client and -server options conflict"); - if (++i >= args.length) - die("Error: -client missing host/port"); - try { - int sepi = args[i].indexOf(':'); - host = args[i].substring(0, sepi); - port = Integer.parseInt(args[i].substring(sepi + 1)); - } catch (Exception e) { - die("Error: illegal host/port specified for -client"); - } - runmode = CLIENT; - } else if (args[i].equals("-server")) { - if (runmode == CLIENT) - die("Error: -client and -server options conflict"); - if (runmode == SERVER) - die("Error: multiple -server options"); - if (++i >= args.length) - die("Error: -server missing port"); - try { - port = Integer.parseInt(args[i]); - } catch (Exception e) { - die("Error: illegal port specified for -server"); - } - runmode = SERVER; - } else { - System.err.println("Illegal option: \"" + args[i] + "\""); - usage(); - System.exit(1); - } - } + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-h")) { + usage(); + System.exit(0); + } else if (args[i].equals("-v")) { + verbose = true; + } else if (args[i].equals("-l")) { + list = true; + } else if (args[i].equals("-t")) { + if (++i >= args.length) + die("Error: no timeout value specified"); + try { + exitOnTimer = true; + testDurationSeconds = Integer.parseInt(args[i]) * 3600; + } catch (Exception e) { + die("Error: unable to determine timeout value"); + } + } else if (args[i].equals("-o")) { + if (++i >= args.length) + die("Error: no output file specified"); + try { + repstr = new FileOutputStream(args[i]); + } catch (IOException e) { + die("Error: unable to open \"" + args[i] + "\""); + } + } else if (args[i].equals("-c")) { + if (++i >= args.length) + die("Error: no config file specified"); + try { + confstr = new FileInputStream(args[i]); + } catch (IOException e) { + die("Error: unable to open \"" + args[i] + "\""); + } + } else if (args[i].equals("-html")) { + if (format != TEXT) + die("Error: conflicting formats"); + format = HTML; + } else if (args[i].equals("-xml")) { + if (format != TEXT) + die("Error: conflicting formats"); + format = XML; + } else if (args[i].equals("-client")) { + if (runmode == CLIENT) + die("Error: multiple -client options"); + if (runmode == SERVER) + die("Error: -client and -server options conflict"); + if (++i >= args.length) + die("Error: -client missing host/port"); + try { + int sepi = args[i].indexOf(':'); + host = args[i].substring(0, sepi); + port = Integer.parseInt(args[i].substring(sepi + 1)); + } catch (Exception e) { + die("Error: illegal host/port specified for -client"); + } + runmode = CLIENT; + } else if (args[i].equals("-server")) { + if (runmode == CLIENT) + die("Error: -client and -server options conflict"); + if (runmode == SERVER) + die("Error: multiple -server options"); + if (++i >= args.length) + die("Error: -server missing port"); + try { + port = Integer.parseInt(args[i]); + } catch (Exception e) { + die("Error: illegal port specified for -server"); + } + runmode = SERVER; + } else { + System.err.println("Illegal option: \"" + args[i] + "\""); + usage(); + System.exit(1); + } + } } - + /** * Set up security manager and policy, if not set already. */ static void setupSecurity() { - if (System.getSecurityManager() != null) - return; - - /* As of 1.4, it is too late to set the security policy - * file at this point so these line have been commented out. - */ - //System.setProperty("java.security.policy", - // Main.class.getResource("/bench/rmi/policy.all").toString()); - System.setSecurityManager(new RMISecurityManager()); + if (System.getSecurityManager() != null) + return; + + /* As of 1.4, it is too late to set the security policy + * file at this point so these line have been commented out. + */ + //System.setProperty("java.security.policy", + // Main.class.getResource("/bench/rmi/policy.all").toString()); + System.setSecurityManager(new RMISecurityManager()); } /** * Set up configuration file and report streams, if not set already. */ static void setupStreams() { - if (repstr == null) - repstr = System.out; - if (confstr == null) - confstr = (new Main()).getClass().getResourceAsStream(CONFFILE); - if (confstr == null) - die("Error: unable to find default config file"); + if (repstr == null) + repstr = System.out; + if (confstr == null) + confstr = (new Main()).getClass().getResourceAsStream(CONFFILE); + if (confstr == null) + die("Error: unable to find default config file"); } - + /** * Print contents of configuration file to selected output stream. */ static void listConfig() { - try { - byte[] buf = new byte[256]; - int len; - while ((len = confstr.read(buf)) != -1) - repstr.write(buf, 0, len); - } catch (IOException e) { - die("Error: failed to list config file"); - } + try { + byte[] buf = new byte[256]; + int len; + while ((len = confstr.read(buf)) != -1) + repstr.write(buf, 0, len); + } catch (IOException e) { + die("Error: failed to list config file"); + } } - + /** * Setup benchmark server. */ static void setupServer() { - switch (runmode) { - case SAMEVM: - try { - serverImpl = new BenchServerImpl(); - server = (BenchServer) RemoteObject.toStub(serverImpl); - } catch (Exception e) { - die("Error: failed to create local server: " + e); - } - if (verbose) - System.out.println("Benchmark server created locally"); - break; - - case CLIENT: - try { - Registry reg = LocateRegistry.getRegistry(host, port); - server = (BenchServer) reg.lookup(REGNAME); - } catch (Exception e) { - die("Error: failed to connect to server: " + e); - } - if (server == null) { - die("Error: server not found"); - } - if (verbose) { - System.out.println("Connected to benchmark server on " + - host + ":" + port); - } - break; - - case SERVER: - try { - Registry reg = LocateRegistry.createRegistry(port); - serverImpl = new BenchServerImpl(); - reg.bind(REGNAME, serverImpl); - } catch (Exception e) { - die("Error: failed to initialize server: " + e); - } - if (verbose) { - System.out.println("Benchmark server started on port " + - port); - } - break; - - default: - throw new InternalError("illegal runmode"); - } + switch (runmode) { + case SAMEVM: + try { + serverImpl = new BenchServerImpl(); + server = (BenchServer) RemoteObject.toStub(serverImpl); + } catch (Exception e) { + die("Error: failed to create local server: " + e); + } + if (verbose) + System.out.println("Benchmark server created locally"); + break; + + case CLIENT: + try { + Registry reg = LocateRegistry.getRegistry(host, port); + server = (BenchServer) reg.lookup(REGNAME); + } catch (Exception e) { + die("Error: failed to connect to server: " + e); + } + if (server == null) { + die("Error: server not found"); + } + if (verbose) { + System.out.println("Connected to benchmark server on " + + host + ":" + port); + } + break; + + case SERVER: + try { + Registry reg = LocateRegistry.createRegistry(port); + serverImpl = new BenchServerImpl(); + reg.bind(REGNAME, serverImpl); + } catch (Exception e) { + die("Error: failed to initialize server: " + e); + } + if (verbose) { + System.out.println("Benchmark server started on port " + + port); + } + break; + + default: + throw new InternalError("illegal runmode"); + } } /** * Set up the timer to end the test. * - * @param delay the amount of delay, in seconds, before requesting + * @param delay the amount of delay, in seconds, before requesting * the process exit */ static void setupTimer(int delay) { - timer = new Timer(true); + timer = new Timer(true); timer.schedule( new TimerTask() { public void run() { @@ -391,12 +391,12 @@ public class Main { } catch (ConfigFormatException e) { String errmsg = e.getMessage(); if (errmsg != null) { - die("Error parsing config file: " + errmsg); - } else { + die("Error parsing config file: " + errmsg); + } else { die("Error: illegal config file syntax"); - } + } } catch (IOException e) { - die("Error: failed to read config file"); + die("Error: failed to read config file"); } } @@ -405,24 +405,24 @@ public class Main { */ static void setupReporter() { String title = "RMI Benchmark, v" + VERSION; - switch (format) { - case TEXT: - reporter = new TextReporter(repstr, title); - break; - - case HTML: - reporter = new HtmlReporter(repstr, title); - break; + switch (format) { + case TEXT: + reporter = new TextReporter(repstr, title); + break; - case XML: - reporter = new XmlReporter(repstr, title); - break; - - default: - die("Error: unrecognized format type"); - } + case HTML: + reporter = new HtmlReporter(repstr, title); + break; + + case XML: + reporter = new XmlReporter(repstr, title); + break; + + default: + die("Error: unrecognized format type"); + } } - + /** * Run benchmarks. */ @@ -430,4 +430,3 @@ public class Main { harness.runBenchmarks(reporter, verbose); } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/NullCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/NullCalls.java index 7cd6a1c4313..0616f2e97f3 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/NullCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/NullCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,39 +38,38 @@ import java.rmi.server.UnicastRemoteObject; public class NullCalls implements Benchmark { interface Server extends Remote { - public void call() throws RemoteException; + public void call() throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public void call() throws RemoteException { - } + public ServerImpl() throws RemoteException { + } + + public void call() throws RemoteException { + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue null calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int reps = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int reps = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjArrayCalls.java index a3835daad25..3fa66cdbc1c 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,16 +41,16 @@ public class ObjArrayCalls implements Benchmark { static class Node implements Serializable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -61,44 +61,43 @@ public class ObjArrayCalls implements Benchmark { } interface Server extends Remote { - public Node[] call(Node[] a) throws RemoteException; + public Node[] call(Node[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } + public ServerImpl() throws RemoteException { + } - public Node[] call(Node[] a) throws RemoteException { - return a; - } + public Node[] call(Node[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue calls using arrays of objects as parameters/return values. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - Node[] nodes = new Node[size]; - for (int i = 0; i < size; i++) - nodes[i] = new Node(null, 0); + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + Node[] nodes = new Node[size]; + for (int i = 0; i < size; i++) + nodes[i] = new Node(null, 0); - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(nodes); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(nodes); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjTreeCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjTreeCalls.java index bcf9fad7f2e..02a9f066f80 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjTreeCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ObjTreeCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,16 +41,16 @@ public class ObjTreeCalls implements Benchmark { static class Node implements Serializable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -61,42 +61,41 @@ public class ObjTreeCalls implements Benchmark { } interface Server extends Remote { - public Node call(Node val) throws RemoteException; + public Node call(Node val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } + public ServerImpl() throws RemoteException { + } - public Node call(Node val) throws RemoteException { - return val; - } + public Node call(Node val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue calls using trees of objects as parameters/return values. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - Node node = new Node(null, depth); + int depth = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + Node node = new Node(null, depth); - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(node); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(node); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ProxyArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ProxyArrayCalls.java index 0ab713af6ea..7242a4f31a8 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ProxyArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ProxyArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -44,52 +44,52 @@ import java.rmi.server.UnicastRemoteObject; public class ProxyArrayCalls implements Benchmark { static class DummyHandler implements InvocationHandler, Serializable { - public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable - { - return null; - } + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + return null; + } } - + public static interface DummyInterface { - public void foo(); + public void foo(); } interface Server extends Remote { - public Proxy[] call(Proxy[] a) throws RemoteException; + public Proxy[] call(Proxy[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } + public ServerImpl() throws RemoteException { + } - public Proxy[] call(Proxy[] a) throws RemoteException { - return a; - } + public Proxy[] call(Proxy[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Generate proxy object array of the given size. */ Proxy[] genProxies(int size) throws Exception { - Class proxyClass = - Proxy.getProxyClass(DummyInterface.class.getClassLoader(), - new Class[] { DummyInterface.class }); - Constructor proxyCons = - proxyClass.getConstructor(new Class[] { InvocationHandler.class }); - Object[] consArgs = new Object[] { new DummyHandler() }; - Proxy[] proxies = new Proxy[size]; + Class proxyClass = + Proxy.getProxyClass(DummyInterface.class.getClassLoader(), + new Class[] { DummyInterface.class }); + Constructor proxyCons = + proxyClass.getConstructor(new Class[] { InvocationHandler.class }); + Object[] consArgs = new Object[] { new DummyHandler() }; + Proxy[] proxies = new Proxy[size]; - for (int i = 0; i < size; i++) - proxies[i] = (Proxy) proxyCons.newInstance(consArgs); + for (int i = 0; i < size; i++) + proxies[i] = (Proxy) proxyCons.newInstance(consArgs); - return proxies; + return proxies; } /** @@ -97,19 +97,18 @@ public class ProxyArrayCalls implements Benchmark { * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - Proxy[] proxies = genProxies(size); + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + Proxy[] proxies = genProxies(size); - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(proxies); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(proxies); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/RemoteObjArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/RemoteObjArrayCalls.java index d8a6ec8905d..5bf6a3b929a 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/RemoteObjArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/RemoteObjArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,49 +39,48 @@ import java.rmi.server.UnicastRemoteObject; public class RemoteObjArrayCalls implements Benchmark { static class RemoteObj extends UnicastRemoteObject implements Remote { - RemoteObj() throws RemoteException { - } + RemoteObj() throws RemoteException { + } } interface Server extends Remote { - public Remote[] call(Remote[] a) throws RemoteException; + public Remote[] call(Remote[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } + public ServerImpl() throws RemoteException { + } - public Remote[] call(Remote[] a) throws RemoteException { - return a; - } + public Remote[] call(Remote[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue calls using arrays of remote objects as parameters/return values. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - Remote[] objs = new Remote[size]; - for (int i = 0; i < size; i++) - objs[i] = new RemoteObj(); + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + Remote[] objs = new Remote[size]; + for (int i = 0; i < size; i++) + objs[i] = new RemoteObj(); - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(objs); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(objs); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortArrayCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortArrayCalls.java index 76432712caa..91589b8d401 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortArrayCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortArrayCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -20,7 +20,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ - + /* * */ @@ -39,42 +39,41 @@ import java.rmi.server.UnicastRemoteObject; public class ShortArrayCalls implements Benchmark { interface Server extends Remote { - public short[] call(short[] a) throws RemoteException; + public short[] call(short[] a) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public short[] call(short[] a) throws RemoteException { - return a; - } + public ServerImpl() throws RemoteException { + } + + public short[] call(short[] a) throws RemoteException { + return a; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue short array calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - short[] array = new short[size]; + int size = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + short[] array = new short[size]; - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(array); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(array); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortCalls.java index 867ebef8530..2ba8e0f3acc 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/ShortCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,40 +38,39 @@ import java.rmi.server.UnicastRemoteObject; public class ShortCalls implements Benchmark { interface Server extends Remote { - public short call(short val) throws RemoteException; + public short call(short val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } - - public short call(short val) throws RemoteException { - return val; - } + public ServerImpl() throws RemoteException { + } + + public short call(short val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue short calls. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int cycles = Integer.parseInt(args[0]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); + int cycles = Integer.parseInt(args[0]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); - long start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) - stub.call((short) 0); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < cycles; i++) + stub.call((short) 0); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/SmallObjTreeCalls.java b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/SmallObjTreeCalls.java index 29829d6ec91..a43defb5234 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/rmi/SmallObjTreeCalls.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/rmi/SmallObjTreeCalls.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,7 +41,7 @@ public class SmallObjTreeCalls implements Benchmark { static class Node implements Serializable { Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -52,42 +52,41 @@ public class SmallObjTreeCalls implements Benchmark { } interface Server extends Remote { - public Node call(Node val) throws RemoteException; + public Node call(Node val) throws RemoteException; } static class ServerImpl extends UnicastRemoteObject implements Server { - public ServerImpl() throws RemoteException { - } + public ServerImpl() throws RemoteException { + } - public Node call(Node val) throws RemoteException { - return val; - } + public Node call(Node val) throws RemoteException { + return val; + } } - + static class ServerFactory implements BenchServer.RemoteObjectFactory { - public Remote create() throws RemoteException { - return new ServerImpl(); - } + public Remote create() throws RemoteException { + return new ServerImpl(); + } } - + /** * Issue calls using trees of small objects as parameters/return values. * Arguments: <# calls> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int reps = Integer.parseInt(args[1]); - BenchServer bsrv = Main.getBenchServer(); - Server stub = (Server) bsrv.create(new ServerFactory()); - Node node = new Node(null, depth); + int depth = Integer.parseInt(args[0]); + int reps = Integer.parseInt(args[1]); + BenchServer bsrv = Main.getBenchServer(); + Server stub = (Server) bsrv.create(new ServerFactory()); + Node node = new Node(null, depth); - long start = System.currentTimeMillis(); - for (int i = 0; i < reps; i++) - stub.call(node); - long time = System.currentTimeMillis() - start; - - bsrv.unexport(stub, true); - return time; + long start = System.currentTimeMillis(); + for (int i = 0; i < reps; i++) + stub.call(node); + long time = System.currentTimeMillis() - start; + + bsrv.unexport(stub, true); + return time; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/BooleanArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/BooleanArrays.java index d52fdcf2052..5e6ff7656aa 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/BooleanArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/BooleanArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of boolean array reads/writes. */ public class BooleanArrays implements Benchmark { - + /** * Write and read boolean arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class BooleanArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - boolean[][] arrays = new boolean[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + boolean[][] arrays = new boolean[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, boolean[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, boolean[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Booleans.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Booleans.java index 690d4ac190d..abf8ef8c5e8 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Booleans.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Booleans.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of boolean reads/writes. */ public class Booleans implements Benchmark { - + /** * Write and read boolean values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,40 +44,38 @@ public class Booleans implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeBoolean(false); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readBoolean(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeBoolean(false); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readBoolean(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ByteArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ByteArrays.java index 5c21de5b14a..b300e8af79b 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ByteArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ByteArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of byte array reads/writes. */ public class ByteArrays implements Benchmark { - + /** * Write and read byte arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class ByteArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - byte[][] arrays = new byte[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + byte[][] arrays = new byte[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, byte[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, byte[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Bytes.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Bytes.java index 585f6b18208..31d6465c30c 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Bytes.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Bytes.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of byte reads/writes. */ public class Bytes implements Benchmark { - + /** * Write and read byte values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,39 +44,38 @@ public class Bytes implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeByte(0); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readByte(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeByte(0); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readByte(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/CharArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/CharArrays.java index e1cec28e566..a9b1353b06f 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/CharArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/CharArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of char array reads/writes. */ public class CharArrays implements Benchmark { - + /** * Write and read char arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class CharArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - char[][] arrays = new char[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + char[][] arrays = new char[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, char[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, char[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Chars.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Chars.java index 835bb6dc010..1ee2c88ed6e 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Chars.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Chars.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of char reads/writes. */ public class Chars implements Benchmark { - + /** * Write and read char values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,39 +44,38 @@ public class Chars implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeChar('0'); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readChar(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeChar('0'); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readChar(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ClassDesc.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ClassDesc.java index 47895b560c6..a7ad155ceb0 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ClassDesc.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ClassDesc.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -89,41 +89,40 @@ public class ClassDesc implements Benchmark { static class Dummy48 extends Dummy47 { Dummy48 i48; } static class Dummy49 extends Dummy48 { Dummy49 i49; } static class Dummy50 extends Dummy49 { Dummy50 i50; } - + /** * Write and read class descriptors to/from a stream. * Arguments: <# cycles> */ public long run(String[] args) throws Exception { - int ncycles = Integer.parseInt(args[0]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - ObjectStreamClass desc = ObjectStreamClass.lookup(Dummy50.class); - - doReps(oout, oin, sbuf, desc, 1); // warmup + int ncycles = Integer.parseInt(args[0]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); + ObjectStreamClass desc = ObjectStreamClass.lookup(Dummy50.class); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, desc, ncycles); + doReps(oout, oin, sbuf, desc, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, desc, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, ObjectStreamClass desc, int ncycles) - throws Exception + StreamBuffer sbuf, ObjectStreamClass desc, int ncycles) + throws Exception { - for (int i = 0; i < ncycles; i++) { - sbuf.reset(); - oout.reset(); - oout.writeObject(desc); - oout.flush(); - oin.readObject(); - } + for (int i = 0; i < ncycles; i++) { + sbuf.reset(); + oout.reset(); + oout.writeObject(desc); + oout.flush(); + oin.readObject(); + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Cons.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Cons.java index 7d6bb08ceb1..99d58c05472 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Cons.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Cons.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -53,29 +53,28 @@ public class Cons implements Benchmark { public long run(String[] args) throws Exception { int reps = Integer.parseInt(args[0]); Dummy dummy = new Dummy(); - StreamBuffer sbuf = new StreamBuffer(); - - doReps(sbuf, dummy, 1); // warmup + StreamBuffer sbuf = new StreamBuffer(); - long start = System.currentTimeMillis(); - doReps(sbuf, dummy, reps); + doReps(sbuf, dummy, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(sbuf, dummy, reps); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of cycles. */ void doReps(StreamBuffer sbuf, Dummy dummy, int reps) throws Exception { - OutputStream out = sbuf.getOutputStream(); - InputStream in = sbuf.getInputStream(); - for (int i = 0; i < reps; i++) { - sbuf.reset(); - ObjectOutputStream oout = new ObjectOutputStream(out); - oout.writeObject(dummy); - oout.flush(); - ObjectInputStream oin = new ObjectInputStream(in); - oin.readObject(); - } + OutputStream out = sbuf.getOutputStream(); + InputStream in = sbuf.getInputStream(); + for (int i = 0; i < reps; i++) { + sbuf.reset(); + ObjectOutputStream oout = new ObjectOutputStream(out); + oout.writeObject(dummy); + oout.flush(); + ObjectInputStream oin = new ObjectInputStream(in); + oin.readObject(); + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomDefaultObjTrees.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomDefaultObjTrees.java index 01d60c54a15..14ddbee4f82 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomDefaultObjTrees.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomDefaultObjTrees.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,19 +39,19 @@ import java.io.Serializable; * defaultWriteObject() and defaultReadObject(). */ public class CustomDefaultObjTrees implements Benchmark { - + static class Node implements Serializable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -61,13 +61,13 @@ public class CustomDefaultObjTrees implements Benchmark { } private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); + out.defaultWriteObject(); } - - private void readObject(ObjectInputStream in) + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); + in.defaultReadObject(); } } @@ -79,20 +79,20 @@ public class CustomDefaultObjTrees implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[] trees = genTrees(depth, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, trees, 1); // warmup + int depth = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[] trees = genTrees(depth, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, trees, nbatches); + doReps(oout, oin, sbuf, trees, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, trees, nbatches); return System.currentTimeMillis() - start; } @@ -100,33 +100,32 @@ public class CustomDefaultObjTrees implements Benchmark { * Generate object trees. */ Node[] genTrees(int depth, int ntrees) { - Node[] trees = new Node[ntrees]; - for (int i = 0; i < ntrees; i++) { - trees[i] = new Node(null, depth); - } - return trees; + Node[] trees = new Node[ntrees]; + for (int i = 0; i < ntrees; i++) { + trees[i] = new Node(null, depth); + } + return trees; } /** - * Run benchmark for given number of batches, with each batch containing + * Run benchmark for given number of batches, with each batch containing * the given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] trees, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] trees, int nbatches) + throws Exception { - int ncycles = trees.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(trees[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = trees.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(trees[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomObjTrees.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomObjTrees.java index b87cc3673f3..d5f10a8738c 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomObjTrees.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/CustomObjTrees.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,19 +38,19 @@ import java.io.Serializable; * nodes contain custom writeObject() and readObject() methods. */ public class CustomObjTrees implements Benchmark { - + static class Node implements Serializable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -60,35 +60,35 @@ public class CustomObjTrees implements Benchmark { } private void writeObject(ObjectOutputStream out) throws IOException { - out.writeBoolean(z); - out.writeByte(b); - out.writeChar(c); - out.writeShort(s); - out.writeInt(i); - out.writeFloat(f); - out.writeLong(j); - out.writeDouble(d); - out.writeObject(str); - out.writeObject(parent); - out.writeObject(left); - out.writeObject(right); + out.writeBoolean(z); + out.writeByte(b); + out.writeChar(c); + out.writeShort(s); + out.writeInt(i); + out.writeFloat(f); + out.writeLong(j); + out.writeDouble(d); + out.writeObject(str); + out.writeObject(parent); + out.writeObject(left); + out.writeObject(right); } - - private void readObject(ObjectInputStream in) + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - z = in.readBoolean(); - b = in.readByte(); - c = in.readChar(); - s = in.readShort(); - i = in.readInt(); - f = in.readFloat(); - j = in.readLong(); - d = in.readDouble(); - str = (String) in.readObject(); - parent = in.readObject(); - left = in.readObject(); - right = in.readObject(); + z = in.readBoolean(); + b = in.readByte(); + c = in.readChar(); + s = in.readShort(); + i = in.readInt(); + f = in.readFloat(); + j = in.readLong(); + d = in.readDouble(); + str = (String) in.readObject(); + parent = in.readObject(); + left = in.readObject(); + right = in.readObject(); } } @@ -100,20 +100,20 @@ public class CustomObjTrees implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[] trees = genTrees(depth, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, trees, 1); // warmup + int depth = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[] trees = genTrees(depth, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, trees, nbatches); + doReps(oout, oin, sbuf, trees, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, trees, nbatches); return System.currentTimeMillis() - start; } @@ -121,33 +121,32 @@ public class CustomObjTrees implements Benchmark { * Generate object trees. */ Node[] genTrees(int depth, int ntrees) { - Node[] trees = new Node[ntrees]; - for (int i = 0; i < ntrees; i++) { - trees[i] = new Node(null, depth); - } - return trees; + Node[] trees = new Node[ntrees]; + for (int i = 0; i < ntrees; i++) { + trees[i] = new Node(null, depth); + } + return trees; } /** - * Run benchmark for given number of batches, with each batch containing + * Run benchmark for given number of batches, with each batch containing * the given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] trees, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] trees, int nbatches) + throws Exception { - int ncycles = trees.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(trees[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = trees.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(trees[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/DoubleArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/DoubleArrays.java index 205bc173b8e..f216ebab694 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/DoubleArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/DoubleArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of double array reads/writes. */ public class DoubleArrays implements Benchmark { - + /** * Write and read double arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class DoubleArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - double[][] arrays = new double[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + double[][] arrays = new double[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, double[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, double[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Doubles.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Doubles.java index 231fd0ee86c..e43df322c27 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Doubles.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Doubles.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of double reads/writes. */ public class Doubles implements Benchmark { - + /** * Write and read double values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,39 +44,38 @@ public class Doubles implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeDouble(0.0); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readDouble(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeDouble(0.0); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readDouble(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ExternObjTrees.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ExternObjTrees.java index 15a490080d2..bb9053a787d 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ExternObjTrees.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ExternObjTrees.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -40,19 +40,19 @@ import java.io.ObjectOutputStream; * objects. */ public class ExternObjTrees implements Benchmark { - + static class Node implements Externalizable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -61,40 +61,40 @@ public class ExternObjTrees implements Benchmark { } } - public Node() { - } - - public void writeExternal(ObjectOutput out) throws IOException { - out.writeBoolean(z); - out.writeByte(b); - out.writeChar(c); - out.writeShort(s); - out.writeInt(i); - out.writeFloat(f); - out.writeLong(j); - out.writeDouble(d); - out.writeObject(str); - out.writeObject(parent); - out.writeObject(left); - out.writeObject(right); - } - - public void readExternal(ObjectInput in) - throws IOException, ClassNotFoundException - { - z = in.readBoolean(); - b = in.readByte(); - c = in.readChar(); - s = in.readShort(); - i = in.readInt(); - f = in.readFloat(); - j = in.readLong(); - d = in.readDouble(); - str = (String) in.readObject(); - parent = in.readObject(); - left = in.readObject(); - right = in.readObject(); - } + public Node() { + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeBoolean(z); + out.writeByte(b); + out.writeChar(c); + out.writeShort(s); + out.writeInt(i); + out.writeFloat(f); + out.writeLong(j); + out.writeDouble(d); + out.writeObject(str); + out.writeObject(parent); + out.writeObject(left); + out.writeObject(right); + } + + public void readExternal(ObjectInput in) + throws IOException, ClassNotFoundException + { + z = in.readBoolean(); + b = in.readByte(); + c = in.readChar(); + s = in.readShort(); + i = in.readInt(); + f = in.readFloat(); + j = in.readLong(); + d = in.readDouble(); + str = (String) in.readObject(); + parent = in.readObject(); + left = in.readObject(); + right = in.readObject(); + } } /** @@ -105,20 +105,20 @@ public class ExternObjTrees implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[] trees = genTrees(depth, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, trees, 1); // warmup + int depth = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[] trees = genTrees(depth, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, trees, nbatches); + doReps(oout, oin, sbuf, trees, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, trees, nbatches); return System.currentTimeMillis() - start; } @@ -126,33 +126,32 @@ public class ExternObjTrees implements Benchmark { * Generate object trees. */ Node[] genTrees(int depth, int ntrees) { - Node[] trees = new Node[ntrees]; - for (int i = 0; i < ntrees; i++) { - trees[i] = new Node(null, depth); - } - return trees; + Node[] trees = new Node[ntrees]; + for (int i = 0; i < ntrees; i++) { + trees[i] = new Node(null, depth); + } + return trees; } /** - * Run benchmark for given number of batches, with each batch containing + * Run benchmark for given number of batches, with each batch containing * the given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] trees, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] trees, int nbatches) + throws Exception { - int ncycles = trees.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(trees[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = trees.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(trees[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/FloatArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/FloatArrays.java index 686fd1974f0..8feae044d55 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/FloatArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/FloatArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of float array reads/writes. */ public class FloatArrays implements Benchmark { - + /** * Write and read float arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class FloatArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - float[][] arrays = new float[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + float[][] arrays = new float[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, float[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, float[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Floats.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Floats.java index d84bf5f969f..1dca696a6a4 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Floats.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Floats.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of float reads/writes. */ public class Floats implements Benchmark { - + /** * Write and read float values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,39 +44,38 @@ public class Floats implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeFloat((float) 0.0); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readFloat(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeFloat((float) 0.0); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readFloat(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/GetPutFieldTrees.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/GetPutFieldTrees.java index 95a475c2d72..c5794f05bad 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/GetPutFieldTrees.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/GetPutFieldTrees.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,19 +39,19 @@ import java.io.Serializable; * GetField()/PutField() API. */ public class GetPutFieldTrees implements Benchmark { - + static class Node implements Serializable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -76,19 +76,19 @@ public class GetPutFieldTrees implements Benchmark { fields.put("right", right); out.writeFields(); } - - private void readObject(ObjectInputStream in) + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { ObjectInputStream.GetField fields = in.readFields(); - z = fields.get("z", false); - b = fields.get("b", (byte) 0); - c = fields.get("c", (char) 0); - s = fields.get("s", (short) 0); - i = fields.get("i", (int) 0); - f = fields.get("f", (float) 0.0); - j = fields.get("j", (long) 0); - d = fields.get("d", (double) 0.0); + z = fields.get("z", false); + b = fields.get("b", (byte) 0); + c = fields.get("c", (char) 0); + s = fields.get("s", (short) 0); + i = fields.get("i", (int) 0); + f = fields.get("f", (float) 0.0); + j = fields.get("j", (long) 0); + d = fields.get("d", (double) 0.0); str = (String) fields.get("str", null); parent = fields.get("parent", null); left = fields.get("left", null); @@ -104,20 +104,20 @@ public class GetPutFieldTrees implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[] trees = genTrees(depth, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, trees, 1); // warmup + int depth = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[] trees = genTrees(depth, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, trees, nbatches); + doReps(oout, oin, sbuf, trees, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, trees, nbatches); return System.currentTimeMillis() - start; } @@ -125,33 +125,32 @@ public class GetPutFieldTrees implements Benchmark { * Generate object trees. */ Node[] genTrees(int depth, int ntrees) { - Node[] trees = new Node[ntrees]; - for (int i = 0; i < ntrees; i++) { - trees[i] = new Node(null, depth); - } - return trees; + Node[] trees = new Node[ntrees]; + for (int i = 0; i < ntrees; i++) { + trees[i] = new Node(null, depth); + } + return trees; } /** - * Run benchmark for given number of batches, with each batch containing + * Run benchmark for given number of batches, with each batch containing * the given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] trees, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] trees, int nbatches) + throws Exception { - int ncycles = trees.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(trees[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = trees.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(trees[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/IntArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/IntArrays.java index 2bc445373c0..c50059bb6c3 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/IntArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/IntArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of int array reads/writes. */ public class IntArrays implements Benchmark { - + /** * Write and read int arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class IntArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - int[][] arrays = new int[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + int[][] arrays = new int[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, int[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Ints.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Ints.java index 152b048e9b5..90cfb30216f 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Ints.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Ints.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of int reads/writes. */ public class Ints implements Benchmark { - + /** * Write and read int values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,39 +44,38 @@ public class Ints implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeInt(0); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readInt(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeInt(0); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readInt(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/LongArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/LongArrays.java index 21b48e98cb6..802bb82cf9a 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/LongArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/LongArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of long array reads/writes. */ public class LongArrays implements Benchmark { - + /** * Write and read long arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class LongArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - long[][] arrays = new long[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + long[][] arrays = new long[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, long[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, long[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Longs.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Longs.java index 7ebac7f9ffb..fdc1e04e647 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Longs.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Longs.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of long reads/writes. */ public class Longs implements Benchmark { - + /** * Write and read long values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,39 +44,38 @@ public class Longs implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeLong(0); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readLong(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeLong(0); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readLong(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java index aeaa4b19153..49e8e813f6e 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Main.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -46,7 +46,7 @@ import java.util.TimerTask; * Object serialization benchmark mainline. */ public class Main { - + static final String CONFFILE = "/bench/serial/config"; static final String VERSION = "1.3"; @@ -80,55 +80,55 @@ public class Main { p.println(" -o specify output file"); p.println(" -c specify (non-default) configuration file"); p.println(" -html format output as html (default is text)"); - p.println(" -xml format output as xml"); + p.println(" -xml format output as xml"); } /** * Print error message and exit. */ static void die(String mesg) { - System.err.println(mesg); - System.exit(1); + System.err.println(mesg); + System.exit(1); } /** * Mainline parses command line, then hands off to benchmark harness. */ public static void main(String[] args) { - parseArgs(args); - setupStreams(); - if (list) { - listConfig(); - } else { - setupHarness(); - setupReporter(); - if (exitOnTimer) { - setupTimer(testDurationSeconds); - while (true) { - runBenchmarks(); - if (exitRequested) { - System.exit(0); - } - } - } else { - runBenchmarks(); - System.exit(0); - } - } + parseArgs(args); + setupStreams(); + if (list) { + listConfig(); + } else { + setupHarness(); + setupReporter(); + if (exitOnTimer) { + setupTimer(testDurationSeconds); + while (true) { + runBenchmarks(); + if (exitRequested) { + System.exit(0); + } + } + } else { + runBenchmarks(); + System.exit(0); + } + } } - + /** * Parse command-line arguments. */ static void parseArgs(String[] args) { - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-h")) { - usage(); - System.exit(0); - } else if (args[i].equals("-v")) { - verbose = true; - } else if (args[i].equals("-l")) { - list = true; + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-h")) { + usage(); + System.exit(0); + } else if (args[i].equals("-v")) { + verbose = true; + } else if (args[i].equals("-l")) { + list = true; } else if (args[i].equals("-t")) { if (++i >= args.length) die("Error: no timeout value specified"); @@ -138,64 +138,64 @@ public class Main { } catch (Exception e) { die("Error: unable to determine timeout value"); } - } else if (args[i].equals("-o")) { - if (++i >= args.length) - die("Error: no output file specified"); - try { - repstr = new FileOutputStream(args[i]); - } catch (IOException e) { - die("Error: unable to open \"" + args[i] + "\""); - } - } else if (args[i].equals("-c")) { - if (++i >= args.length) - die("Error: no config file specified"); - try { - confstr = new FileInputStream(args[i]); - } catch (IOException e) { - die("Error: unable to open \"" + args[i] + "\""); - } - } else if (args[i].equals("-html")) { - if (format != TEXT) - die("Error: conflicting formats"); - format = HTML; - } else if (args[i].equals("-xml")) { - if (format != TEXT) - die("Error: conflicting formats"); - format = XML; - } else { - System.err.println("Illegal option: \"" + args[i] + "\""); - usage(); - System.exit(1); - } - } + } else if (args[i].equals("-o")) { + if (++i >= args.length) + die("Error: no output file specified"); + try { + repstr = new FileOutputStream(args[i]); + } catch (IOException e) { + die("Error: unable to open \"" + args[i] + "\""); + } + } else if (args[i].equals("-c")) { + if (++i >= args.length) + die("Error: no config file specified"); + try { + confstr = new FileInputStream(args[i]); + } catch (IOException e) { + die("Error: unable to open \"" + args[i] + "\""); + } + } else if (args[i].equals("-html")) { + if (format != TEXT) + die("Error: conflicting formats"); + format = HTML; + } else if (args[i].equals("-xml")) { + if (format != TEXT) + die("Error: conflicting formats"); + format = XML; + } else { + System.err.println("Illegal option: \"" + args[i] + "\""); + usage(); + System.exit(1); + } + } } - + /** * Set up configuration file and report streams, if not set already. */ static void setupStreams() { - if (repstr == null) - repstr = System.out; - if (confstr == null) - confstr = (new Main()).getClass().getResourceAsStream(CONFFILE); - if (confstr == null) - die("Error: unable to find default config file"); + if (repstr == null) + repstr = System.out; + if (confstr == null) + confstr = (new Main()).getClass().getResourceAsStream(CONFFILE); + if (confstr == null) + die("Error: unable to find default config file"); } - + /** * Print contents of configuration file to selected output stream. */ static void listConfig() { - try { - byte[] buf = new byte[256]; - int len; - while ((len = confstr.read(buf)) != -1) - repstr.write(buf, 0, len); - } catch (IOException e) { - die("Error: failed to list config file"); - } + try { + byte[] buf = new byte[256]; + int len; + while ((len = confstr.read(buf)) != -1) + repstr.write(buf, 0, len); + } catch (IOException e) { + die("Error: failed to list config file"); + } } - + /** * Set up the timer to end the test. * @@ -222,12 +222,12 @@ public class Main { } catch (ConfigFormatException e) { String errmsg = e.getMessage(); if (errmsg != null) { - die("Error parsing config file: " + errmsg); - } else { + die("Error parsing config file: " + errmsg); + } else { die("Error: illegal config file syntax"); - } + } } catch (IOException e) { - die("Error: failed to read config file"); + die("Error: failed to read config file"); } } @@ -236,22 +236,22 @@ public class Main { */ static void setupReporter() { String title = "Object Serialization Benchmark, v" + VERSION; - switch (format) { - case TEXT: - reporter = new TextReporter(repstr, title); - break; - - case HTML: - reporter = new HtmlReporter(repstr, title); - break; + switch (format) { + case TEXT: + reporter = new TextReporter(repstr, title); + break; - case XML: - reporter = new XmlReporter(repstr, title); - break; - - default: - die("Error: unrecognized format type"); - } + case HTML: + reporter = new HtmlReporter(repstr, title); + break; + + case XML: + reporter = new XmlReporter(repstr, title); + break; + + default: + die("Error: unrecognized format type"); + } } /** @@ -261,4 +261,3 @@ public class Main { harness.runBenchmarks(reporter, verbose); } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjArrays.java index 1bd833e19c2..b9b1ec5fb7a 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,16 +39,16 @@ public class ObjArrays implements Benchmark { static class Node implements Serializable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -57,7 +57,7 @@ public class ObjArrays implements Benchmark { } } } - + /** * Write and read object arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -66,34 +66,34 @@ public class ObjArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[][] arrays = genArrays(size, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[][] arrays = genArrays(size, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Generate object arrays. */ Node[][] genArrays(int size, int narrays) { - Node[][] arrays = new Node[narrays][size]; - for (int i = 0; i < narrays; i++) { - for (int j = 0; j < size; j++) { - arrays[i][j] = new Node(null, 0); - } - } - return arrays; + Node[][] arrays = new Node[narrays][size]; + for (int i = 0; i < narrays; i++) { + for (int j = 0; j < size; j++) { + arrays[i][j] = new Node(null, 0); + } + } + return arrays; } /** @@ -101,22 +101,20 @@ public class ObjArrays implements Benchmark { * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, Node[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjTrees.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjTrees.java index 2fc1cc57a90..f9405ba1d9c 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjTrees.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ObjTrees.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,19 +36,19 @@ import java.io.Serializable; * Benchmark for testing speed of writes and reads of an object tree. */ public class ObjTrees implements Benchmark { - + static class Node implements Serializable { boolean z; - byte b; - char c; - short s; - int i; - float f; - long j; - double d; - String str = "bodega"; + byte b; + char c; + short s; + int i; + float f; + long j; + double d; + String str = "bodega"; Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -66,20 +66,20 @@ public class ObjTrees implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[] trees = genTrees(depth, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, trees, 1); // warmup + int depth = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[] trees = genTrees(depth, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, trees, nbatches); + doReps(oout, oin, sbuf, trees, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, trees, nbatches); return System.currentTimeMillis() - start; } @@ -87,33 +87,32 @@ public class ObjTrees implements Benchmark { * Generate object trees. */ Node[] genTrees(int depth, int ntrees) { - Node[] trees = new Node[ntrees]; - for (int i = 0; i < ntrees; i++) { - trees[i] = new Node(null, depth); - } - return trees; + Node[] trees = new Node[ntrees]; + for (int i = 0; i < ntrees; i++) { + trees[i] = new Node(null, depth); + } + return trees; } /** - * Run benchmark for given number of batches, with each batch containing + * Run benchmark for given number of batches, with each batch containing * the given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] trees, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] trees, int nbatches) + throws Exception { - int ncycles = trees.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(trees[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = trees.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(trees[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyArrays.java index 2a114eac6ca..c6ad86dd50e 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -42,15 +42,15 @@ import java.lang.reflect.Proxy; public class ProxyArrays implements Benchmark { static class DummyHandler implements InvocationHandler, Serializable { - public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable - { - return null; - } + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + return null; + } } - + static interface DummyInterface { - public void foo(); + public void foo(); } /** @@ -61,40 +61,40 @@ public class ProxyArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Proxy[][] arrays = genArrays(size, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Proxy[][] arrays = genArrays(size, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Generate proxy arrays. */ Proxy[][] genArrays(int size, int narrays) throws Exception { - Class proxyClass = - Proxy.getProxyClass(DummyInterface.class.getClassLoader(), - new Class[] { DummyInterface.class }); - Constructor proxyCons = - proxyClass.getConstructor(new Class[] { InvocationHandler.class }); - Object[] consArgs = new Object[] { new DummyHandler() }; - Proxy[][] arrays = new Proxy[narrays][size]; - for (int i = 0; i < narrays; i++) { - for (int j = 0; j < size; j++) { - arrays[i][j] = (Proxy) proxyCons.newInstance(consArgs); - } - } - return arrays; + Class proxyClass = + Proxy.getProxyClass(DummyInterface.class.getClassLoader(), + new Class[] { DummyInterface.class }); + Constructor proxyCons = + proxyClass.getConstructor(new Class[] { InvocationHandler.class }); + Object[] consArgs = new Object[] { new DummyHandler() }; + Proxy[][] arrays = new Proxy[narrays][size]; + for (int i = 0; i < narrays; i++) { + for (int j = 0; j < size; j++) { + arrays[i][j] = (Proxy) proxyCons.newInstance(consArgs); + } + } + return arrays; } /** @@ -102,22 +102,20 @@ public class ProxyArrays implements Benchmark { * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Proxy[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, Proxy[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyClassDesc.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyClassDesc.java index a5ae07a09ad..4a0576361a2 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyClassDesc.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ProxyClassDesc.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,7 +38,7 @@ import java.lang.reflect.Proxy; * Benchmark for testing speed of proxy class descriptor reads/writes. */ public class ProxyClassDesc implements Benchmark { - + static interface A1 {}; static interface A2 {}; static interface A3 {}; @@ -54,75 +54,74 @@ public class ProxyClassDesc implements Benchmark { static interface C3 {}; static interface C4 {}; static interface C5 {}; - + /** * Write and read proxy class descriptors to/from a stream. * Arguments: <# cycles> */ public long run(String[] args) throws Exception { - int ncycles = Integer.parseInt(args[0]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - ObjectStreamClass[] descs = genDescs(); + int ncycles = Integer.parseInt(args[0]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); + ObjectStreamClass[] descs = genDescs(); - doReps(oout, oin, sbuf, descs, 1); // warmup + doReps(oout, oin, sbuf, descs, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, descs, ncycles); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, descs, ncycles); return System.currentTimeMillis() - start; } - + /** * Generate proxy class descriptors. */ ObjectStreamClass[] genDescs() { - ClassLoader ldr = ProxyClassDesc.class.getClassLoader(); - Class[] ifaces = new Class[3]; - Class[] a = - new Class[] { A1.class, A2.class, A3.class, A4.class, A5.class }; - Class[] b = - new Class[] { B1.class, B2.class, B3.class, B4.class, B5.class }; - Class[] c = - new Class[] { C1.class, C2.class, C3.class, C4.class, C5.class }; - ObjectStreamClass[] descs = - new ObjectStreamClass[a.length * b.length * c.length]; - int n = 0; - for (int i = 0; i < a.length; i++) { - ifaces[0] = a[i]; - for (int j = 0; j < b.length; j++) { - ifaces[1] = b[j]; - for (int k = 0; k < c.length; k++) { - ifaces[2] = c[k]; - Class proxyClass = Proxy.getProxyClass(ldr, ifaces); - descs[n++] = ObjectStreamClass.lookup(proxyClass); - } - } - } - return descs; + ClassLoader ldr = ProxyClassDesc.class.getClassLoader(); + Class[] ifaces = new Class[3]; + Class[] a = + new Class[] { A1.class, A2.class, A3.class, A4.class, A5.class }; + Class[] b = + new Class[] { B1.class, B2.class, B3.class, B4.class, B5.class }; + Class[] c = + new Class[] { C1.class, C2.class, C3.class, C4.class, C5.class }; + ObjectStreamClass[] descs = + new ObjectStreamClass[a.length * b.length * c.length]; + int n = 0; + for (int i = 0; i < a.length; i++) { + ifaces[0] = a[i]; + for (int j = 0; j < b.length; j++) { + ifaces[1] = b[j]; + for (int k = 0; k < c.length; k++) { + ifaces[2] = c[k]; + Class proxyClass = Proxy.getProxyClass(ldr, ifaces); + descs[n++] = ObjectStreamClass.lookup(proxyClass); + } + } + } + return descs; } /** * Run benchmark for given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, ObjectStreamClass[] descs, int ncycles) - throws Exception + StreamBuffer sbuf, ObjectStreamClass[] descs, int ncycles) + throws Exception { - int ndescs = descs.length; - for (int i = 0; i < ncycles; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ndescs; j++) { - oout.writeObject(descs[j]); - } - oout.flush(); - for (int j = 0; j < ndescs; j++) { - oin.readObject(); - } - } + int ndescs = descs.length; + for (int i = 0; i < ncycles; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ndescs; j++) { + oout.writeObject(descs[j]); + } + oout.flush(); + for (int j = 0; j < ndescs; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/RepeatObjs.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/RepeatObjs.java index ba95b451e60..08ae15908ef 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/RepeatObjs.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/RepeatObjs.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,7 +36,7 @@ import java.io.Serializable; * Benchmark for testing speed of reads/writes of repeated objects. */ public class RepeatObjs implements Benchmark { - + static class Node implements Serializable { } @@ -49,50 +49,49 @@ public class RepeatObjs implements Benchmark { * Arguments: <# objects> <# cycles> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - Node[] objs = genObjs(size); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, objs, 1); // warmup + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + Node[] objs = genObjs(size); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, objs, nbatches); + doReps(oout, oin, sbuf, objs, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, objs, nbatches); return System.currentTimeMillis() - start; } - + /** * Generate objects. */ Node[] genObjs(int nobjs) { - Node[] objs = new Node[nobjs]; - for (int i = 0; i < nobjs; i++) - objs[i] = new Node(); - return objs; + Node[] objs = new Node[nobjs]; + for (int i = 0; i < nobjs; i++) + objs[i] = new Node(); + return objs; } - + /** * Run benchmark for given number of batches. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] objs, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] objs, int nbatches) + throws Exception { - int nobjs = objs.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < nobjs; j++) { - oout.writeObject(objs[j]); - } - oout.flush(); - for (int j = 0; j < nobjs; j++) { - oin.readObject(); - } - } + int nobjs = objs.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < nobjs; j++) { + oout.writeObject(objs[j]); + } + oout.flush(); + for (int j = 0; j < nobjs; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ReplaceTrees.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ReplaceTrees.java index f52f0438a59..e117453bd9b 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ReplaceTrees.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ReplaceTrees.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -37,15 +37,15 @@ import java.io.Serializable; * objects. */ public class ReplaceTrees implements Benchmark { - + static class Node implements Serializable { Object parent, left, right; - - Node(Object parent, Object left, Object right) { - this.parent = parent; - this.left = left; - this.right = right; - } + + Node(Object parent, Object left, Object right) { + this.parent = parent; + this.left = left; + this.right = right; + } Node(Object parent, int depth) { this.parent = parent; @@ -54,26 +54,26 @@ public class ReplaceTrees implements Benchmark { right = new Node(this, depth - 1); } } - - Object writeReplace() { - return new RepNode(parent, left, right); - } + + Object writeReplace() { + return new RepNode(parent, left, right); + } } - + static class RepNode implements Serializable { - Object parent, left, right; - - RepNode(Object parent, Object left, Object right) { - this.parent = parent; - this.left = left; - this.right = right; - } - - Object readResolve() { - return new Node(parent, left, right); - } + Object parent, left, right; + + RepNode(Object parent, Object left, Object right) { + this.parent = parent; + this.left = left; + this.right = right; + } + + Object readResolve() { + return new Node(parent, left, right); + } } - + /** * Write and read a tree of replaceable objects from a stream. The * benchmark is run in batches: each "batch" consists of a fixed number of @@ -82,20 +82,20 @@ public class ReplaceTrees implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[] trees = genTrees(depth, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, trees, 1); // warmup + int depth = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[] trees = genTrees(depth, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, trees, nbatches); + doReps(oout, oin, sbuf, trees, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, trees, nbatches); return System.currentTimeMillis() - start; } @@ -103,11 +103,11 @@ public class ReplaceTrees implements Benchmark { * Generate object trees. */ Node[] genTrees(int depth, int ntrees) { - Node[] trees = new Node[ntrees]; - for (int i = 0; i < ntrees; i++) { - trees[i] = new Node(null, depth); - } - return trees; + Node[] trees = new Node[ntrees]; + for (int i = 0; i < ntrees; i++) { + trees[i] = new Node(null, depth); + } + return trees; } /** @@ -115,21 +115,20 @@ public class ReplaceTrees implements Benchmark { * the given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] trees, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] trees, int nbatches) + throws Exception { - int ncycles = trees.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(trees[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = trees.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(trees[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ShortArrays.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ShortArrays.java index 9b8cf10a5ec..45339999c5b 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/ShortArrays.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/ShortArrays.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of short array reads/writes. */ public class ShortArrays implements Benchmark { - + /** * Write and read short arrays to/from a stream. The benchmark is run in * batches, with each batch consisting of a fixed number of read/write @@ -44,44 +44,42 @@ public class ShortArrays implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int size = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - short[][] arrays = new short[ncycles][size]; - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); + int size = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + short[][] arrays = new short[ncycles][size]; + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - doReps(oout, oin, sbuf, arrays, 1); // warmup + doReps(oout, oin, sbuf, arrays, 1); // warmup - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, arrays, nbatches); + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, arrays, nbatches); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, short[][] arrays, int nbatches) - throws Exception + StreamBuffer sbuf, short[][] arrays, int nbatches) + throws Exception { - int ncycles = arrays.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(arrays[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = arrays.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(arrays[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Shorts.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Shorts.java index 985d7302a37..dafdf53c9f3 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Shorts.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Shorts.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,7 +35,7 @@ import java.io.ObjectOutputStream; * Benchmark for testing speed of short reads/writes. */ public class Shorts implements Benchmark { - + /** * Write and read short values to/from a stream. The benchmark is run in * batches: each "batch" consists of a fixed number of read/write cycles, @@ -44,39 +44,38 @@ public class Shorts implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int nbatches = Integer.parseInt(args[0]); - int ncycles = Integer.parseInt(args[1]); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, 1, ncycles); // warmup + int nbatches = Integer.parseInt(args[0]); + int ncycles = Integer.parseInt(args[1]); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, nbatches, ncycles); + doReps(oout, oin, sbuf, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, nbatches, ncycles); return System.currentTimeMillis() - start; } - + /** * Run benchmark for given number of batches, with given number of cycles * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeShort(0); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readShort(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeShort(0); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readShort(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/SmallObjTrees.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/SmallObjTrees.java index 30bebd76d64..bb0394f3986 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/SmallObjTrees.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/SmallObjTrees.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,10 +36,10 @@ import java.io.Serializable; * Benchmark for testing speed of writes and reads of a tree of small objects. */ public class SmallObjTrees implements Benchmark { - + static class Node implements Serializable { Object parent, left, right; - + Node(Object parent, int depth) { this.parent = parent; if (depth > 0) { @@ -57,20 +57,20 @@ public class SmallObjTrees implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int depth = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - Node[] trees = genTrees(depth, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, trees, 1); // warmup + int depth = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + Node[] trees = genTrees(depth, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, trees, nbatches); + doReps(oout, oin, sbuf, trees, 1); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, trees, nbatches); return System.currentTimeMillis() - start; } @@ -78,11 +78,11 @@ public class SmallObjTrees implements Benchmark { * Generate object trees. */ Node[] genTrees(int depth, int ntrees) { - Node[] trees = new Node[ntrees]; - for (int i = 0; i < ntrees; i++) { - trees[i] = new Node(null, depth); - } - return trees; + Node[] trees = new Node[ntrees]; + for (int i = 0; i < ntrees; i++) { + trees[i] = new Node(null, depth); + } + return trees; } /** @@ -90,21 +90,20 @@ public class SmallObjTrees implements Benchmark { * given number of cycles. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, Node[] trees, int nbatches) - throws Exception + StreamBuffer sbuf, Node[] trees, int nbatches) + throws Exception { - int ncycles = trees.length; - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(trees[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + int ncycles = trees.length; + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(trees[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/StreamBuffer.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/StreamBuffer.java index 100a294d1dd..33efee8724b 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/StreamBuffer.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/StreamBuffer.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -47,85 +47,85 @@ import java.io.IOException; * StreamBufferInputStream.read(). */ public class StreamBuffer { - + /** * Output stream for writing to stream buffer. */ private class StreamBufferOutputStream extends OutputStream { - - private int pos; - public void write(int b) throws IOException { - if (mode != WRITE_MODE) - throw new IOException(); - while (pos >= buf.length) - grow(); - buf[pos++] = (byte) b; - } - - public void write(byte[] b, int off, int len) throws IOException { - if (mode != WRITE_MODE) - throw new IOException(); - while (pos + len > buf.length) - grow(); - System.arraycopy(b, off, buf, pos, len); - pos += len; - } - - public void close() throws IOException { - if (mode != WRITE_MODE) - throw new IOException(); - mode = READ_MODE; - } + private int pos; + + public void write(int b) throws IOException { + if (mode != WRITE_MODE) + throw new IOException(); + while (pos >= buf.length) + grow(); + buf[pos++] = (byte) b; + } + + public void write(byte[] b, int off, int len) throws IOException { + if (mode != WRITE_MODE) + throw new IOException(); + while (pos + len > buf.length) + grow(); + System.arraycopy(b, off, buf, pos, len); + pos += len; + } + + public void close() throws IOException { + if (mode != WRITE_MODE) + throw new IOException(); + mode = READ_MODE; + } } - + /** * Input stream for reading from stream buffer. */ private class StreamBufferInputStream extends InputStream { - - private int pos; - public int read() throws IOException { - if (mode == CLOSED_MODE) - throw new IOException(); - mode = READ_MODE; - return (pos < out.pos) ? (buf[pos++] & 0xFF) : -1; - } - - public int read(byte[] b, int off, int len) throws IOException { - if (mode == CLOSED_MODE) - throw new IOException(); - mode = READ_MODE; - int avail = out.pos - pos; - int rlen = (avail < len) ? avail : len; - System.arraycopy(buf, pos, b, off, rlen); - pos += rlen; - return rlen; - } - - public long skip(long len) throws IOException { - if (mode == CLOSED_MODE) - throw new IOException(); - mode = READ_MODE; - int avail = out.pos - pos; - long slen = (avail < len) ? avail : len; - pos += slen; - return slen; - } + private int pos; - public int available() throws IOException { - if (mode == CLOSED_MODE) - throw new IOException(); - mode = READ_MODE; - return out.pos - pos; - } - - public void close() throws IOException { - if (mode == CLOSED_MODE) - throw new IOException(); - mode = CLOSED_MODE; - } + public int read() throws IOException { + if (mode == CLOSED_MODE) + throw new IOException(); + mode = READ_MODE; + return (pos < out.pos) ? (buf[pos++] & 0xFF) : -1; + } + + public int read(byte[] b, int off, int len) throws IOException { + if (mode == CLOSED_MODE) + throw new IOException(); + mode = READ_MODE; + int avail = out.pos - pos; + int rlen = (avail < len) ? avail : len; + System.arraycopy(buf, pos, b, off, rlen); + pos += rlen; + return rlen; + } + + public long skip(long len) throws IOException { + if (mode == CLOSED_MODE) + throw new IOException(); + mode = READ_MODE; + int avail = out.pos - pos; + long slen = (avail < len) ? avail : len; + pos += slen; + return slen; + } + + public int available() throws IOException { + if (mode == CLOSED_MODE) + throw new IOException(); + mode = READ_MODE; + return out.pos - pos; + } + + public void close() throws IOException { + if (mode == CLOSED_MODE) + throw new IOException(); + mode = CLOSED_MODE; + } } private static final int START_BUFSIZE = 256; @@ -140,30 +140,29 @@ public class StreamBuffer { private int mode = WRITE_MODE; public StreamBuffer() { - this(START_BUFSIZE); + this(START_BUFSIZE); } - + public StreamBuffer(int size) { - buf = new byte[size]; + buf = new byte[size]; } - + public OutputStream getOutputStream() { - return out; + return out; } - + public InputStream getInputStream() { - return in; + return in; } - + public void reset() { - in.pos = out.pos = 0; - mode = WRITE_MODE; + in.pos = out.pos = 0; + mode = WRITE_MODE; } - + private void grow() { - byte[] newbuf = new byte[buf.length * GROW_FACTOR]; - System.arraycopy(buf, 0, newbuf, 0, buf.length); - buf = newbuf; + byte[] newbuf = new byte[buf.length * GROW_FACTOR]; + System.arraycopy(buf, 0, newbuf, 0, buf.length); + buf = newbuf; } } - diff --git a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Strings.java b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Strings.java index aad74b7212b..512e1a33de4 100644 --- a/jdk/test/java/rmi/reliability/benchmark/bench/serial/Strings.java +++ b/jdk/test/java/rmi/reliability/benchmark/bench/serial/Strings.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -45,20 +45,20 @@ public class Strings implements Benchmark { * Arguments: <# batches> <# cycles per batch> */ public long run(String[] args) throws Exception { - int slen = Integer.parseInt(args[0]); - int nbatches = Integer.parseInt(args[1]); - int ncycles = Integer.parseInt(args[2]); - String[] strs = genStrings(slen, ncycles); - StreamBuffer sbuf = new StreamBuffer(); - ObjectOutputStream oout = - new ObjectOutputStream(sbuf.getOutputStream()); - ObjectInputStream oin = - new ObjectInputStream(sbuf.getInputStream()); - - doReps(oout, oin, sbuf, strs, 1, ncycles); // warmup + int slen = Integer.parseInt(args[0]); + int nbatches = Integer.parseInt(args[1]); + int ncycles = Integer.parseInt(args[2]); + String[] strs = genStrings(slen, ncycles); + StreamBuffer sbuf = new StreamBuffer(); + ObjectOutputStream oout = + new ObjectOutputStream(sbuf.getOutputStream()); + ObjectInputStream oin = + new ObjectInputStream(sbuf.getInputStream()); - long start = System.currentTimeMillis(); - doReps(oout, oin, sbuf, strs, nbatches, ncycles); + doReps(oout, oin, sbuf, strs, 1, ncycles); // warmup + + long start = System.currentTimeMillis(); + doReps(oout, oin, sbuf, strs, nbatches, ncycles); return System.currentTimeMillis() - start; } @@ -66,16 +66,16 @@ public class Strings implements Benchmark { * Generate nstrings random strings, each of length len. */ String[] genStrings(int len, int nstrings) { - String[] strs = new String[nstrings]; - char[] ca = new char[len]; - Random rand = new Random(System.currentTimeMillis()); - for (int i = 0; i < nstrings; i++) { - for (int j = 0; j < len; j++) { - ca[j] = (char) rand.nextInt(); - } - strs[i] = new String(ca); - } - return strs; + String[] strs = new String[nstrings]; + char[] ca = new char[len]; + Random rand = new Random(System.currentTimeMillis()); + for (int i = 0; i < nstrings; i++) { + for (int j = 0; j < len; j++) { + ca[j] = (char) rand.nextInt(); + } + strs[i] = new String(ca); + } + return strs; } /** @@ -83,20 +83,19 @@ public class Strings implements Benchmark { * for each batch. */ void doReps(ObjectOutputStream oout, ObjectInputStream oin, - StreamBuffer sbuf, String[] strs, int nbatches, int ncycles) - throws Exception + StreamBuffer sbuf, String[] strs, int nbatches, int ncycles) + throws Exception { - for (int i = 0; i < nbatches; i++) { - sbuf.reset(); - oout.reset(); - for (int j = 0; j < ncycles; j++) { - oout.writeObject(strs[j]); - } - oout.flush(); - for (int j = 0; j < ncycles; j++) { - oin.readObject(); - } - } + for (int i = 0; i < nbatches; i++) { + sbuf.reset(); + oout.reset(); + for (int j = 0; j < ncycles; j++) { + oout.writeObject(strs[j]); + } + oout.flush(); + for (int j = 0; j < ncycles; j++) { + oin.readObject(); + } + } } } - diff --git a/jdk/test/java/rmi/reliability/juicer/Apple.java b/jdk/test/java/rmi/reliability/juicer/Apple.java index 10c5ba6fc6c..f1b6b640351 100644 --- a/jdk/test/java/rmi/reliability/juicer/Apple.java +++ b/jdk/test/java/rmi/reliability/juicer/Apple.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,7 @@ import java.rmi.Remote; import java.rmi.RemoteException; /** - * A remote factory for Orange instances. This interface also + * A remote factory for Orange instances. This interface also * includes a method to test object array serialization. */ public interface Apple extends Remote { diff --git a/jdk/test/java/rmi/reliability/juicer/AppleEvent.java b/jdk/test/java/rmi/reliability/juicer/AppleEvent.java index b019e29c26f..c76a6fd271e 100644 --- a/jdk/test/java/rmi/reliability/juicer/AppleEvent.java +++ b/jdk/test/java/rmi/reliability/juicer/AppleEvent.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ import java.util.Date; /** * The AppleEvent class is simply an object to be passed to a - * remote object exported by an applet. The intent is to verify + * remote object exported by an applet. The intent is to verify * proper object serialization of arrays. */ public class AppleEvent implements Serializable { @@ -39,24 +39,24 @@ public class AppleEvent implements Serializable { private final Date when; public AppleEvent(int what) { - this.what = what; - this.when = new Date(); + this.what = what; + this.when = new Date(); } public String toString() { - String desc = "["; - switch (what) { - case BUY: - desc += "BUY"; - break; - case EAT: - desc += "EAT"; - break; - case THROW: - desc += "THROW"; - break; - } - desc += " @ " + when + "]"; - return desc; + String desc = "["; + switch (what) { + case BUY: + desc += "BUY"; + break; + case EAT: + desc += "EAT"; + break; + case THROW: + desc += "THROW"; + break; + } + desc += " @ " + when + "]"; + return desc; } } diff --git a/jdk/test/java/rmi/reliability/juicer/AppleImpl.java b/jdk/test/java/rmi/reliability/juicer/AppleImpl.java index f8027f063eb..f1f1c3ee94f 100644 --- a/jdk/test/java/rmi/reliability/juicer/AppleImpl.java +++ b/jdk/test/java/rmi/reliability/juicer/AppleImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,46 +34,46 @@ public class AppleImpl extends UnicastRemoteObject implements Apple { private static final Logger logger = Logger.getLogger("reliability.apple"); private final String name; - + public AppleImpl(String name) throws RemoteException { - this.name = name; + this.name = name; } /** * Receive an array of AppleEvent objects. */ public void notify(AppleEvent[] events) { - String threadName = Thread.currentThread().getName(); - logger.log(Level.FINEST, - threadName + ": " + toString() + ".notify: BEGIN"); + String threadName = Thread.currentThread().getName(); + logger.log(Level.FINEST, + threadName + ": " + toString() + ".notify: BEGIN"); - for (int i = 0; i < events.length; i++) { - logger.log(Level.FINEST, - threadName + ": " + toString() + ".notify(): events[" - + i + "] = " + events[i].toString()); - } + for (int i = 0; i < events.length; i++) { + logger.log(Level.FINEST, + threadName + ": " + toString() + ".notify(): events[" + + i + "] = " + events[i].toString()); + } - logger.log(Level.FINEST, - threadName + ": " + toString() + ".notify(): END"); + logger.log(Level.FINEST, + threadName + ": " + toString() + ".notify(): END"); } /** * Return a newly created and exported orange implementation. */ public Orange newOrange(String name) throws RemoteException { - String threadName = Thread.currentThread().getName(); - logger.log(Level.FINEST, - threadName + ": " + toString() + ".newOrange(" + name + "): BEGIN"); + String threadName = Thread.currentThread().getName(); + logger.log(Level.FINEST, + threadName + ": " + toString() + ".newOrange(" + name + "): BEGIN"); - Orange orange = new OrangeImpl(name); - - logger.log(Level.FINEST, - threadName + ": " + toString() + ".newOrange(" + name + "): END"); + Orange orange = new OrangeImpl(name); - return orange; + logger.log(Level.FINEST, + threadName + ": " + toString() + ".newOrange(" + name + "): END"); + + return orange; } public String toString() { - return name; + return name; } } diff --git a/jdk/test/java/rmi/reliability/juicer/AppleUser.java b/jdk/test/java/rmi/reliability/juicer/AppleUser.java index c7eb48d46b9..be86b053b12 100644 --- a/jdk/test/java/rmi/reliability/juicer/AppleUser.java +++ b/jdk/test/java/rmi/reliability/juicer/AppleUser.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java b/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java index 475aca228e3..d2f8b681f5b 100644 --- a/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java +++ b/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,30 +27,30 @@ * a large number of concurrent, long running, remote method invocations * between many threads which have exported remote objects. These * threads use remote objects that carry on deep "two party" - * recursion. The juicer relies on Distributed Garbage Collection to - * unexport these remote objects when no more references are held to them. + * recursion. The juicer relies on Distributed Garbage Collection to + * unexport these remote objects when no more references are held to them. * The two parties in the recursion are OrangeImpl and * OrangeEchoImpl. OrangeImpl checks the base case of the recursion * so that the program will exit. * * When the AppleUserImpl.main() method is invoked, the class binds an * instance of itself in a registry. A second server process, - * an ApplicationServer, is started which looks up the recently + * an ApplicationServer, is started which looks up the recently * bound AppleUser object. This server is either started up in * the same VM or can optionally be started in a separate VM on the - * same host or on a different host. When this test is run on the - * RMI profile, ApplicationServer must be started by AppleUserImpl + * same host or on a different host. When this test is run on the + * RMI profile, ApplicationServer must be started by AppleUserImpl * and the complete juicer runs in a single process. * * The second server process instructs the AppleUserImpl to "use" some apples. * AppleUserImpl creates a new thread for each apple. These threads * initiate the two party recursion. - * + * * Each recursive call nests to a depth determined by this - * expression: (2 + Math.abs(random.nextInt() % (maxLevel + 1)), + * expression: (2 + Math.abs(random.nextInt() % (maxLevel + 1)), * where maxLevel is a command line parameter. Thus each recursive * call nests a random number of levels between 2 and maxLevel. - * + * * The test ends when an exception is encountered or the stop time * has been reached. * @@ -81,8 +81,8 @@ import java.util.logging.Level; */ public class AppleUserImpl extends UnicastRemoteObject implements AppleUser { - private static final Logger logger = - Logger.getLogger("reliability.appleuser"); + private static final Logger logger = + Logger.getLogger("reliability.appleuser"); private static int threadNum = 0; private static long testDuration = 0; private static int maxLevel = 7; @@ -91,7 +91,7 @@ public class AppleUserImpl extends UnicastRemoteObject implements AppleUser { private static boolean startTestNotified = false; private static final Random random = new Random(); private static final Object lock = new Object(); - + public AppleUserImpl() throws RemoteException { } @@ -100,7 +100,7 @@ public class AppleUserImpl extends UnicastRemoteObject implements AppleUser { * to start "juicing". */ public synchronized void startTest() throws RemoteException { - startTestNotified = true; + startTestNotified = true; this.notifyAll(); } @@ -109,9 +109,9 @@ public class AppleUserImpl extends UnicastRemoteObject implements AppleUser { * process and thereby terminate the test. */ public void reportException(Exception status) throws RemoteException { - synchronized (lock) { - this.status = status; - lock.notifyAll(); + synchronized (lock) { + this.status = status; + lock.notifyAll(); } } @@ -120,136 +120,136 @@ public class AppleUserImpl extends UnicastRemoteObject implements AppleUser { * stress it out. */ public synchronized void useApple(Apple apple) throws RemoteException { - String threadName = Thread.currentThread().getName(); - logger.log(Level.FINEST, - threadName + ": AppleUserImpl.useApple(): BEGIN"); + String threadName = Thread.currentThread().getName(); + logger.log(Level.FINEST, + threadName + ": AppleUserImpl.useApple(): BEGIN"); - AppleUserThread t = - new AppleUserThread("AppleUserThread-" + (++threadNum), apple); - t.start(); + AppleUserThread t = + new AppleUserThread("AppleUserThread-" + (++threadNum), apple); + t.start(); - logger.log(Level.FINEST, - threadName + ": AppleUserImpl.useApple(): END"); + logger.log(Level.FINEST, + threadName + ": AppleUserImpl.useApple(): END"); } - + /** * The AppleUserThread class repeatedly invokes calls on its associated * Apple object to stress the RMI system. */ class AppleUserThread extends Thread { - final Apple apple; + final Apple apple; - public AppleUserThread(String name, Apple apple) { - super(name); - this.apple = apple; - } + public AppleUserThread(String name, Apple apple) { + super(name); + this.apple = apple; + } - public void run() { - int orangeNum = 0; + public void run() { + int orangeNum = 0; long stopTime = System.currentTimeMillis() + testDuration; Logger logger = Logger.getLogger("reliability.appleuserthread"); - - try { - do { // loop until stopTime is reached - /* - * Notify apple with some apple events. This tests + try { + do { // loop until stopTime is reached + + /* + * Notify apple with some apple events. This tests * serialization of arrays. - */ - int numEvents = Math.abs(random.nextInt() % 5); - AppleEvent[] events = new AppleEvent[numEvents]; - for (int i = 0; i < events.length; i++) { - events[i] = new AppleEvent(orangeNum % 3); - } - apple.notify(events); + */ + int numEvents = Math.abs(random.nextInt() % 5); + AppleEvent[] events = new AppleEvent[numEvents]; + for (int i = 0; i < events.length; i++) { + events[i] = new AppleEvent(orangeNum % 3); + } + apple.notify(events); - /* - * Request a new orange object be created in + /* + * Request a new orange object be created in * the application server. - */ - Orange orange = apple.newOrange( - "Orange(" + getName() + ")-" + (++orangeNum)); + */ + Orange orange = apple.newOrange( + "Orange(" + getName() + ")-" + (++orangeNum)); - /* - * Create a large message of random ints to pass to orange. - */ + /* + * Create a large message of random ints to pass to orange. + */ int msgLength = 1000 + Math.abs(random.nextInt() % 3000); - int[] message = new int[msgLength]; - for (int i = 0; i < message.length; i++) { - message[i] = random.nextInt(); - } + int[] message = new int[msgLength]; + for (int i = 0; i < message.length; i++) { + message[i] = random.nextInt(); + } - /* - * Invoke recursive call on the orange. Base case + /* + * Invoke recursive call on the orange. Base case * of recursion inverts messgage. - */ - OrangeEchoImpl echo = new OrangeEchoImpl( - "OrangeEcho(" + getName() + ")-" + orangeNum); - int[] response = orange.recurse(echo, message, - 2 + Math.abs(random.nextInt() % (maxLevel + 1))); + */ + OrangeEchoImpl echo = new OrangeEchoImpl( + "OrangeEcho(" + getName() + ")-" + orangeNum); + int[] response = orange.recurse(echo, message, + 2 + Math.abs(random.nextInt() % (maxLevel + 1))); - /* - * Verify message was properly inverted and not corrupted - * through all the recursive method invocations. - */ - if (response.length != message.length) { - throw new RuntimeException( - "ERROR: CORRUPTED RESPONSE: " + - "wrong length of returned array " + "(should be " + - message.length + ", is " + response.length + ")"); - } - for (int i = 0; i < message.length; i++) { - if (~message[i] != response[i]) { - throw new RuntimeException( - "ERROR: CORRUPTED RESPONSE: " + - "at element " + i + "/" + message.length + - " of returned array (should be " + - Integer.toHexString(~message[i]) + ", is " + - Integer.toHexString(response[i]) + ")"); - } - } + /* + * Verify message was properly inverted and not corrupted + * through all the recursive method invocations. + */ + if (response.length != message.length) { + throw new RuntimeException( + "ERROR: CORRUPTED RESPONSE: " + + "wrong length of returned array " + "(should be " + + message.length + ", is " + response.length + ")"); + } + for (int i = 0; i < message.length; i++) { + if (~message[i] != response[i]) { + throw new RuntimeException( + "ERROR: CORRUPTED RESPONSE: " + + "at element " + i + "/" + message.length + + " of returned array (should be " + + Integer.toHexString(~message[i]) + ", is " + + Integer.toHexString(response[i]) + ")"); + } + } - try { - Thread.sleep(Math.abs(random.nextInt() % 10) * 1000); - } catch (InterruptedException e) { - } + try { + Thread.sleep(Math.abs(random.nextInt() % 10) * 1000); + } catch (InterruptedException e) { + } - } while (System.currentTimeMillis() < stopTime); + } while (System.currentTimeMillis() < stopTime); - } catch (Exception e) { - status = e; - } - finished = true; - synchronized (lock) { - lock.notifyAll(); - } - } + } catch (Exception e) { + status = e; + } + finished = true; + synchronized (lock) { + lock.notifyAll(); + } + } } private static void usage() { - System.err.println("Usage: AppleUserImpl [-hours | " + - "-seconds ]"); - System.err.println(" [-maxLevel ]"); - System.err.println(" [-othervm]"); - System.err.println(" [-exit]"); - System.err.println(" hours The number of hours to run the juicer."); - System.err.println(" The default is 0 hours."); - System.err.println(" seconds The number of seconds to run the juicer."); - System.err.println(" The default is 0 seconds."); - System.err.println(" maxLevel The maximum number of levels to "); - System.err.println(" recurse on each call."); - System.err.println(" The default is 7 levels."); - System.err.println(" othervm If present, the VM will wait for the"); - System.err.println(" ApplicationServer to start in"); - System.err.println(" another process."); - System.err.println(" The default is to run everything in"); - System.err.println(" a single VM."); - System.err.println(" exit If present, the VM will call"); - System.err.println(" System.exit() when main() finishes."); - System.err.println(" The default is to not call"); - System.err.println(" System.exit()."); - System.err.println(); + System.err.println("Usage: AppleUserImpl [-hours | " + + "-seconds ]"); + System.err.println(" [-maxLevel ]"); + System.err.println(" [-othervm]"); + System.err.println(" [-exit]"); + System.err.println(" hours The number of hours to run the juicer."); + System.err.println(" The default is 0 hours."); + System.err.println(" seconds The number of seconds to run the juicer."); + System.err.println(" The default is 0 seconds."); + System.err.println(" maxLevel The maximum number of levels to "); + System.err.println(" recurse on each call."); + System.err.println(" The default is 7 levels."); + System.err.println(" othervm If present, the VM will wait for the"); + System.err.println(" ApplicationServer to start in"); + System.err.println(" another process."); + System.err.println(" The default is to run everything in"); + System.err.println(" a single VM."); + System.err.println(" exit If present, the VM will call"); + System.err.println(" System.exit() when main() finishes."); + System.err.println(" The default is to not call"); + System.err.println(" System.exit()."); + System.err.println(); } /** @@ -257,122 +257,122 @@ public class AppleUserImpl extends UnicastRemoteObject implements AppleUser { * an apple user implementation in an rmiregistry running on localhost. */ public static void main(String[] args) { - String durationString = null; + String durationString = null; boolean othervm = false; boolean exit = false; - try { - // parse command line args - for (int i = 0; i < args.length ; i++ ) { + try { + // parse command line args + for (int i = 0; i < args.length ; i++ ) { String arg = args[i]; if (arg.equals("-hours")) { - if (durationString != null) { - usage(); - } - i++; - int hours = Integer.parseInt(args[i]); - durationString = hours + " hours"; - testDuration = hours * 60 * 60 * 1000; + if (durationString != null) { + usage(); + } + i++; + int hours = Integer.parseInt(args[i]); + durationString = hours + " hours"; + testDuration = hours * 60 * 60 * 1000; } else if (arg.equals("-seconds")) { - if (durationString != null) { - usage(); - } - i++; - long seconds = Long.parseLong(args[i]); - durationString = seconds + " seconds"; - testDuration = seconds * 1000; + if (durationString != null) { + usage(); + } + i++; + long seconds = Long.parseLong(args[i]); + durationString = seconds + " seconds"; + testDuration = seconds * 1000; } else if (arg.equals("-maxLevel")) { - i++; - maxLevel = Integer.parseInt(args[i]); + i++; + maxLevel = Integer.parseInt(args[i]); } else if (arg.equals("-othervm")) { - othervm = true; + othervm = true; } else if (arg.equals("-exit")) { - exit = true; + exit = true; } else { - usage(); + usage(); } } if (durationString == null) { durationString = testDuration + " milliseconds"; } - } catch (Throwable t) { - usage(); - throw new RuntimeException("TEST FAILED: Bad argument"); - } + } catch (Throwable t) { + usage(); + throw new RuntimeException("TEST FAILED: Bad argument"); + } - AppleUserImpl user = null; - long startTime = 0; - Thread server = null; - int exitValue = 0; - try { - user = new AppleUserImpl(); + AppleUserImpl user = null; + long startTime = 0; + Thread server = null; + int exitValue = 0; + try { + user = new AppleUserImpl(); - synchronized (user) { - // create new registry and bind new AppleUserImpl in registry + synchronized (user) { + // create new registry and bind new AppleUserImpl in registry LocateRegistry.createRegistry(2006); LocateRegistry.getRegistry(2006).rebind("AppleUser",user); - - // start the other server if applicable - if (othervm) { - // the other server must be running in a separate process - logger.log(Level.INFO, "Application server must be " + - "started in separate process"); - } else { - Class app = Class.forName("ApplicationServer"); - server = new Thread((Runnable) app.newInstance()); - logger.log(Level.INFO, "Starting application server " + + + // start the other server if applicable + if (othervm) { + // the other server must be running in a separate process + logger.log(Level.INFO, "Application server must be " + + "started in separate process"); + } else { + Class app = Class.forName("ApplicationServer"); + server = new Thread((Runnable) app.newInstance()); + logger.log(Level.INFO, "Starting application server " + "in same process"); - server.start(); - } + server.start(); + } - // wait for other server to call startTest method - logger.log(Level.INFO, "Waiting for application server " + + // wait for other server to call startTest method + logger.log(Level.INFO, "Waiting for application server " + "process to start"); - while (!startTestNotified) { - user.wait(); - } - } - - startTime = System.currentTimeMillis(); - logger.log(Level.INFO, "Test starting"); - - // wait for exception to be reported or first thread to complete - logger.log(Level.INFO, "Waiting " + durationString + " for " + - "test to complete or exception to be thrown"); - - synchronized (lock) { - while (status == null && !finished) { - lock.wait(); - } - } - - if (status != null) { - throw new RuntimeException("TEST FAILED: " - + "juicer server reported an exception", status); - } else { - logger.log(Level.INFO, "TEST PASSED"); + while (!startTestNotified) { + user.wait(); + } } - } catch (Exception e) { - logger.log(Level.INFO, "TEST FAILED"); - exitValue = 1; - if (exit) { - e.printStackTrace(); - } - throw new RuntimeException("TEST FAILED: " - + "unexpected exception", e); - } finally { - long actualDuration = System.currentTimeMillis() - startTime; - logger.log(Level.INFO, "Test finished"); - try { - UnicastRemoteObject.unexportObject(user, true); + + startTime = System.currentTimeMillis(); + logger.log(Level.INFO, "Test starting"); + + // wait for exception to be reported or first thread to complete + logger.log(Level.INFO, "Waiting " + durationString + " for " + + "test to complete or exception to be thrown"); + + synchronized (lock) { + while (status == null && !finished) { + lock.wait(); + } + } + + if (status != null) { + throw new RuntimeException("TEST FAILED: " + + "juicer server reported an exception", status); + } else { + logger.log(Level.INFO, "TEST PASSED"); + } + } catch (Exception e) { + logger.log(Level.INFO, "TEST FAILED"); + exitValue = 1; + if (exit) { + e.printStackTrace(); + } + throw new RuntimeException("TEST FAILED: " + + "unexpected exception", e); + } finally { + long actualDuration = System.currentTimeMillis() - startTime; + logger.log(Level.INFO, "Test finished"); + try { + UnicastRemoteObject.unexportObject(user, true); } catch (NoSuchObjectException ignore) { - } - logger.log(Level.INFO, "Test duration was " + - (actualDuration/1000) + " seconds " + - "(" + (actualDuration/3600000) + " hours)"); - System.gc(); System.gc(); - if (exit) { - System.exit(exitValue); - } + } + logger.log(Level.INFO, "Test duration was " + + (actualDuration/1000) + " seconds " + + "(" + (actualDuration/3600000) + " hours)"); + System.gc(); System.gc(); + if (exit) { + System.exit(exitValue); + } } } } diff --git a/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java b/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java index 050da0e3b7b..e17528af81b 100644 --- a/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java +++ b/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,7 +32,7 @@ import java.util.logging.Level; * stress test of RMI. */ public class ApplicationServer implements Runnable { - + /** number of remote Apple objects to export */ private static final Logger logger = Logger.getLogger("reliability.orange"); private static final int LOOKUP_ATTEMPTS = 5; @@ -58,102 +58,102 @@ public class ApplicationServer implements Runnable { * them with server. */ public void run() { - try { - int i = 0; + try { + int i = 0; - /* - * Locate apple user object in registry. The lookup will - * occur until it is successful or fails LOOKUP_ATTEMPTS times. - * These repeated attempts allow the ApplicationServer - * to be started before the AppleUserImpl. - */ - Exception exc = null; - for (i = 0; i < LOOKUP_ATTEMPTS; i++) { - try { - Registry registry = LocateRegistry.getRegistry( - registryHost, 2006); - user = (AppleUser) registry.lookup("AppleUser"); - user.startTest(); - break; //successfully obtained AppleUser - } catch (Exception e) { - exc = e; - Thread.sleep(10000); //sleep 10 seconds and try again - } - } - if (user == null) { - logger.log(Level.SEVERE, "Failed to lookup AppleUser:", exc); - return; - } - - /* - * Create and export apple implementations. - */ - try { - for (i = 0; i < numApples; i++) { - apples[i] = new AppleImpl("AppleImpl #" + (i + 1)); - } - } catch (RemoteException e) { - logger.log(Level.SEVERE, - "Failed to create AppleImpl #" + (i + 1) + ":", e); - user.reportException(e); - return; - } - - /* - * Hand apple objects to apple user. - */ - try { - for (i = 0; i < numApples; i++) { - user.useApple(apples[i]); + /* + * Locate apple user object in registry. The lookup will + * occur until it is successful or fails LOOKUP_ATTEMPTS times. + * These repeated attempts allow the ApplicationServer + * to be started before the AppleUserImpl. + */ + Exception exc = null; + for (i = 0; i < LOOKUP_ATTEMPTS; i++) { + try { + Registry registry = LocateRegistry.getRegistry( + registryHost, 2006); + user = (AppleUser) registry.lookup("AppleUser"); + user.startTest(); + break; //successfully obtained AppleUser + } catch (Exception e) { + exc = e; + Thread.sleep(10000); //sleep 10 seconds and try again } - } catch (RemoteException e) { - logger.log(Level.SEVERE, - "Failed to register callbacks for " + apples[i] + ":", e); - user.reportException(e); - return; - } - } catch (Exception e) { - logger.log(Level.SEVERE, "Unexpected exception:", e); - } + } + if (user == null) { + logger.log(Level.SEVERE, "Failed to lookup AppleUser:", exc); + return; + } + + /* + * Create and export apple implementations. + */ + try { + for (i = 0; i < numApples; i++) { + apples[i] = new AppleImpl("AppleImpl #" + (i + 1)); + } + } catch (RemoteException e) { + logger.log(Level.SEVERE, + "Failed to create AppleImpl #" + (i + 1) + ":", e); + user.reportException(e); + return; + } + + /* + * Hand apple objects to apple user. + */ + try { + for (i = 0; i < numApples; i++) { + user.useApple(apples[i]); + } + } catch (RemoteException e) { + logger.log(Level.SEVERE, + "Failed to register callbacks for " + apples[i] + ":", e); + user.reportException(e); + return; + } + } catch (Exception e) { + logger.log(Level.SEVERE, "Unexpected exception:", e); + } } private static void usage() { - System.err.println("Usage: ApplicationServer [-numApples ]"); - System.err.println(" [-registryHost ]"); - System.err.println(" numApples The number of apples (threads) to use."); - System.err.println(" The default is 10 apples."); - System.err.println(" host The host running rmiregistry " + - "which contains AppleUser."); - System.err.println(" The default is \"localhost\"."); - System.err.println(); + System.err.println("Usage: ApplicationServer [-numApples ]"); + System.err.println(" [-registryHost ]"); + System.err.println(" numApples The number of apples (threads) to use."); + System.err.println(" The default is 10 apples."); + System.err.println(" host The host running rmiregistry " + + "which contains AppleUser."); + System.err.println(" The default is \"localhost\"."); + System.err.println(); } public static void main(String[] args) { int num = DEFAULT_NUMAPPLES; String host = DEFAULT_REGISTRYHOST; - // parse command line args - try { + // parse command line args + try { for (int i = 0; i < args.length ; i++ ) { - String arg = args[i]; - if (arg.equals("-numApples")) { + String arg = args[i]; + if (arg.equals("-numApples")) { i++; num = Integer.parseInt(args[i]); - } else if (arg.equals("-registryHost")) { + } else if (arg.equals("-registryHost")) { i++; host = args[i]; - } else { + } else { usage(); - } + } } - } catch (Throwable t) { + } catch (Throwable t) { usage(); - throw new RuntimeException("TEST FAILED: Bad argument"); - } + throw new RuntimeException("TEST FAILED: Bad argument"); + } - // start the client server - Thread server = new Thread(new ApplicationServer(num,host)); - server.start(); - // main should exit once all exported remote objects are gc'd + // start the client server + Thread server = new Thread(new ApplicationServer(num,host)); + server.start(); + // main should exit once all exported remote objects are gc'd } } diff --git a/jdk/test/java/rmi/reliability/juicer/Orange.java b/jdk/test/java/rmi/reliability/juicer/Orange.java index 6020eae3681..40e670a7ee5 100644 --- a/jdk/test/java/rmi/reliability/juicer/Orange.java +++ b/jdk/test/java/rmi/reliability/juicer/Orange.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,11 +26,11 @@ import java.rmi.RemoteException; /** * Represents one remote party of the deep 2-party recursion implemented by - * this RMI reliability test. An Orange instance recursively calls back + * this RMI reliability test. An Orange instance recursively calls back * to it's caller, typically an OrangeEcho instance. * The recursion stops when it reaches a given 'level'. */ public interface Orange extends Remote { - int[] recurse(OrangeEcho echo, int[] message, int level) - throws RemoteException; + int[] recurse(OrangeEcho echo, int[] message, int level) + throws RemoteException; } diff --git a/jdk/test/java/rmi/reliability/juicer/OrangeEcho.java b/jdk/test/java/rmi/reliability/juicer/OrangeEcho.java index 77e5d2f103f..8077afad8bf 100644 --- a/jdk/test/java/rmi/reliability/juicer/OrangeEcho.java +++ b/jdk/test/java/rmi/reliability/juicer/OrangeEcho.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,11 +26,11 @@ import java.rmi.RemoteException; /** * Represents one remote party of the deep 2-party recursion implemented by - * this RMI reliability test. An OrangeEcho instance recursively calls back + * this RMI reliability test. An OrangeEcho instance recursively calls back * to it's caller, an Orange instance. * The recursion stops when it reaches a given 'level'. */ public interface OrangeEcho extends Remote { int[] recurse(Orange orange, int[] message, int level) - throws RemoteException; + throws RemoteException; } diff --git a/jdk/test/java/rmi/reliability/juicer/OrangeEchoImpl.java b/jdk/test/java/rmi/reliability/juicer/OrangeEchoImpl.java index 494bf1914fa..5472138bd31 100644 --- a/jdk/test/java/rmi/reliability/juicer/OrangeEchoImpl.java +++ b/jdk/test/java/rmi/reliability/juicer/OrangeEchoImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,12 +33,12 @@ import java.util.logging.Level; */ public class OrangeEchoImpl extends UnicastRemoteObject implements OrangeEcho { - private static final Logger logger = - Logger.getLogger("reliability.orangeecho"); + private static final Logger logger = + Logger.getLogger("reliability.orangeecho"); private final String name; public OrangeEchoImpl(String name) throws RemoteException { - this.name = name; + this.name = name; } /** @@ -46,24 +46,24 @@ public class OrangeEchoImpl extends UnicastRemoteObject implements OrangeEcho { * with the same message data and a decremented recursion level. */ public int[] recurse(Orange orange, int[] message, int level) - throws RemoteException + throws RemoteException { - String threadName = Thread.currentThread().getName(); + String threadName = Thread.currentThread().getName(); - logger.log(Level.FINEST, - threadName + ": " + toString() + ".recurse(message[" - + message.length + "], " + level + "): BEGIN"); + logger.log(Level.FINEST, + threadName + ": " + toString() + ".recurse(message[" + + message.length + "], " + level + "): BEGIN"); - int[] response = orange.recurse(this, message, level - 1); + int[] response = orange.recurse(this, message, level - 1); - logger.log(Level.FINEST, - threadName + ": " + toString() + ".recurse(message[" - + message.length + "], " + level + "): END"); + logger.log(Level.FINEST, + threadName + ": " + toString() + ".recurse(message[" + + message.length + "], " + level + "): END"); - return response; + return response; } public String toString() { - return name; + return name; } } diff --git a/jdk/test/java/rmi/reliability/juicer/OrangeImpl.java b/jdk/test/java/rmi/reliability/juicer/OrangeImpl.java index 876617e1acb..9643ca52fea 100644 --- a/jdk/test/java/rmi/reliability/juicer/OrangeImpl.java +++ b/jdk/test/java/rmi/reliability/juicer/OrangeImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,7 +36,7 @@ public class OrangeImpl extends UnicastRemoteObject implements Orange { private final String name; public OrangeImpl(String name) throws RemoteException { - this.name = name; + this.name = name; } /** @@ -44,31 +44,31 @@ public class OrangeImpl extends UnicastRemoteObject implements Orange { * object if not at recursion level zero. */ public int[] recurse(OrangeEcho echo, int[] message, int level) - throws RemoteException + throws RemoteException { - String threadName = Thread.currentThread().getName(); - logger.log(Level.FINEST, - threadName + ": " + toString() + ".recurse(message[" - + message.length + "], " + level + "): BEGIN"); + String threadName = Thread.currentThread().getName(); + logger.log(Level.FINEST, + threadName + ": " + toString() + ".recurse(message[" + + message.length + "], " + level + "): BEGIN"); - int[] response; - if (level > 0) { - response = echo.recurse(this, message, level); - } else { - for (int i = 0; i < message.length; i++) { - message[i] = ~message[i]; - } - response = message; - } + int[] response; + if (level > 0) { + response = echo.recurse(this, message, level); + } else { + for (int i = 0; i < message.length; i++) { + message[i] = ~message[i]; + } + response = message; + } - logger.log(Level.FINEST, - threadName + ": " + toString() + ".recurse(message[" - + message.length + "], " + level + "): END"); + logger.log(Level.FINEST, + threadName + ": " + toString() + ".recurse(message[" + + message.length + "], " + level + "): END"); - return response; + return response; } public String toString() { - return name; + return name; } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressConstants.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressConstants.java index 7db4a6b9c8a..cc7526077d8 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressConstants.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressConstants.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,9 +27,9 @@ interface CompressConstants { // constants for 6-bit code values - static final int NOP = 0; // no operation: used to pad words on flush() - static final int RAW = 1; // introduces raw byte format - static final int BASE = 2; // base for codes found in lookup table + static final int NOP = 0; // no operation: used to pad words on flush() + static final int RAW = 1; // introduces raw byte format + static final int BASE = 2; // base for codes found in lookup table static final String codeTable = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()"; + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()"; } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressInputStream.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressInputStream.java index 3a42bb18073..31577a1c2ad 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressInputStream.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressInputStream.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,7 @@ class CompressInputStream extends FilterInputStream { public CompressInputStream(InputStream in) { - super(in); + super(in); } // buffer of unpacked 6-bit codes from last 32-word read @@ -41,70 +41,70 @@ class CompressInputStream extends FilterInputStream int bufPos = 5; public int read() throws IOException { - try { - int code; - do { - code = readCode(); - } while (code == NOP); // ignore NOP codes + try { + int code; + do { + code = readCode(); + } while (code == NOP); // ignore NOP codes - if (code >= BASE) - return codeTable.charAt(code - BASE); - else if (code == RAW) { - int high = readCode(); - int low = readCode(); - return (high << 4) | low; - } else - throw new IOException("unknown compression code: " + code); - } catch (EOFException e) { - return -1; - } + if (code >= BASE) + return codeTable.charAt(code - BASE); + else if (code == RAW) { + int high = readCode(); + int low = readCode(); + return (high << 4) | low; + } else + throw new IOException("unknown compression code: " + code); + } catch (EOFException e) { + return -1; + } } public int read(byte b[], int off, int len) throws IOException { - if (len <= 0) { - return 0; - } + if (len <= 0) { + return 0; + } - int c = read(); - if (c == -1) { - return -1; - } - b[off] = (byte)c; + int c = read(); + if (c == -1) { + return -1; + } + b[off] = (byte)c; - int i = 1; + int i = 1; /***** - try { - for (; i < len ; i++) { - c = read(); - if (c == -1) { - break; - } - if (b != null) { - b[off + i] = (byte)c; - } - } - } catch (IOException ee) { - } + try { + for (; i < len ; i++) { + c = read(); + if (c == -1) { + break; + } + if (b != null) { + b[off + i] = (byte)c; + } + } + } catch (IOException ee) { + } *****/ - return i; + return i; } private int readCode() throws IOException { - if (bufPos == 5) { - int b1 = in.read(); - int b2 = in.read(); - int b3 = in.read(); - int b4 = in.read(); - if ((b1 | b2 | b3 | b4) < 0) - throw new EOFException(); - int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; - buf[0] = (pack >>> 24) & 0x3F; - buf[1] = (pack >>> 18) & 0x3F; - buf[2] = (pack >>> 12) & 0x3F; - buf[3] = (pack >>> 6) & 0x3F; - buf[4] = (pack >>> 0) & 0x3F; - bufPos = 0; - } - return buf[bufPos++]; + if (bufPos == 5) { + int b1 = in.read(); + int b2 = in.read(); + int b3 = in.read(); + int b4 = in.read(); + if ((b1 | b2 | b3 | b4) < 0) + throw new EOFException(); + int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; + buf[0] = (pack >>> 24) & 0x3F; + buf[1] = (pack >>> 18) & 0x3F; + buf[2] = (pack >>> 12) & 0x3F; + buf[3] = (pack >>> 6) & 0x3F; + buf[4] = (pack >>> 0) & 0x3F; + bufPos = 0; + } + return buf[bufPos++]; } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressOutputStream.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressOutputStream.java index ca1a5963f95..5d38e147b18 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressOutputStream.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/CompressOutputStream.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,7 @@ class CompressOutputStream extends FilterOutputStream { public CompressOutputStream(OutputStream out) { - super(out); + super(out); } // buffer of 6-bit codes to pack into next 32-bit word @@ -41,44 +41,44 @@ class CompressOutputStream extends FilterOutputStream int bufPos = 0; public void write(int b) throws IOException { - b &= 0xFF; // force argument to a byte + b &= 0xFF; // force argument to a byte - int pos = codeTable.indexOf((char)b); - if (pos != -1) - writeCode(BASE + pos); - else { - writeCode(RAW); - writeCode(b >> 4); - writeCode(b & 0xF); - } + int pos = codeTable.indexOf((char)b); + if (pos != -1) + writeCode(BASE + pos); + else { + writeCode(RAW); + writeCode(b >> 4); + writeCode(b & 0xF); + } } public void write(byte b[], int off, int len) throws IOException { - /* - * This is quite an inefficient implementation, because it has to - * call the other write method for every byte in the array. It + /* + * This is quite an inefficient implementation, because it has to + * call the other write method for every byte in the array. It * could be optimized for performance by doing all the processing - * in this method. - */ - for (int i = 0; i < len; i++) - write(b[off + i]); + * in this method. + */ + for (int i = 0; i < len; i++) + write(b[off + i]); } public void flush() throws IOException { - while (bufPos > 0) - writeCode(NOP); + while (bufPos > 0) + writeCode(NOP); } private void writeCode(int c) throws IOException { - buf[bufPos++] = c; - if (bufPos == 5) { // write next word when we have 5 codes - int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) | - (buf[3] << 6) | buf[4]; - out.write((pack >>> 24) & 0xFF); - out.write((pack >>> 16) & 0xFF); - out.write((pack >>> 8) & 0xFF); - out.write((pack >>> 0) & 0xFF); - bufPos = 0; - } + buf[bufPos++] = c; + if (bufPos == 5) { // write next word when we have 5 codes + int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) | + (buf[3] << 6) | buf[4]; + out.write((pack >>> 24) & 0xFF); + out.write((pack >>> 16) & 0xFF); + out.write((pack >>> 8) & 0xFF); + out.write((pack >>> 0) & 0xFF); + bufPos = 0; + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/Echo.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/Echo.java index b313a906dc2..074781b2559 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/Echo.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/Echo.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java index ee01472f7eb..7b334fe0375 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -39,49 +39,49 @@ public class EchoImpl * Initialization constructor. */ public EchoImpl(String protocol) - throws ActivationException, RemoteException + throws ActivationException, RemoteException { - super(null, makeMarshalledObject(protocol), false, 0, - new MultiSocketFactory.ClientFactory(protocol, pattern), - new MultiSocketFactory.ServerFactory(protocol, pattern)); + super(null, makeMarshalledObject(protocol), false, 0, + new MultiSocketFactory.ClientFactory(protocol, pattern), + new MultiSocketFactory.ServerFactory(protocol, pattern)); } /** * Activation constructor. */ public EchoImpl(ActivationID id, MarshalledObject obj) - throws RemoteException + throws RemoteException { - super(id, 0, - new MultiSocketFactory.ClientFactory(getProtocol(obj), pattern), - new MultiSocketFactory.ServerFactory(getProtocol(obj), pattern)); + super(id, 0, + new MultiSocketFactory.ClientFactory(getProtocol(obj), pattern), + new MultiSocketFactory.ServerFactory(getProtocol(obj), pattern)); } private static MarshalledObject makeMarshalledObject(String protocol) { - MarshalledObject obj = null; - try { - obj = new MarshalledObject(protocol); - } catch (Exception willNotHappen) { - } + MarshalledObject obj = null; + try { + obj = new MarshalledObject(protocol); + } catch (Exception willNotHappen) { + } - return obj; + return obj; } private static String getProtocol(MarshalledObject obj) { - String protocol = ""; - try { - protocol = (String) obj.get(); - } catch (Exception willNotHappen) { - } + String protocol = ""; + try { + protocol = (String) obj.get(); + } catch (Exception willNotHappen) { + } - return protocol; + return protocol; } - + public byte[] echoNot(byte[] data) { - byte[] result = new byte[data.length]; - for (int i = 0; i < data.length; i++) - result[i] = (byte) ~data[i]; - return result; + byte[] result = new byte[data.length]; + for (int i = 0; i < data.length; i++) + result[i] = (byte) ~data[i]; + return result; } /** @@ -89,7 +89,7 @@ public class EchoImpl */ public void shutdown() throws Exception { - (new Thread(this,"Echo.shutdown")).start(); + (new Thread(this,"Echo.shutdown")).start(); } /** @@ -98,43 +98,43 @@ public class EchoImpl * object may still have pending/executing calls), then * unexport the object forcibly. */ - public void run() + public void run() { - ActivationLibrary.deactivate(this, getID()); + ActivationLibrary.deactivate(this, getID()); } public static void main(String[] args) { - /* - * The following line is required with the JDK 1.2 VM so that the - * VM can exit gracefully when this test completes. Otherwise, the - * conservative garbage collector will find a handle to the server - * object on the native stack and not clear the weak reference to - * it in the RMI runtime's object table. - */ - Object dummy = new Object(); - - System.setSecurityManager(new RMISecurityManager()); - - try { - String protocol = ""; - if (args.length >= 1) - protocol = args[0]; + /* + * The following line is required with the JDK 1.2 VM so that the + * VM can exit gracefully when this test completes. Otherwise, the + * conservative garbage collector will find a handle to the server + * object on the native stack and not clear the weak reference to + * it in the RMI runtime's object table. + */ + Object dummy = new Object(); - System.out.println("EchoServer: creating remote object"); - ActivationGroupDesc groupDesc = - new ActivationGroupDesc(null, null); - ActivationSystem system = ActivationGroup.getSystem(); - ActivationGroupID groupID = system.registerGroup(groupDesc); - ActivationGroup.createGroup(groupID, groupDesc, 0); - - EchoImpl impl = new EchoImpl(protocol); - System.out.println("EchoServer: binding in registry"); - Naming.rebind("//:" + UseCustomSocketFactory.REGISTRY_PORT + - "/EchoServer", impl); - System.out.println("EchoServer ready."); - } catch (Exception e) { - System.err.println("EXCEPTION OCCURRED:"); - e.printStackTrace(); - } + System.setSecurityManager(new RMISecurityManager()); + + try { + String protocol = ""; + if (args.length >= 1) + protocol = args[0]; + + System.out.println("EchoServer: creating remote object"); + ActivationGroupDesc groupDesc = + new ActivationGroupDesc(null, null); + ActivationSystem system = ActivationGroup.getSystem(); + ActivationGroupID groupID = system.registerGroup(groupDesc); + ActivationGroup.createGroup(groupID, groupDesc, 0); + + EchoImpl impl = new EchoImpl(protocol); + System.out.println("EchoServer: binding in registry"); + Naming.rebind("//:" + UseCustomSocketFactory.REGISTRY_PORT + + "/EchoServer", impl); + System.out.println("EchoServer ready."); + } catch (Exception e) { + System.err.println("EXCEPTION OCCURRED:"); + e.printStackTrace(); + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl_Stub.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl_Stub.java index 5ff9b36e12f..134446486fd 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl_Stub.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,47 +29,47 @@ public final class EchoImpl_Stub implements Echo, java.rmi.Remote { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_echoNot_0; private static java.lang.reflect.Method $method_shutdown_1; - + static { - try { - $method_echoNot_0 = Echo.class.getMethod("echoNot", new java.lang.Class[] {byte[].class}); - $method_shutdown_1 = Echo.class.getMethod("shutdown", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_echoNot_0 = Echo.class.getMethod("echoNot", new java.lang.Class[] {byte[].class}); + $method_shutdown_1 = Echo.class.getMethod("shutdown", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public EchoImpl_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of echoNot(byte[]) public byte[] echoNot(byte[] $param_arrayOf_byte_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - Object $result = ref.invoke(this, $method_echoNot_0, new java.lang.Object[] {$param_arrayOf_byte_1}, -4295721514897591756L); - return ((byte[]) $result); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_echoNot_0, new java.lang.Object[] {$param_arrayOf_byte_1}, -4295721514897591756L); + return ((byte[]) $result); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of shutdown() public void shutdown() - throws java.lang.Exception + throws java.lang.Exception { - ref.invoke(this, $method_shutdown_1, null, -7207851917985848402L); + ref.invoke(this, $method_shutdown_1, null, -7207851917985848402L); } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/MultiSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/MultiSocketFactory.java index f8ef69fac1c..9ebfa3236e0 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/MultiSocketFactory.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/MultiSocketFactory.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,194 +34,193 @@ import java.util.zip.*; public class MultiSocketFactory { private static RMISocketFactory def = - RMISocketFactory.getDefaultSocketFactory(); + RMISocketFactory.getDefaultSocketFactory(); + - public static class ServerFactory - implements RMIServerSocketFactory, Serializable + implements RMIServerSocketFactory, Serializable { - private String protocol; - private byte[] data; + private String protocol; + private byte[] data; - public ServerFactory(String protocol, byte[] data) { - this.protocol = protocol; - this.data = data; - } + public ServerFactory(String protocol, byte[] data) { + this.protocol = protocol; + this.data = data; + } - public ServerSocket createServerSocket(int port) throws IOException - { - if (protocol.equals("compress")) { - return new CompressServerSocket(port); - - } else if (protocol.equals("xor")) { - if (data == null || data.length != 1) - throw new IOException("invalid argument for XOR protocol"); - return new XorServerSocket(port, data[0]); + public ServerSocket createServerSocket(int port) throws IOException + { + if (protocol.equals("compress")) { + return new CompressServerSocket(port); - } - - return def.createServerSocket(port); - } + } else if (protocol.equals("xor")) { + if (data == null || data.length != 1) + throw new IOException("invalid argument for XOR protocol"); + return new XorServerSocket(port, data[0]); + + } + + return def.createServerSocket(port); + } } public static class ClientFactory - implements RMIClientSocketFactory, Serializable + implements RMIClientSocketFactory, Serializable { - private String protocol; - private byte[] data; + private String protocol; + private byte[] data; - public ClientFactory(String protocol, byte[] data) { - this.protocol = protocol; - this.data = data; - } - - public Socket createSocket(String host, int port) - throws IOException - { - if (protocol.equals("compress")) { - return new CompressSocket(host, port); - - } else if (protocol.equals("xor")) { - if (data == null || data.length != 1) - throw new IOException("invalid argument for XOR protocol"); - return new XorSocket(host, port, data[0]); + public ClientFactory(String protocol, byte[] data) { + this.protocol = protocol; + this.data = data; + } - } + public Socket createSocket(String host, int port) + throws IOException + { + if (protocol.equals("compress")) { + return new CompressSocket(host, port); - return def.createSocket(host, port); - } + } else if (protocol.equals("xor")) { + if (data == null || data.length != 1) + throw new IOException("invalid argument for XOR protocol"); + return new XorSocket(host, port, data[0]); + + } + + return def.createSocket(host, port); + } } static class CompressSocket extends Socket { - private InputStream in; - private OutputStream out; - public CompressSocket() { super(); } - public CompressSocket(String host, int port) throws IOException { - super(host, port); - } - public InputStream getInputStream() throws IOException { - if (in == null) { - in = new CompressInputStream(super.getInputStream()); - } - return in; + private InputStream in; + private OutputStream out; + public CompressSocket() { super(); } + public CompressSocket(String host, int port) throws IOException { + super(host, port); + } + public InputStream getInputStream() throws IOException { + if (in == null) { + in = new CompressInputStream(super.getInputStream()); + } + return in; + } + public OutputStream getOutputStream() throws IOException { + if (out == null) { + out = new CompressOutputStream(super.getOutputStream()); + } + return out; } - public OutputStream getOutputStream() throws IOException { - if (out == null) { - out = new CompressOutputStream(super.getOutputStream()); - } - return out; - } } static class CompressServerSocket extends ServerSocket { - public CompressServerSocket(int port) throws IOException { - super(port); - } - public Socket accept() throws IOException { - Socket s = new CompressSocket(); - implAccept(s); - return s; - } + public CompressServerSocket(int port) throws IOException { + super(port); + } + public Socket accept() throws IOException { + Socket s = new CompressSocket(); + implAccept(s); + return s; + } } static class XorSocket extends Socket { - private byte pattern; - private InputStream in; - private OutputStream out; - public XorSocket(byte pattern) { super(); this.pattern = pattern; } - public XorSocket(String host, int port, byte pattern) - throws IOException - { - super(host, port); - this.pattern = pattern; - } - public InputStream getInputStream() throws IOException { - if (in == null) { - in = new XorInputStream(super.getInputStream(), pattern); - } - return in; + private byte pattern; + private InputStream in; + private OutputStream out; + public XorSocket(byte pattern) { super(); this.pattern = pattern; } + public XorSocket(String host, int port, byte pattern) + throws IOException + { + super(host, port); + this.pattern = pattern; + } + public InputStream getInputStream() throws IOException { + if (in == null) { + in = new XorInputStream(super.getInputStream(), pattern); + } + return in; + } + public OutputStream getOutputStream() throws IOException { + if (out == null) { + out = new XorOutputStream(super.getOutputStream(), pattern); + } + return out; } - public OutputStream getOutputStream() throws IOException { - if (out == null) { - out = new XorOutputStream(super.getOutputStream(), pattern); - } - return out; - } } static class XorServerSocket extends ServerSocket { - private byte pattern; - public XorServerSocket(int port, byte pattern) throws IOException { - super(port); - this.pattern = pattern; - } - public Socket accept() throws IOException { - Socket s = new XorSocket(pattern); - implAccept(s); - return s; - } + private byte pattern; + public XorServerSocket(int port, byte pattern) throws IOException { + super(port); + this.pattern = pattern; + } + public Socket accept() throws IOException { + Socket s = new XorSocket(pattern); + implAccept(s); + return s; + } } static class XorOutputStream extends FilterOutputStream { - private byte pattern; - public XorOutputStream(OutputStream out, byte pattern) { - super(out); - this.pattern = pattern; - } - public void write(int b) throws IOException { - out.write(b ^ pattern); - out.flush(); - } - public void write(byte b[], int off, int len) throws IOException { - for (int i = 0; i < len; i++) - write(b[off + i]); - } + private byte pattern; + public XorOutputStream(OutputStream out, byte pattern) { + super(out); + this.pattern = pattern; + } + public void write(int b) throws IOException { + out.write(b ^ pattern); + out.flush(); + } + public void write(byte b[], int off, int len) throws IOException { + for (int i = 0; i < len; i++) + write(b[off + i]); + } } static class XorInputStream extends FilterInputStream { - private byte pattern; - public XorInputStream(InputStream in, byte pattern) { - super(in); - this.pattern = pattern; - } - public int read() throws IOException { - int b = in.read(); -// System.out.print("BEFORE: " + Integer.toHexString(b)); - if (b != -1) - b = (b ^ pattern) & 0xFF; -// System.out.println("\tAFTER: " + Integer.toHexString(b)); - return b; - } - public int read(byte b[], int off, int len) throws IOException { - if (len <= 0) { - return 0; - } + private byte pattern; + public XorInputStream(InputStream in, byte pattern) { + super(in); + this.pattern = pattern; + } + public int read() throws IOException { + int b = in.read(); +// System.out.print("BEFORE: " + Integer.toHexString(b)); + if (b != -1) + b = (b ^ pattern) & 0xFF; +// System.out.println("\tAFTER: " + Integer.toHexString(b)); + return b; + } + public int read(byte b[], int off, int len) throws IOException { + if (len <= 0) { + return 0; + } - int c = read(); - if (c == -1) { - return -1; - } - b[off] = (byte)c; + int c = read(); + if (c == -1) { + return -1; + } + b[off] = (byte)c; - int i = 1; + int i = 1; /***** - try { - for (; i < len ; i++) { - c = read(); - if (c == -1) { - break; - } - if (b != null) { - b[off + i] = (byte)c; - } - } - } catch (IOException ee) { - } + try { + for (; i < len ; i++) { + c = read(); + if (c == -1) { + break; + } + if (b != null) { + b[off + i] = (byte)c; + } + } + } catch (IOException ee) { + } *****/ - return i; - } + return i; + } } } - diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java index 7fbcd7f3018..b3e7a77b99b 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -45,124 +45,124 @@ public class UseCustomSocketFactory { final static int REGISTRY_PORT = 2006; static String[] protocol = new String[] { "", "compress", "xor" }; - + public static void main(String[] args) { - System.out.println("\nRegression test for bug 4115696\n"); - - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + System.out.println("\nRegression test for bug 4115696\n"); - try { - LocateRegistry.createRegistry(REGISTRY_PORT); - } catch (Exception e) { - TestLibrary.bomb("creating registry", e); - } + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - RMID rmid = null; - - try { - rmid = RMID.createRMID(true); - rmid.addArguments(new String[] { - "-C-Djava.security.policy=" + - TestParams.defaultGroupPolicy + - " -C-Djava.security.manager=java.rmi.RMISecurityManager "}); - rmid.start(); + try { + LocateRegistry.createRegistry(REGISTRY_PORT); + } catch (Exception e) { + TestLibrary.bomb("creating registry", e); + } - Echo[] echo = spawnAndTest(); - reactivateAndTest(echo); - } catch (IOException e) { - TestLibrary.bomb("creating rmid", e); - } finally { - if (rmid != null) - rmid.destroy(); - } + RMID rmid = null; + + try { + rmid = RMID.createRMID(true); + rmid.addArguments(new String[] { + "-C-Djava.security.policy=" + + TestParams.defaultGroupPolicy + + " -C-Djava.security.manager=java.rmi.RMISecurityManager "}); + rmid.start(); + + Echo[] echo = spawnAndTest(); + reactivateAndTest(echo); + } catch (IOException e) { + TestLibrary.bomb("creating rmid", e); + } finally { + if (rmid != null) + rmid.destroy(); + } } private static Echo[] spawnAndTest() { - - System.err.println("\nCreate Test-->"); - Echo[] echo = new Echo[protocol.length]; - - for (int i = 0; i < protocol.length; i++) { - - JavaVM serverVM = new JavaVM("EchoImpl", - "-Djava.security.policy=" + - TestParams.defaultPolicy, - protocol[i]); + System.err.println("\nCreate Test-->"); - System.err.println("\nusing protocol: " + - (protocol[i] == "" ? "none" : protocol[i])); - - try { - /* spawn VM for EchoServer */ - serverVM.start(); + Echo[] echo = new Echo[protocol.length]; - /* lookup server */ - int tries = 12; // need enough tries for slow machine. - echo[i] = null; - do { - try { - echo[i] = (Echo) Naming.lookup("//:" + REGISTRY_PORT + - "/EchoServer"); - break; - } catch (NotBoundException e) { - try { - Thread.sleep(2000); - } catch (Exception ignore) { - } - continue; - } - } while (--tries > 0); + for (int i = 0; i < protocol.length; i++) { - if (echo[i] == null) - TestLibrary.bomb("server not bound in 12 tries", null); + JavaVM serverVM = new JavaVM("EchoImpl", + "-Djava.security.policy=" + + TestParams.defaultPolicy, + protocol[i]); - /* invoke remote method and print result*/ - System.err.println("Bound to " + echo[i]); - byte[] data = ("Greetings, citizen " + - System.getProperty("user.name") + "!"). getBytes(); - byte[] result = echo[i].echoNot(data); - for (int j = 0; j < result.length; j++) - result[j] = (byte) ~result[j]; - System.err.println("Result: " + new String(result)); - echo[i].shutdown(); - - } catch (Exception e) { - TestLibrary.bomb("test failed", e); - - } finally { - serverVM.destroy(); - try { - Naming.unbind("//:" + REGISTRY_PORT + "/EchoServer"); - } catch (Exception e) { - TestLibrary.bomb("unbinding EchoServer", e); - - } - } - } - return echo; + System.err.println("\nusing protocol: " + + (protocol[i] == "" ? "none" : protocol[i])); + + try { + /* spawn VM for EchoServer */ + serverVM.start(); + + /* lookup server */ + int tries = 12; // need enough tries for slow machine. + echo[i] = null; + do { + try { + echo[i] = (Echo) Naming.lookup("//:" + REGISTRY_PORT + + "/EchoServer"); + break; + } catch (NotBoundException e) { + try { + Thread.sleep(2000); + } catch (Exception ignore) { + } + continue; + } + } while (--tries > 0); + + if (echo[i] == null) + TestLibrary.bomb("server not bound in 12 tries", null); + + /* invoke remote method and print result*/ + System.err.println("Bound to " + echo[i]); + byte[] data = ("Greetings, citizen " + + System.getProperty("user.name") + "!"). getBytes(); + byte[] result = echo[i].echoNot(data); + for (int j = 0; j < result.length; j++) + result[j] = (byte) ~result[j]; + System.err.println("Result: " + new String(result)); + echo[i].shutdown(); + + } catch (Exception e) { + TestLibrary.bomb("test failed", e); + + } finally { + serverVM.destroy(); + try { + Naming.unbind("//:" + REGISTRY_PORT + "/EchoServer"); + } catch (Exception e) { + TestLibrary.bomb("unbinding EchoServer", e); + + } + } + } + return echo; } private static void reactivateAndTest(Echo[] echo) { - System.err.println("\nReactivate Test-->"); + System.err.println("\nReactivate Test-->"); - for (int i = 0; i < echo.length; i++) { - try { - System.err.println("\nusing protocol: " + - (protocol[i] == "" ? "none" : protocol[i])); - byte[] data = ("Greetings, citizen " + - System.getProperty("user.name") + "!").getBytes(); - byte[] result = echo[i].echoNot(data); - for (int j = 0; j < result.length; j++) - result[j] = (byte) ~result[j]; - System.err.println("Result: " + new String(result)); - echo[i].shutdown(); - } catch (Exception e) { - TestLibrary.bomb("activating EchoServer for protocol " + protocol[i], e); - } - } + for (int i = 0; i < echo.length; i++) { + try { + System.err.println("\nusing protocol: " + + (protocol[i] == "" ? "none" : protocol[i])); + byte[] data = ("Greetings, citizen " + + System.getProperty("user.name") + "!").getBytes(); + byte[] result = echo[i].echoNot(data); + for (int j = 0; j < result.length; j++) + result[j] = (byte) ~result[j]; + System.err.println("Result: " + new String(result)); + echo[i].shutdown(); + } catch (Exception e) { + TestLibrary.bomb("activating EchoServer for protocol " + protocol[i], e); + } + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Compress.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Compress.java index 67bcf970a0b..88057b954a0 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Compress.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Compress.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,204 +31,204 @@ import java.net.*; public class Compress { interface CompressConstants { - // constants for 6-bit code values - static final int NOP = 0; // no operation: used to pad words on flush() - static final int RAW = 1; // introduces raw byte format - static final int BASE = 2; // base for codes found in lookup table - static final String codeTable = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()"; - } - - public static class CompressRMIClientSocketFactory - implements java.rmi.server.RMIClientSocketFactory, Serializable { - - public Socket createSocket(String host, int port) - throws IOException { - - return ((Socket) new CompressSocket(host, port)); - } + // constants for 6-bit code values + static final int NOP = 0; // no operation: used to pad words on flush() + static final int RAW = 1; // introduces raw byte format + static final int BASE = 2; // base for codes found in lookup table + static final String codeTable = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()"; } - public static class CompressRMIServerSocketFactory - implements RMIServerSocketFactory, - Serializable { - - public ServerSocket createServerSocket(int port) - throws IOException { + public static class CompressRMIClientSocketFactory + implements java.rmi.server.RMIClientSocketFactory, Serializable { - return ((ServerSocket) new CompressServerSocket(port)); - } - } - - public static class CompressSocket extends Socket { - private InputStream in; - private OutputStream out; - public CompressSocket() { super(); } - public CompressSocket(String host, int port) throws IOException { - super(host, port); - } - public InputStream getInputStream() throws IOException { - if (in == null) { - in = new CompressInputStream(super.getInputStream()); - } - return in; + public Socket createSocket(String host, int port) + throws IOException { + + return ((Socket) new CompressSocket(host, port)); + } + } + + public static class CompressRMIServerSocketFactory + implements RMIServerSocketFactory, + Serializable { + + public ServerSocket createServerSocket(int port) + throws IOException { + + return ((ServerSocket) new CompressServerSocket(port)); + } + } + + public static class CompressSocket extends Socket { + private InputStream in; + private OutputStream out; + public CompressSocket() { super(); } + public CompressSocket(String host, int port) throws IOException { + super(host, port); + } + public InputStream getInputStream() throws IOException { + if (in == null) { + in = new CompressInputStream(super.getInputStream()); + } + return in; + } + public OutputStream getOutputStream() throws IOException { + if (out == null) { + out = new CompressOutputStream(super.getOutputStream()); + } + return out; } - public OutputStream getOutputStream() throws IOException { - if (out == null) { - out = new CompressOutputStream(super.getOutputStream()); - } - return out; - } } public static class CompressServerSocket extends ServerSocket { - public CompressServerSocket(int port) throws IOException { - super(port); - } - public Socket accept() throws IOException { - Socket s = new CompressSocket(); - implAccept(s); - return s; - } + public CompressServerSocket(int port) throws IOException { + super(port); + } + public Socket accept() throws IOException { + Socket s = new CompressSocket(); + implAccept(s); + return s; + } } public static class CompressInputStream extends FilterInputStream - implements CompressConstants + implements CompressConstants { - - public CompressInputStream(InputStream in) { - super(in); - } - - // buffer of unpacked 6-bit codes from last 32-word read - int buf[] = new int[5]; - - // position of next code to read in buffer (5 == end of buffer) - int bufPos = 5; - - public int read() throws IOException { - try { - int code; - do { - code = readCode(); - } while (code == NOP); // ignore NOP codes - - if (code >= BASE) - return codeTable.charAt(code - BASE); - else if (code == RAW) { - int high = readCode(); - int low = readCode(); - return (high << 4) | low; - } else - throw new IOException("unknown compression code: " + code); - } catch (EOFException e) { - return -1; - } - } - - public int read(byte b[], int off, int len) throws IOException { - if (len <= 0) { - return 0; - } - - int c = read(); - if (c == -1) { - return -1; - } - b[off] = (byte)c; - - int i = 1; - /***** - try { - for (; i < len ; i++) { - c = read(); - if (c == -1) { - break; - } - if (b != null) { - b[off + i] = (byte)c; - } - } - } catch (IOException ee) { - } - *****/ - return i; - } - - private int readCode() throws IOException { - if (bufPos == 5) { - int b1 = in.read(); - int b2 = in.read(); - int b3 = in.read(); - int b4 = in.read(); - if ((b1 | b2 | b3 | b4) < 0) - throw new EOFException(); - int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; - buf[0] = (pack >>> 24) & 0x3F; - buf[1] = (pack >>> 18) & 0x3F; - buf[2] = (pack >>> 12) & 0x3F; - buf[3] = (pack >>> 6) & 0x3F; - buf[4] = (pack >>> 0) & 0x3F; - bufPos = 0; - } - return buf[bufPos++]; - } + + public CompressInputStream(InputStream in) { + super(in); + } + + // buffer of unpacked 6-bit codes from last 32-word read + int buf[] = new int[5]; + + // position of next code to read in buffer (5 == end of buffer) + int bufPos = 5; + + public int read() throws IOException { + try { + int code; + do { + code = readCode(); + } while (code == NOP); // ignore NOP codes + + if (code >= BASE) + return codeTable.charAt(code - BASE); + else if (code == RAW) { + int high = readCode(); + int low = readCode(); + return (high << 4) | low; + } else + throw new IOException("unknown compression code: " + code); + } catch (EOFException e) { + return -1; + } + } + + public int read(byte b[], int off, int len) throws IOException { + if (len <= 0) { + return 0; + } + + int c = read(); + if (c == -1) { + return -1; + } + b[off] = (byte)c; + + int i = 1; + /***** + try { + for (; i < len ; i++) { + c = read(); + if (c == -1) { + break; + } + if (b != null) { + b[off + i] = (byte)c; + } + } + } catch (IOException ee) { + } + *****/ + return i; + } + + private int readCode() throws IOException { + if (bufPos == 5) { + int b1 = in.read(); + int b2 = in.read(); + int b3 = in.read(); + int b4 = in.read(); + if ((b1 | b2 | b3 | b4) < 0) + throw new EOFException(); + int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; + buf[0] = (pack >>> 24) & 0x3F; + buf[1] = (pack >>> 18) & 0x3F; + buf[2] = (pack >>> 12) & 0x3F; + buf[3] = (pack >>> 6) & 0x3F; + buf[4] = (pack >>> 0) & 0x3F; + bufPos = 0; + } + return buf[bufPos++]; + } } public static class CompressOutputStream extends FilterOutputStream - implements CompressConstants + implements CompressConstants { - - public CompressOutputStream(OutputStream out) { - super(out); - } - - // buffer of 6-bit codes to pack into next 32-bit word - int buf[] = new int[5]; - - // number of valid codes pending in buffer - int bufPos = 0; - - public void write(int b) throws IOException { - b &= 0xFF; // force argument to a byte - - int pos = codeTable.indexOf((char)b); - if (pos != -1) - writeCode(BASE + pos); - else { - writeCode(RAW); - writeCode(b >> 4); - writeCode(b & 0xF); - } - } - - public void write(byte b[], int off, int len) throws IOException { - /* - * This is quite an inefficient implementation, because it has to - * call the other write method for every byte in the array. It - * could be optimized for performance by doing all the processing - * in this method. - */ - for (int i = 0; i < len; i++) - write(b[off + i]); - } - - public void flush() throws IOException { - while (bufPos > 0) - writeCode(NOP); - } - - private void writeCode(int c) throws IOException { - buf[bufPos++] = c; - if (bufPos == 5) { // write next word when we have 5 codes - int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) | - (buf[3] << 6) | buf[4]; - out.write((pack >>> 24) & 0xFF); - out.write((pack >>> 16) & 0xFF); - out.write((pack >>> 8) & 0xFF); - out.write((pack >>> 0) & 0xFF); - bufPos = 0; - } - } + + public CompressOutputStream(OutputStream out) { + super(out); + } + + // buffer of 6-bit codes to pack into next 32-bit word + int buf[] = new int[5]; + + // number of valid codes pending in buffer + int bufPos = 0; + + public void write(int b) throws IOException { + b &= 0xFF; // force argument to a byte + + int pos = codeTable.indexOf((char)b); + if (pos != -1) + writeCode(BASE + pos); + else { + writeCode(RAW); + writeCode(b >> 4); + writeCode(b & 0xF); + } + } + + public void write(byte b[], int off, int len) throws IOException { + /* + * This is quite an inefficient implementation, because it has to + * call the other write method for every byte in the array. It + * could be optimized for performance by doing all the processing + * in this method. + */ + for (int i = 0; i < len; i++) + write(b[off + i]); + } + + public void flush() throws IOException { + while (bufPos > 0) + writeCode(NOP); + } + + private void writeCode(int c) throws IOException { + buf[bufPos++] = c; + if (bufPos == 5) { // write next word when we have 5 codes + int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) | + (buf[3] << 6) | buf[4]; + out.write((pack >>> 24) & 0xFF); + out.write((pack >>> 16) & 0xFF); + out.write((pack >>> 8) & 0xFF); + out.write((pack >>> 0) & 0xFF); + bufPos = 0; + } + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Hello.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Hello.java index 5d3a83e7e8b..347dd9cc8e3 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Hello.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/Hello.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java index adb1819ec82..13f74488a6c 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,49 +36,49 @@ public class HelloImpl public static boolean clientCalledSuccessfully = false; public HelloImpl() throws RemoteException { - super(0); + super(0); } - + public synchronized String sayHello() { - HelloImpl.clientCalledSuccessfully = true; - System.out.println("hello method called"); - this.notifyAll(); - return "hello"; + HelloImpl.clientCalledSuccessfully = true; + System.out.println("hello method called"); + this.notifyAll(); + return "hello"; } public static void main(String[] args) { - /* - * The following line is required with the JDK 1.2 VM so that the - * VM can exit gracefully when this test completes. Otherwise, the - * conservative garbage collector will find a handle to the server - * object on the native stack and not clear the weak reference to - * it in the RMI runtime's object table. - */ - Object dummy = new Object(); - Hello hello = null; - Registry registry = null; + /* + * The following line is required with the JDK 1.2 VM so that the + * VM can exit gracefully when this test completes. Otherwise, the + * conservative garbage collector will find a handle to the server + * object on the native stack and not clear the weak reference to + * it in the RMI runtime's object table. + */ + Object dummy = new Object(); + Hello hello = null; + Registry registry = null; - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - try { - String protocol = ""; - if (args.length >= 1) - protocol = args[0]; + try { + String protocol = ""; + if (args.length >= 1) + protocol = args[0]; - registry = java.rmi.registry.LocateRegistry. - getRegistry("localhost", TestLibrary.REGISTRY_PORT, - new Compress.CompressRMIClientSocketFactory()); - UseCustomSocketFactory.checkStub(registry, "RMIClientSocket"); - hello = (Hello) registry.lookup("/HelloServer"); + registry = java.rmi.registry.LocateRegistry. + getRegistry("localhost", TestLibrary.REGISTRY_PORT, + new Compress.CompressRMIClientSocketFactory()); + UseCustomSocketFactory.checkStub(registry, "RMIClientSocket"); + hello = (Hello) registry.lookup("/HelloServer"); - /* lookup server */ - System.err.println(hello.sayHello() + - ", remote greeting."); - } catch (Exception e) { - System.err.println("EXCEPTION OCCURRED:"); - e.printStackTrace(); - } finally { - hello = null; - } + /* lookup server */ + System.err.println(hello.sayHello() + + ", remote greeting."); + } catch (Exception e) { + System.err.println("EXCEPTION OCCURRED:"); + e.printStackTrace(); + } finally { + hello = null; + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl_Stub.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl_Stub.java index e500d6741f1..a2858f1ece8 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl_Stub.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,72 +29,72 @@ public final class HelloImpl_Stub implements Hello, java.rmi.Remote { private static java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("java.lang.String sayHello()") + new java.rmi.server.Operation("java.lang.String sayHello()") }; - + private static final long interfaceHash = 6486744599627128933L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_sayHello_0; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_sayHello_0 = Hello.class.getMethod("sayHello", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_sayHello_0 = Hello.class.getMethod("sayHello", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public HelloImpl_Stub() { - super(); + super(); } public HelloImpl_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of sayHello() public java.lang.String sayHello() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_sayHello_0, null, 6043973830760146143L); - return ((java.lang.String) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - java.lang.String $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.lang.String) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_sayHello_0, null, 6043973830760146143L); + return ((java.lang.String) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + java.lang.String $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.String) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java index 767a7c47c8f..3bce0037a8a 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -47,86 +47,86 @@ import java.rmi.registry.*; * (i.e. compression) client and server socket factories. */ public class UseCustomSocketFactory { - + Hello hello = null; - + public static void main(String[] args) { - - Registry registry = null; - HelloImpl impl = null; - System.out.println("\nRegression test for bug 4148850\n"); - - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + Registry registry = null; + HelloImpl impl = null; - try { - impl = new HelloImpl(); + System.out.println("\nRegression test for bug 4148850\n"); - /* Make sure that the rmiregistry can communicate over a - * custom socket. Ensure that the functionality exists to - * allow the rmiregistry to be secure. - */ - registry = LocateRegistry. - createRegistry(TestLibrary.REGISTRY_PORT, - new Compress.CompressRMIClientSocketFactory(), - new Compress.CompressRMIServerSocketFactory()); - registry.rebind("/HelloServer", impl); - checkStub(registry, "RMIServerSocket"); - - } catch (Exception e) { - TestLibrary.bomb("creating registry", e); - } - - JavaVM serverVM = new JavaVM("HelloImpl", "-Djava.security.policy=" + - TestParams.defaultPolicy, ""); + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - try { + try { + impl = new HelloImpl(); - /* - * spawn VM for HelloServer which will download a client socket - * factory - */ - serverVM.start(); + /* Make sure that the rmiregistry can communicate over a + * custom socket. Ensure that the functionality exists to + * allow the rmiregistry to be secure. + */ + registry = LocateRegistry. + createRegistry(TestLibrary.REGISTRY_PORT, + new Compress.CompressRMIClientSocketFactory(), + new Compress.CompressRMIServerSocketFactory()); + registry.rebind("/HelloServer", impl); + checkStub(registry, "RMIServerSocket"); - synchronized (impl) { + } catch (Exception e) { + TestLibrary.bomb("creating registry", e); + } - System.out.println("waiting for remote notification"); - - if (!HelloImpl.clientCalledSuccessfully) { - impl.wait(75 * 1000); - } - - if (!HelloImpl.clientCalledSuccessfully) { - throw new RuntimeException("Client did not execute call in time..."); - } - } + JavaVM serverVM = new JavaVM("HelloImpl", "-Djava.security.policy=" + + TestParams.defaultPolicy, ""); - System.err.println("\nRegression test for bug 4148850 passed.\n "); + try { - } catch (Exception e) { - TestLibrary.bomb("test failed", e); - - } finally { - serverVM.destroy(); - try { - registry.unbind("/HelloServer"); - } catch (Exception e) { - TestLibrary.bomb("unbinding HelloServer", e); - } - TestLibrary.unexport(registry); - TestLibrary.unexport(impl); - impl = null; - registry = null; - } + /* + * spawn VM for HelloServer which will download a client socket + * factory + */ + serverVM.start(); + + synchronized (impl) { + + System.out.println("waiting for remote notification"); + + if (!HelloImpl.clientCalledSuccessfully) { + impl.wait(75 * 1000); + } + + if (!HelloImpl.clientCalledSuccessfully) { + throw new RuntimeException("Client did not execute call in time..."); + } + } + + System.err.println("\nRegression test for bug 4148850 passed.\n "); + + } catch (Exception e) { + TestLibrary.bomb("test failed", e); + + } finally { + serverVM.destroy(); + try { + registry.unbind("/HelloServer"); + } catch (Exception e) { + TestLibrary.bomb("unbinding HelloServer", e); + } + TestLibrary.unexport(registry); + TestLibrary.unexport(impl); + impl = null; + registry = null; + } } static void checkStub(Object stub, String toCheck) throws RemoteException { - System.err.println("Ensuring that the stub contains a socket factory string: " + - toCheck); - System.err.println(stub); - if (stub.toString().indexOf(toCheck) < 0) { - throw new RemoteException("RemoteStub.toString() did not contain instance of " - + toCheck); - } + System.err.println("Ensuring that the stub contains a socket factory string: " + + toCheck); + System.err.println(stub); + if (stub.toString().indexOf(toCheck) < 0) { + throw new RemoteException("RemoteStub.toString() did not contain instance of " + + toCheck); + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressConstants.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressConstants.java index 7db4a6b9c8a..cc7526077d8 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressConstants.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressConstants.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,9 +27,9 @@ interface CompressConstants { // constants for 6-bit code values - static final int NOP = 0; // no operation: used to pad words on flush() - static final int RAW = 1; // introduces raw byte format - static final int BASE = 2; // base for codes found in lookup table + static final int NOP = 0; // no operation: used to pad words on flush() + static final int RAW = 1; // introduces raw byte format + static final int BASE = 2; // base for codes found in lookup table static final String codeTable = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()"; + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()"; } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressInputStream.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressInputStream.java index 3a42bb18073..31577a1c2ad 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressInputStream.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressInputStream.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,7 @@ class CompressInputStream extends FilterInputStream { public CompressInputStream(InputStream in) { - super(in); + super(in); } // buffer of unpacked 6-bit codes from last 32-word read @@ -41,70 +41,70 @@ class CompressInputStream extends FilterInputStream int bufPos = 5; public int read() throws IOException { - try { - int code; - do { - code = readCode(); - } while (code == NOP); // ignore NOP codes + try { + int code; + do { + code = readCode(); + } while (code == NOP); // ignore NOP codes - if (code >= BASE) - return codeTable.charAt(code - BASE); - else if (code == RAW) { - int high = readCode(); - int low = readCode(); - return (high << 4) | low; - } else - throw new IOException("unknown compression code: " + code); - } catch (EOFException e) { - return -1; - } + if (code >= BASE) + return codeTable.charAt(code - BASE); + else if (code == RAW) { + int high = readCode(); + int low = readCode(); + return (high << 4) | low; + } else + throw new IOException("unknown compression code: " + code); + } catch (EOFException e) { + return -1; + } } public int read(byte b[], int off, int len) throws IOException { - if (len <= 0) { - return 0; - } + if (len <= 0) { + return 0; + } - int c = read(); - if (c == -1) { - return -1; - } - b[off] = (byte)c; + int c = read(); + if (c == -1) { + return -1; + } + b[off] = (byte)c; - int i = 1; + int i = 1; /***** - try { - for (; i < len ; i++) { - c = read(); - if (c == -1) { - break; - } - if (b != null) { - b[off + i] = (byte)c; - } - } - } catch (IOException ee) { - } + try { + for (; i < len ; i++) { + c = read(); + if (c == -1) { + break; + } + if (b != null) { + b[off + i] = (byte)c; + } + } + } catch (IOException ee) { + } *****/ - return i; + return i; } private int readCode() throws IOException { - if (bufPos == 5) { - int b1 = in.read(); - int b2 = in.read(); - int b3 = in.read(); - int b4 = in.read(); - if ((b1 | b2 | b3 | b4) < 0) - throw new EOFException(); - int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; - buf[0] = (pack >>> 24) & 0x3F; - buf[1] = (pack >>> 18) & 0x3F; - buf[2] = (pack >>> 12) & 0x3F; - buf[3] = (pack >>> 6) & 0x3F; - buf[4] = (pack >>> 0) & 0x3F; - bufPos = 0; - } - return buf[bufPos++]; + if (bufPos == 5) { + int b1 = in.read(); + int b2 = in.read(); + int b3 = in.read(); + int b4 = in.read(); + if ((b1 | b2 | b3 | b4) < 0) + throw new EOFException(); + int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; + buf[0] = (pack >>> 24) & 0x3F; + buf[1] = (pack >>> 18) & 0x3F; + buf[2] = (pack >>> 12) & 0x3F; + buf[3] = (pack >>> 6) & 0x3F; + buf[4] = (pack >>> 0) & 0x3F; + bufPos = 0; + } + return buf[bufPos++]; } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressOutputStream.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressOutputStream.java index ca1a5963f95..5d38e147b18 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressOutputStream.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/CompressOutputStream.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,7 @@ class CompressOutputStream extends FilterOutputStream { public CompressOutputStream(OutputStream out) { - super(out); + super(out); } // buffer of 6-bit codes to pack into next 32-bit word @@ -41,44 +41,44 @@ class CompressOutputStream extends FilterOutputStream int bufPos = 0; public void write(int b) throws IOException { - b &= 0xFF; // force argument to a byte + b &= 0xFF; // force argument to a byte - int pos = codeTable.indexOf((char)b); - if (pos != -1) - writeCode(BASE + pos); - else { - writeCode(RAW); - writeCode(b >> 4); - writeCode(b & 0xF); - } + int pos = codeTable.indexOf((char)b); + if (pos != -1) + writeCode(BASE + pos); + else { + writeCode(RAW); + writeCode(b >> 4); + writeCode(b & 0xF); + } } public void write(byte b[], int off, int len) throws IOException { - /* - * This is quite an inefficient implementation, because it has to - * call the other write method for every byte in the array. It + /* + * This is quite an inefficient implementation, because it has to + * call the other write method for every byte in the array. It * could be optimized for performance by doing all the processing - * in this method. - */ - for (int i = 0; i < len; i++) - write(b[off + i]); + * in this method. + */ + for (int i = 0; i < len; i++) + write(b[off + i]); } public void flush() throws IOException { - while (bufPos > 0) - writeCode(NOP); + while (bufPos > 0) + writeCode(NOP); } private void writeCode(int c) throws IOException { - buf[bufPos++] = c; - if (bufPos == 5) { // write next word when we have 5 codes - int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) | - (buf[3] << 6) | buf[4]; - out.write((pack >>> 24) & 0xFF); - out.write((pack >>> 16) & 0xFF); - out.write((pack >>> 8) & 0xFF); - out.write((pack >>> 0) & 0xFF); - bufPos = 0; - } + buf[bufPos++] = c; + if (bufPos == 5) { // write next word when we have 5 codes + int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) | + (buf[3] << 6) | buf[4]; + out.write((pack >>> 24) & 0xFF); + out.write((pack >>> 16) & 0xFF); + out.write((pack >>> 8) & 0xFF); + out.write((pack >>> 0) & 0xFF); + bufPos = 0; + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/Echo.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/Echo.java index 8a9fc44998f..03441f25a50 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/Echo.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/Echo.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java index 78cf7414adb..c156ff903e9 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,44 +33,44 @@ public class EchoImpl private static final byte[] pattern = { (byte) 'A' }; public EchoImpl(String protocol) throws RemoteException { - super(0, - new MultiSocketFactory.ClientFactory(protocol, pattern), - new MultiSocketFactory.ServerFactory(protocol, pattern)); + super(0, + new MultiSocketFactory.ClientFactory(protocol, pattern), + new MultiSocketFactory.ServerFactory(protocol, pattern)); } - + public byte[] echoNot(byte[] data) { - byte[] result = new byte[data.length]; - for (int i = 0; i < data.length; i++) - result[i] = (byte) ~data[i]; - return result; + byte[] result = new byte[data.length]; + for (int i = 0; i < data.length; i++) + result[i] = (byte) ~data[i]; + return result; } public static void main(String[] args) { - /* - * The following line is required with the JDK 1.2 VM so that the - * VM can exit gracefully when this test completes. Otherwise, the - * conservative garbage collector will find a handle to the server - * object on the native stack and not clear the weak reference to - * it in the RMI runtime's object table. - */ - Object dummy = new Object(); - - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - - try { - String protocol = ""; - if (args.length >= 1) - protocol = args[0]; + /* + * The following line is required with the JDK 1.2 VM so that the + * VM can exit gracefully when this test completes. Otherwise, the + * conservative garbage collector will find a handle to the server + * object on the native stack and not clear the weak reference to + * it in the RMI runtime's object table. + */ + Object dummy = new Object(); - System.out.println("EchoServer: creating remote object"); - EchoImpl impl = new EchoImpl(protocol); - System.out.println("EchoServer: binding in registry"); - Naming.rebind("//:" + TestLibrary.REGISTRY_PORT + - "/EchoServer", impl); - System.out.println("EchoServer ready."); - } catch (Exception e) { - System.err.println("EXCEPTION OCCURRED:"); - e.printStackTrace(); - } + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + + try { + String protocol = ""; + if (args.length >= 1) + protocol = args[0]; + + System.out.println("EchoServer: creating remote object"); + EchoImpl impl = new EchoImpl(protocol); + System.out.println("EchoServer: binding in registry"); + Naming.rebind("//:" + TestLibrary.REGISTRY_PORT + + "/EchoServer", impl); + System.out.println("EchoServer ready."); + } catch (Exception e) { + System.err.println("EXCEPTION OCCURRED:"); + e.printStackTrace(); + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl_Stub.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl_Stub.java index be15d2722d8..05e866e61d9 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl_Stub.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,38 +29,38 @@ public final class EchoImpl_Stub implements Echo, java.rmi.Remote { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_echoNot_0; - + static { - try { - $method_echoNot_0 = Echo.class.getMethod("echoNot", new java.lang.Class[] {byte[].class}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_echoNot_0 = Echo.class.getMethod("echoNot", new java.lang.Class[] {byte[].class}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public EchoImpl_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of echoNot(byte[]) public byte[] echoNot(byte[] $param_arrayOf_byte_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - Object $result = ref.invoke(this, $method_echoNot_0, new java.lang.Object[] {$param_arrayOf_byte_1}, -4295721514897591756L); - return ((byte[]) $result); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_echoNot_0, new java.lang.Object[] {$param_arrayOf_byte_1}, -4295721514897591756L); + return ((byte[]) $result); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/MultiSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/MultiSocketFactory.java index f8ef69fac1c..9ebfa3236e0 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/MultiSocketFactory.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/MultiSocketFactory.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,194 +34,193 @@ import java.util.zip.*; public class MultiSocketFactory { private static RMISocketFactory def = - RMISocketFactory.getDefaultSocketFactory(); + RMISocketFactory.getDefaultSocketFactory(); + - public static class ServerFactory - implements RMIServerSocketFactory, Serializable + implements RMIServerSocketFactory, Serializable { - private String protocol; - private byte[] data; + private String protocol; + private byte[] data; - public ServerFactory(String protocol, byte[] data) { - this.protocol = protocol; - this.data = data; - } + public ServerFactory(String protocol, byte[] data) { + this.protocol = protocol; + this.data = data; + } - public ServerSocket createServerSocket(int port) throws IOException - { - if (protocol.equals("compress")) { - return new CompressServerSocket(port); - - } else if (protocol.equals("xor")) { - if (data == null || data.length != 1) - throw new IOException("invalid argument for XOR protocol"); - return new XorServerSocket(port, data[0]); + public ServerSocket createServerSocket(int port) throws IOException + { + if (protocol.equals("compress")) { + return new CompressServerSocket(port); - } - - return def.createServerSocket(port); - } + } else if (protocol.equals("xor")) { + if (data == null || data.length != 1) + throw new IOException("invalid argument for XOR protocol"); + return new XorServerSocket(port, data[0]); + + } + + return def.createServerSocket(port); + } } public static class ClientFactory - implements RMIClientSocketFactory, Serializable + implements RMIClientSocketFactory, Serializable { - private String protocol; - private byte[] data; + private String protocol; + private byte[] data; - public ClientFactory(String protocol, byte[] data) { - this.protocol = protocol; - this.data = data; - } - - public Socket createSocket(String host, int port) - throws IOException - { - if (protocol.equals("compress")) { - return new CompressSocket(host, port); - - } else if (protocol.equals("xor")) { - if (data == null || data.length != 1) - throw new IOException("invalid argument for XOR protocol"); - return new XorSocket(host, port, data[0]); + public ClientFactory(String protocol, byte[] data) { + this.protocol = protocol; + this.data = data; + } - } + public Socket createSocket(String host, int port) + throws IOException + { + if (protocol.equals("compress")) { + return new CompressSocket(host, port); - return def.createSocket(host, port); - } + } else if (protocol.equals("xor")) { + if (data == null || data.length != 1) + throw new IOException("invalid argument for XOR protocol"); + return new XorSocket(host, port, data[0]); + + } + + return def.createSocket(host, port); + } } static class CompressSocket extends Socket { - private InputStream in; - private OutputStream out; - public CompressSocket() { super(); } - public CompressSocket(String host, int port) throws IOException { - super(host, port); - } - public InputStream getInputStream() throws IOException { - if (in == null) { - in = new CompressInputStream(super.getInputStream()); - } - return in; + private InputStream in; + private OutputStream out; + public CompressSocket() { super(); } + public CompressSocket(String host, int port) throws IOException { + super(host, port); + } + public InputStream getInputStream() throws IOException { + if (in == null) { + in = new CompressInputStream(super.getInputStream()); + } + return in; + } + public OutputStream getOutputStream() throws IOException { + if (out == null) { + out = new CompressOutputStream(super.getOutputStream()); + } + return out; } - public OutputStream getOutputStream() throws IOException { - if (out == null) { - out = new CompressOutputStream(super.getOutputStream()); - } - return out; - } } static class CompressServerSocket extends ServerSocket { - public CompressServerSocket(int port) throws IOException { - super(port); - } - public Socket accept() throws IOException { - Socket s = new CompressSocket(); - implAccept(s); - return s; - } + public CompressServerSocket(int port) throws IOException { + super(port); + } + public Socket accept() throws IOException { + Socket s = new CompressSocket(); + implAccept(s); + return s; + } } static class XorSocket extends Socket { - private byte pattern; - private InputStream in; - private OutputStream out; - public XorSocket(byte pattern) { super(); this.pattern = pattern; } - public XorSocket(String host, int port, byte pattern) - throws IOException - { - super(host, port); - this.pattern = pattern; - } - public InputStream getInputStream() throws IOException { - if (in == null) { - in = new XorInputStream(super.getInputStream(), pattern); - } - return in; + private byte pattern; + private InputStream in; + private OutputStream out; + public XorSocket(byte pattern) { super(); this.pattern = pattern; } + public XorSocket(String host, int port, byte pattern) + throws IOException + { + super(host, port); + this.pattern = pattern; + } + public InputStream getInputStream() throws IOException { + if (in == null) { + in = new XorInputStream(super.getInputStream(), pattern); + } + return in; + } + public OutputStream getOutputStream() throws IOException { + if (out == null) { + out = new XorOutputStream(super.getOutputStream(), pattern); + } + return out; } - public OutputStream getOutputStream() throws IOException { - if (out == null) { - out = new XorOutputStream(super.getOutputStream(), pattern); - } - return out; - } } static class XorServerSocket extends ServerSocket { - private byte pattern; - public XorServerSocket(int port, byte pattern) throws IOException { - super(port); - this.pattern = pattern; - } - public Socket accept() throws IOException { - Socket s = new XorSocket(pattern); - implAccept(s); - return s; - } + private byte pattern; + public XorServerSocket(int port, byte pattern) throws IOException { + super(port); + this.pattern = pattern; + } + public Socket accept() throws IOException { + Socket s = new XorSocket(pattern); + implAccept(s); + return s; + } } static class XorOutputStream extends FilterOutputStream { - private byte pattern; - public XorOutputStream(OutputStream out, byte pattern) { - super(out); - this.pattern = pattern; - } - public void write(int b) throws IOException { - out.write(b ^ pattern); - out.flush(); - } - public void write(byte b[], int off, int len) throws IOException { - for (int i = 0; i < len; i++) - write(b[off + i]); - } + private byte pattern; + public XorOutputStream(OutputStream out, byte pattern) { + super(out); + this.pattern = pattern; + } + public void write(int b) throws IOException { + out.write(b ^ pattern); + out.flush(); + } + public void write(byte b[], int off, int len) throws IOException { + for (int i = 0; i < len; i++) + write(b[off + i]); + } } static class XorInputStream extends FilterInputStream { - private byte pattern; - public XorInputStream(InputStream in, byte pattern) { - super(in); - this.pattern = pattern; - } - public int read() throws IOException { - int b = in.read(); -// System.out.print("BEFORE: " + Integer.toHexString(b)); - if (b != -1) - b = (b ^ pattern) & 0xFF; -// System.out.println("\tAFTER: " + Integer.toHexString(b)); - return b; - } - public int read(byte b[], int off, int len) throws IOException { - if (len <= 0) { - return 0; - } + private byte pattern; + public XorInputStream(InputStream in, byte pattern) { + super(in); + this.pattern = pattern; + } + public int read() throws IOException { + int b = in.read(); +// System.out.print("BEFORE: " + Integer.toHexString(b)); + if (b != -1) + b = (b ^ pattern) & 0xFF; +// System.out.println("\tAFTER: " + Integer.toHexString(b)); + return b; + } + public int read(byte b[], int off, int len) throws IOException { + if (len <= 0) { + return 0; + } - int c = read(); - if (c == -1) { - return -1; - } - b[off] = (byte)c; + int c = read(); + if (c == -1) { + return -1; + } + b[off] = (byte)c; - int i = 1; + int i = 1; /***** - try { - for (; i < len ; i++) { - c = read(); - if (c == -1) { - break; - } - if (b != null) { - b[off + i] = (byte)c; - } - } - } catch (IOException ee) { - } + try { + for (; i < len ; i++) { + c = read(); + if (c == -1) { + break; + } + if (b != null) { + b[off + i] = (byte)c; + } + } + } catch (IOException ee) { + } *****/ - return i; - } + return i; + } } } - diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java index 04e81e45083..f1b01f9b7c6 100644 --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,7 @@ * @bug 4127826 * * @summary synopsis: need to download factories for use with custom socket - * types + * types * @author Ann Wollrath * * @library ../../../../testlibrary @@ -45,77 +45,77 @@ import java.rmi.registry.*; public class UseCustomSocketFactory { public static void main(String[] args) { - - String[] protocol = new String[] { "", "compress", "xor" }; - System.out.println("\nRegression test for bug 4127826\n"); - - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + String[] protocol = new String[] { "", "compress", "xor" }; - try { - LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); - } catch (Exception e) { - TestLibrary.bomb("creating registry", e); - } + System.out.println("\nRegression test for bug 4127826\n"); - for (int i = 0; i < protocol.length; i++) { + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - System.err.println("test policy: " + - TestParams.defaultPolicy); + try { + LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); + } catch (Exception e) { + TestLibrary.bomb("creating registry", e); + } - JavaVM serverVM = new JavaVM("EchoImpl", - "-Djava.security.policy=" + - TestParams.defaultPolicy, - protocol[i]); - System.err.println("\nusing protocol: " + - (protocol[i] == "" ? "none" : protocol[i])); - - try { - /* spawn VM for EchoServer */ - serverVM.start(); + for (int i = 0; i < protocol.length; i++) { - /* lookup server */ - int tries = 8; - Echo obj = null; - do { - try { - obj = (Echo) Naming.lookup("//:" + TestLibrary.REGISTRY_PORT + - "/EchoServer"); - break; - } catch (NotBoundException e) { - try { - Thread.sleep(2000); - } catch (Exception ignore) { - } - continue; - } - } while (--tries > 0); + System.err.println("test policy: " + + TestParams.defaultPolicy); - if (obj == null) - TestLibrary.bomb("server not bound in 8 tries", null); + JavaVM serverVM = new JavaVM("EchoImpl", + "-Djava.security.policy=" + + TestParams.defaultPolicy, + protocol[i]); + System.err.println("\nusing protocol: " + + (protocol[i] == "" ? "none" : protocol[i])); - /* invoke remote method and print result*/ - System.err.println("Bound to " + obj); - byte[] data = ("Greetings, citizen " + - System.getProperty("user.name") + "!"). getBytes(); - byte[] result = obj.echoNot(data); - for (int j = 0; j < result.length; j++) - result[j] = (byte) ~result[j]; - System.err.println("Result: " + new String(result)); - - } catch (Exception e) { - TestLibrary.bomb("test failed", e); - - } finally { - serverVM.destroy(); - try { - Naming.unbind("//:" + TestLibrary.REGISTRY_PORT + - "/EchoServer"); - } catch (Exception e) { - TestLibrary.bomb("unbinding EchoServer", e); - - } - } - } + try { + /* spawn VM for EchoServer */ + serverVM.start(); + + /* lookup server */ + int tries = 8; + Echo obj = null; + do { + try { + obj = (Echo) Naming.lookup("//:" + TestLibrary.REGISTRY_PORT + + "/EchoServer"); + break; + } catch (NotBoundException e) { + try { + Thread.sleep(2000); + } catch (Exception ignore) { + } + continue; + } + } while (--tries > 0); + + if (obj == null) + TestLibrary.bomb("server not bound in 8 tries", null); + + /* invoke remote method and print result*/ + System.err.println("Bound to " + obj); + byte[] data = ("Greetings, citizen " + + System.getProperty("user.name") + "!"). getBytes(); + byte[] result = obj.echoNot(data); + for (int j = 0; j < result.length; j++) + result[j] = (byte) ~result[j]; + System.err.println("Result: " + new String(result)); + + } catch (Exception e) { + TestLibrary.bomb("test failed", e); + + } finally { + serverVM.destroy(); + try { + Naming.unbind("//:" + TestLibrary.REGISTRY_PORT + + "/EchoServer"); + } catch (Exception e) { + TestLibrary.bomb("unbinding EchoServer", e); + + } + } + } } } diff --git a/jdk/test/java/rmi/server/RemoteServer/setLogPermission/SetLogPermission.java b/jdk/test/java/rmi/server/RemoteServer/setLogPermission/SetLogPermission.java index 75ba21e3d44..5d191fe67a6 100644 --- a/jdk/test/java/rmi/server/RemoteServer/setLogPermission/SetLogPermission.java +++ b/jdk/test/java/rmi/server/RemoteServer/setLogPermission/SetLogPermission.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,7 @@ * @bug 4533390 * @summary SecurityException can be obtained but is not specified. * The RemoteServer.setLog method requires - * java.util.log.LoggingPermission("control"). + * java.util.log.LoggingPermission("control"). * @author Ann Wollrath * @run main/othervm/policy=java.policy SetLogPermission */ @@ -40,42 +40,42 @@ public class SetLogPermission { public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 4533390\n"); + System.err.println("\nRegression test for bug 4533390\n"); - if (System.getSecurityManager() == null) { - System.setSecurityManager(new SecurityManager()); - } - - CodeSource codesource = new CodeSource(null, (Certificate[]) null); - Permissions perms = null; - ProtectionDomain pd = new ProtectionDomain(codesource, perms); - AccessControlContext acc = - new AccessControlContext(new ProtectionDomain[] { pd }); - - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - try { - System.err.println( - "Attempt to set log without permission"); - RemoteServer.setLog(new ByteArrayOutputStream()); - throw new RuntimeException( - "TEST FAILED: set log without permission"); - } catch (SecurityException e) { - System.err.println( - "TEST PASSED: unable to set log without permission"); - } - return null; - }}, acc); + if (System.getSecurityManager() == null) { + System.setSecurityManager(new SecurityManager()); + } - try { - System.err.println("Attempt to set log with permission"); - RemoteServer.setLog(new ByteArrayOutputStream()); - System.err.println( - "TEST PASSED: sufficient permission to set log"); - } catch (SecurityException e) { - System.err.println("TEST FAILED: unable to set log"); - throw e; - } + CodeSource codesource = new CodeSource(null, (Certificate[]) null); + Permissions perms = null; + ProtectionDomain pd = new ProtectionDomain(codesource, perms); + AccessControlContext acc = + new AccessControlContext(new ProtectionDomain[] { pd }); + + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + try { + System.err.println( + "Attempt to set log without permission"); + RemoteServer.setLog(new ByteArrayOutputStream()); + throw new RuntimeException( + "TEST FAILED: set log without permission"); + } catch (SecurityException e) { + System.err.println( + "TEST PASSED: unable to set log without permission"); + } + return null; + }}, acc); + + try { + System.err.println("Attempt to set log with permission"); + RemoteServer.setLog(new ByteArrayOutputStream()); + System.err.println( + "TEST PASSED: sufficient permission to set log"); + } catch (SecurityException e) { + System.err.println("TEST FAILED: unable to set log"); + throw e; + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java b/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java index 0a7754a75f3..436d70a4051 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -50,40 +50,40 @@ public class ChangeHostName } public void receive(Remote obj) { - System.err.println("received: " + obj.toString()); + System.err.println("received: " + obj.toString()); } public static void main(String[] args) throws Exception { - InetAddress localAddress = InetAddress.getLocalHost(); - String[] hostlist = new String[] { - localAddress.getHostAddress(), localAddress.getHostName() }; + InetAddress localAddress = InetAddress.getLocalHost(); + String[] hostlist = new String[] { + localAddress.getHostAddress(), localAddress.getHostName() }; - for (int i = 0; i < hostlist.length; i++) { - - System.setProperty("java.rmi.server.hostname", hostlist[i]); - Remote impl = new ChangeHostName(); - System.err.println("\ncreated impl extending URO: " + impl); - - Receiver stub = (Receiver) RemoteObject.toStub(impl); - System.err.println("stub for impl: " + stub); + for (int i = 0; i < hostlist.length; i++) { - System.err.println("invoking method on stub"); - stub.receive(stub); + System.setProperty("java.rmi.server.hostname", hostlist[i]); + Remote impl = new ChangeHostName(); + System.err.println("\ncreated impl extending URO: " + impl); - UnicastRemoteObject.unexportObject(impl, true); - System.err.println("unexported impl"); + Receiver stub = (Receiver) RemoteObject.toStub(impl); + System.err.println("stub for impl: " + stub); - if (stub.toString().indexOf(hostlist[i]) >= 0) { - System.err.println("stub's ref contains hostname: " + - hostlist[i]); - } else { - throw new RuntimeException( - "TEST FAILED: stub's ref doesn't contain hostname: " + - hostlist[i]); - } - } - System.err.println("TEST PASSED"); + System.err.println("invoking method on stub"); + stub.receive(stub); + + UnicastRemoteObject.unexportObject(impl, true); + System.err.println("unexported impl"); + + if (stub.toString().indexOf(hostlist[i]) >= 0) { + System.err.println("stub's ref contains hostname: " + + hostlist[i]); + } else { + throw new RuntimeException( + "TEST FAILED: stub's ref doesn't contain hostname: " + + hostlist[i]); + } + } + System.err.println("TEST PASSED"); } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName_Stub.java b/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName_Stub.java index ff67210c4c2..f42eda7d419 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName_Stub.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,37 +29,37 @@ public final class ChangeHostName_Stub implements Receiver, java.rmi.Remote { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_receive_0; - + static { - try { - $method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public ChangeHostName_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of receive(Remote) public void receive(java.rmi.Remote $param_Remote_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java index e4a41b06f52..9ea571a41c6 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -59,83 +59,83 @@ public class KeepAliveDuringCall implements ShutdownMonitor { private boolean stillAlive = false; public void submitShutdown(Shutdown shutdown) { - synchronized (lock) { - this.shutdown = shutdown; - lock.notifyAll(); - } + synchronized (lock) { + this.shutdown = shutdown; + lock.notifyAll(); + } } public void declareStillAlive() { - synchronized (lock) { - stillAlive = true; - lock.notifyAll(); - } + synchronized (lock) { + stillAlive = true; + lock.notifyAll(); + } } public static void main(String[] args) { - System.err.println("\nRegression test for bug 4308492\n"); + System.err.println("\nRegression test for bug 4308492\n"); - KeepAliveDuringCall obj = new KeepAliveDuringCall(); + KeepAliveDuringCall obj = new KeepAliveDuringCall(); - try { - UnicastRemoteObject.exportObject(obj); - System.err.println("exported shutdown monitor"); + try { + UnicastRemoteObject.exportObject(obj); + System.err.println("exported shutdown monitor"); - Registry localRegistry = - LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); - System.err.println("created local registry"); + Registry localRegistry = + LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); + System.err.println("created local registry"); - localRegistry.bind(BINDING, obj); - System.err.println("bound shutdown monitor in local registry"); + localRegistry.bind(BINDING, obj); + System.err.println("bound shutdown monitor in local registry"); - System.err.println("starting remote ShutdownImpl VM..."); - (new JavaVM("ShutdownImpl")).start(); + System.err.println("starting remote ShutdownImpl VM..."); + (new JavaVM("ShutdownImpl")).start(); - Shutdown s; - synchronized (obj.lock) { - System.err.println( - "waiting for submission of object to shutdown..."); - while ((s = obj.shutdown) == null) { - obj.lock.wait(TIMEOUT); - } - if (s == null) { - throw new RuntimeException( - "TEST FAILED: timeout waiting for shutdown object " + - "to make initial contact"); - } - System.err.println("shutdown object submitted: " + s); - } + Shutdown s; + synchronized (obj.lock) { + System.err.println( + "waiting for submission of object to shutdown..."); + while ((s = obj.shutdown) == null) { + obj.lock.wait(TIMEOUT); + } + if (s == null) { + throw new RuntimeException( + "TEST FAILED: timeout waiting for shutdown object " + + "to make initial contact"); + } + System.err.println("shutdown object submitted: " + s); + } - try { - s.shutdown(); - } catch (RemoteException e) { - throw new RuntimeException( - "TEST FAILED: shutdown method threw remote exception", e); - } + try { + s.shutdown(); + } catch (RemoteException e) { + throw new RuntimeException( + "TEST FAILED: shutdown method threw remote exception", e); + } - synchronized (obj.lock) { - if (!obj.stillAlive) { - throw new RuntimeException("TEST FAILED: " + - "shutdown object not detected alive after unexport"); - } - } + synchronized (obj.lock) { + if (!obj.stillAlive) { + throw new RuntimeException("TEST FAILED: " + + "shutdown object not detected alive after unexport"); + } + } - System.err.println("TEST PASSED: " + - "shutdown object detected still alive after unexport"); + System.err.println("TEST PASSED: " + + "shutdown object detected still alive after unexport"); - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException( - "TEST FAILED: unexpected exception", e); - } - } finally { - try { - UnicastRemoteObject.unexportObject(obj, true); - } catch (RemoteException e) { - } - } + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException( + "TEST FAILED: unexpected exception", e); + } + } finally { + try { + UnicastRemoteObject.unexportObject(obj, true); + } catch (RemoteException e) { + } + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall_Stub.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall_Stub.java index d7ba21cdfdb..9583f53546b 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall_Stub.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,54 +29,54 @@ public final class KeepAliveDuringCall_Stub implements ShutdownMonitor { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_declareStillAlive_0; private static java.lang.reflect.Method $method_submitShutdown_1; - + static { - try { - $method_declareStillAlive_0 = ShutdownMonitor.class.getMethod("declareStillAlive", new java.lang.Class[] {}); - $method_submitShutdown_1 = ShutdownMonitor.class.getMethod("submitShutdown", new java.lang.Class[] {Shutdown.class}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_declareStillAlive_0 = ShutdownMonitor.class.getMethod("declareStillAlive", new java.lang.Class[] {}); + $method_submitShutdown_1 = ShutdownMonitor.class.getMethod("submitShutdown", new java.lang.Class[] {Shutdown.class}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public KeepAliveDuringCall_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of declareStillAlive() public void declareStillAlive() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_declareStillAlive_0, null, -1562228924246272634L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_declareStillAlive_0, null, -1562228924246272634L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of submitShutdown(Shutdown) public void submitShutdown(Shutdown $param_Shutdown_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_submitShutdown_1, new java.lang.Object[] {$param_Shutdown_1}, 7574258166120515108L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_submitShutdown_1, new java.lang.Object[] {$param_Shutdown_1}, 7574258166120515108L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/Shutdown.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/Shutdown.java index d3aa3283069..4dadbe51b2e 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/Shutdown.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/Shutdown.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java index 39952ed5f2c..32c0c118b25 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,58 +32,58 @@ import java.rmi.server.UnicastRemoteObject; public class ShutdownImpl implements Shutdown { - private static Remote impl; // rooted here to prevent GC + private static Remote impl; // rooted here to prevent GC private final ShutdownMonitor monitor; private ShutdownImpl(ShutdownMonitor monitor) { - this.monitor = monitor; + this.monitor = monitor; } public void shutdown() { - try { - System.err.println( - "(ShutdownImpl.shutdown) shutdown method invoked:"); + try { + System.err.println( + "(ShutdownImpl.shutdown) shutdown method invoked:"); - UnicastRemoteObject.unexportObject(this, true); - System.err.println( - "(ShutdownImpl.shutdown) shutdown object unexported"); + UnicastRemoteObject.unexportObject(this, true); + System.err.println( + "(ShutdownImpl.shutdown) shutdown object unexported"); - Thread.sleep(500); - System.err.println("(ShutDownImpl.shutdown) FEE"); - Thread.sleep(500); - System.err.println("(ShutDownImpl.shutdown) FIE"); - Thread.sleep(500); - System.err.println("(ShutDownImpl.shutdown) FOE"); - Thread.sleep(500); - System.err.println("(ShutDownImpl.shutdown) FOO"); + Thread.sleep(500); + System.err.println("(ShutDownImpl.shutdown) FEE"); + Thread.sleep(500); + System.err.println("(ShutDownImpl.shutdown) FIE"); + Thread.sleep(500); + System.err.println("(ShutDownImpl.shutdown) FOE"); + Thread.sleep(500); + System.err.println("(ShutDownImpl.shutdown) FOO"); - monitor.declareStillAlive(); - System.err.println("(ShutDownImpl.shutdown) still alive!"); - } catch (Exception e) { - throw new RuntimeException( - "unexpected exception occurred in shutdown method", e); - } + monitor.declareStillAlive(); + System.err.println("(ShutDownImpl.shutdown) still alive!"); + } catch (Exception e) { + throw new RuntimeException( + "unexpected exception occurred in shutdown method", e); + } } public static void main(String[] args) { - try { - Registry registry = - LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); - ShutdownMonitor monitor = (ShutdownMonitor) - registry.lookup(KeepAliveDuringCall.BINDING); - System.err.println("(ShutdownImpl) retrieved shutdown monitor"); + try { + Registry registry = + LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); + ShutdownMonitor monitor = (ShutdownMonitor) + registry.lookup(KeepAliveDuringCall.BINDING); + System.err.println("(ShutdownImpl) retrieved shutdown monitor"); - impl = new ShutdownImpl(monitor); - Shutdown stub = (Shutdown) UnicastRemoteObject.exportObject(impl); - System.err.println("(ShutdownImpl) exported shutdown object"); + impl = new ShutdownImpl(monitor); + Shutdown stub = (Shutdown) UnicastRemoteObject.exportObject(impl); + System.err.println("(ShutdownImpl) exported shutdown object"); - monitor.submitShutdown(stub); - System.err.println("(ShutdownImpl) submitted shutdown object"); + monitor.submitShutdown(stub); + System.err.println("(ShutdownImpl) submitted shutdown object"); - } catch (Exception e) { - System.err.println("(ShutdownImpl) TEST SUBPROCESS FAILURE:"); - e.printStackTrace(); - } + } catch (Exception e) { + System.err.println("(ShutdownImpl) TEST SUBPROCESS FAILURE:"); + e.printStackTrace(); + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl_Stub.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl_Stub.java index 0540a634574..97c62ca33f8 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl_Stub.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,37 +29,37 @@ public final class ShutdownImpl_Stub implements Shutdown { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_shutdown_0; - + static { - try { - $method_shutdown_0 = Shutdown.class.getMethod("shutdown", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_shutdown_0 = Shutdown.class.getMethod("shutdown", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public ShutdownImpl_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of shutdown() public void shutdown() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_shutdown_0, null, -7207851917985848402L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_shutdown_0, null, -7207851917985848402L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownMonitor.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownMonitor.java index 45c4deb0c76..29f630b1fe0 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownMonitor.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownMonitor.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java index 10536f2fe13..0fb37c62209 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -53,35 +53,35 @@ public class MarshalAfterUnexport } public static void main(String[] args) throws Exception { - Remote impl2 = null; - try { - Remote impl = new MarshalAfterUnexport(); - System.err.println("created impl extending URO: " + impl); + Remote impl2 = null; + try { + Remote impl = new MarshalAfterUnexport(); + System.err.println("created impl extending URO: " + impl); - Receiver stub = (Receiver) RemoteObject.toStub(impl); - System.err.println("stub for impl: " + stub); + Receiver stub = (Receiver) RemoteObject.toStub(impl); + System.err.println("stub for impl: " + stub); - UnicastRemoteObject.unexportObject(impl, true); - System.err.println("unexported impl"); + UnicastRemoteObject.unexportObject(impl, true); + System.err.println("unexported impl"); - impl2 = new MarshalAfterUnexport(); - Receiver stub2 = (Receiver) RemoteObject.toStub(impl2); + impl2 = new MarshalAfterUnexport(); + Receiver stub2 = (Receiver) RemoteObject.toStub(impl2); - System.err.println("marshalling unexported object:"); - MarshalledObject mobj = new MarshalledObject(impl); + System.err.println("marshalling unexported object:"); + MarshalledObject mobj = new MarshalledObject(impl); - System.err.println("passing unexported object via RMI-JRMP:"); - stub2.receive(stub); + System.err.println("passing unexported object via RMI-JRMP:"); + stub2.receive(stub); - System.err.println("TEST PASSED"); - } finally { - if (impl2 != null) { - try { - UnicastRemoteObject.unexportObject(impl2, true); - } catch (Throwable t) { - } - } - } + System.err.println("TEST PASSED"); + } finally { + if (impl2 != null) { + try { + UnicastRemoteObject.unexportObject(impl2, true); + } catch (Throwable t) { + } + } + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java index f7d1e575d66..7e8d3592872 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -49,47 +49,47 @@ public class MarshalAfterUnexport2 implements Receiver { public MarshalAfterUnexport2() throws RemoteException { - super(0, null, null); + super(0, null, null); } public void receive(Remote obj) { } public static void main(String[] args) throws Exception { - - System.err.println("\nRegression test for bug 4513223\n"); - - Remote impl2 = null; - try { - Remote impl = new MarshalAfterUnexport2(); - System.err.println( - "created impl extending URO (with a UnicastServerRef2): " + - impl); - Receiver stub = (Receiver) RemoteObject.toStub(impl); - System.err.println("stub for impl: " + stub); + System.err.println("\nRegression test for bug 4513223\n"); - UnicastRemoteObject.unexportObject(impl, true); - System.err.println("unexported impl"); + Remote impl2 = null; + try { + Remote impl = new MarshalAfterUnexport2(); + System.err.println( + "created impl extending URO (with a UnicastServerRef2): " + + impl); - impl2 = new MarshalAfterUnexport2(); - Receiver stub2 = (Receiver) RemoteObject.toStub(impl2); + Receiver stub = (Receiver) RemoteObject.toStub(impl); + System.err.println("stub for impl: " + stub); - System.err.println("marshalling unexported object:"); - MarshalledObject mobj = new MarshalledObject(impl); + UnicastRemoteObject.unexportObject(impl, true); + System.err.println("unexported impl"); - System.err.println("passing unexported object via RMI-JRMP:"); - stub2.receive(stub); + impl2 = new MarshalAfterUnexport2(); + Receiver stub2 = (Receiver) RemoteObject.toStub(impl2); - System.err.println("TEST PASSED"); - } finally { - if (impl2 != null) { - try { - UnicastRemoteObject.unexportObject(impl2, true); - } catch (Throwable t) { - } - } - } + System.err.println("marshalling unexported object:"); + MarshalledObject mobj = new MarshalledObject(impl); + + System.err.println("passing unexported object via RMI-JRMP:"); + stub2.receive(stub); + + System.err.println("TEST PASSED"); + } finally { + if (impl2 != null) { + try { + UnicastRemoteObject.unexportObject(impl2, true); + } catch (Throwable t) { + } + } + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2_Stub.java b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2_Stub.java index b122813d559..bbefd5248aa 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2_Stub.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,37 +29,37 @@ public final class MarshalAfterUnexport2_Stub implements Receiver, java.rmi.Remote { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_receive_0; - + static { - try { - $method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public MarshalAfterUnexport2_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of receive(Remote) public void receive(java.rmi.Remote $param_Remote_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport_Stub.java b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport_Stub.java index 15022b4d04e..535fffa00e1 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport_Stub.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,37 +29,37 @@ public final class MarshalAfterUnexport_Stub implements Receiver, java.rmi.Remote { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_receive_0; - + static { - try { - $method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public MarshalAfterUnexport_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of receive(Remote) public void receive(java.rmi.Remote $param_Remote_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/Ping.java b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/Ping.java index 2e88ab924cf..682915cfcf2 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/Ping.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/Ping.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,4 +26,3 @@ import java.rmi.*; public interface Ping extends Remote { public void ping() throws RemoteException; } - diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java index e40f19e50cf..de1cef78188 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,7 @@ /* @test * @bug 4331349 * @summary synopsis: unexporting doesn't guarantee that DGC will - * let go of remote object + * let go of remote object * * @author Ann Wollrath * @@ -40,36 +40,36 @@ import java.rmi.server.*; import java.rmi.registry.*; public class UnexportLeak implements Ping { - + private static int PORT = 2006; public void ping() { } public static void main(String[] args) { - try { - System.err.println("\nRegression test for bug 4331349\n"); - LocateRegistry.createRegistry(PORT); - Remote obj = new UnexportLeak(); - WeakReference wr = new WeakReference(obj); - UnicastRemoteObject.exportObject(obj); - LocateRegistry.getRegistry(PORT).rebind("UnexportLeak", obj); - UnicastRemoteObject.unexportObject(obj, true); - obj = null; - flushRefs(); - if (wr.get() != null) { - System.err.println("FAILED: unexported object not collected"); - throw new RuntimeException( - "FAILED: unexported object not collected"); - } else { - System.err.println("PASSED: unexported object collected"); - } - } catch (RemoteException e) { - System.err.println( - "FAILED: RemoteException encountered: " + e.getMessage()); - e.printStackTrace(); - throw new RuntimeException("FAILED: RemoteException encountered"); - } + try { + System.err.println("\nRegression test for bug 4331349\n"); + LocateRegistry.createRegistry(PORT); + Remote obj = new UnexportLeak(); + WeakReference wr = new WeakReference(obj); + UnicastRemoteObject.exportObject(obj); + LocateRegistry.getRegistry(PORT).rebind("UnexportLeak", obj); + UnicastRemoteObject.unexportObject(obj, true); + obj = null; + flushRefs(); + if (wr.get() != null) { + System.err.println("FAILED: unexported object not collected"); + throw new RuntimeException( + "FAILED: unexported object not collected"); + } else { + System.err.println("PASSED: unexported object collected"); + } + } catch (RemoteException e) { + System.err.println( + "FAILED: RemoteException encountered: " + e.getMessage()); + e.printStackTrace(); + throw new RuntimeException("FAILED: RemoteException encountered"); + } } /** @@ -77,15 +77,13 @@ public class UnexportLeak implements Ping { * will be cleared. */ private static void flushRefs() { - java.util.Vector chain = new java.util.Vector(); - try { - while (true) { - int[] hungry = new int[65536]; - chain.addElement(hungry); - } - } catch (OutOfMemoryError e) { - } + java.util.Vector chain = new java.util.Vector(); + try { + while (true) { + int[] hungry = new int[65536]; + chain.addElement(hungry); + } + } catch (OutOfMemoryError e) { + } } } - - diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak_Stub.java b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak_Stub.java index 1f7ab308c20..56102aa54fe 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak_Stub.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,37 +29,37 @@ public final class UnexportLeak_Stub implements Ping { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_ping_0; - + static { - try { - $method_ping_0 = Ping.class.getMethod("ping", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_ping_0 = Ping.class.getMethod("ping", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public UnexportLeak_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of ping() public void ping() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - ref.invoke(this, $method_ping_0, null, 5866401369815527589L); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + ref.invoke(this, $method_ping_0, null, 5866401369815527589L); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies.java b/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies.java index bec4e954f80..62b0ae9339b 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -43,75 +43,75 @@ public class UseDynamicProxies implements RemoteInterface { public Object passObject(Object obj) { - return obj; + return obj; } public int passInt(int x) { - return x; + return x; } public String passString(String string) { - return string; + return string; } public static void main(String[] args) throws Exception { - - RemoteInterface server = null; - RemoteInterface proxy = null; - - try { - System.setProperty("java.rmi.server.ignoreStubClasses", args[0]); - boolean ignoreStubClasses = Boolean.parseBoolean(args[0]); - if (System.getSecurityManager() == null) { - System.setSecurityManager(new SecurityManager()); - } + RemoteInterface server = null; + RemoteInterface proxy = null; - System.err.println("export object"); - server = new UseDynamicProxies(); - proxy = - (RemoteInterface) UnicastRemoteObject.exportObject(server, 0); + try { + System.setProperty("java.rmi.server.ignoreStubClasses", args[0]); + boolean ignoreStubClasses = Boolean.parseBoolean(args[0]); - System.err.println("proxy = " + proxy); - if (ignoreStubClasses) { - if (!Proxy.isProxyClass(proxy.getClass())) { - throw new RuntimeException( - "server proxy is not a dynamic proxy"); - } - if (!(Proxy.getInvocationHandler(proxy) instanceof - RemoteObjectInvocationHandler)) - { - throw new RuntimeException("invalid invocation handler"); - } - - } else if (!(proxy instanceof RemoteStub)) { - throw new RuntimeException( - "server proxy is not a RemoteStub"); - } + if (System.getSecurityManager() == null) { + System.setSecurityManager(new SecurityManager()); + } - System.err.println("invoke methods"); - Object obj = proxy.passObject(proxy); - if (!proxy.equals(obj)) { - throw new RuntimeException("returned proxy not equal"); - } + System.err.println("export object"); + server = new UseDynamicProxies(); + proxy = + (RemoteInterface) UnicastRemoteObject.exportObject(server, 0); - int x = proxy.passInt(53); - if (x != 53) { - throw new RuntimeException("returned int not equal"); - } + System.err.println("proxy = " + proxy); + if (ignoreStubClasses) { + if (!Proxy.isProxyClass(proxy.getClass())) { + throw new RuntimeException( + "server proxy is not a dynamic proxy"); + } + if (!(Proxy.getInvocationHandler(proxy) instanceof + RemoteObjectInvocationHandler)) + { + throw new RuntimeException("invalid invocation handler"); + } - String string = proxy.passString("test"); - if (!string.equals("test")) { - throw new RuntimeException("returned string not equal"); - } - - System.err.println("TEST PASSED"); - - } finally { - if (proxy != null) { - UnicastRemoteObject.unexportObject(server, true); - } - } + } else if (!(proxy instanceof RemoteStub)) { + throw new RuntimeException( + "server proxy is not a RemoteStub"); + } + + System.err.println("invoke methods"); + Object obj = proxy.passObject(proxy); + if (!proxy.equals(obj)) { + throw new RuntimeException("returned proxy not equal"); + } + + int x = proxy.passInt(53); + if (x != 53) { + throw new RuntimeException("returned int not equal"); + } + + String string = proxy.passString("test"); + if (!string.equals("test")) { + throw new RuntimeException("returned string not equal"); + } + + System.err.println("TEST PASSED"); + + } finally { + if (proxy != null) { + UnicastRemoteObject.unexportObject(server, true); + } + } } } diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies_Stub.java b/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies_Stub.java index 549c2396ab8..b567c29ebd6 100644 --- a/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies_Stub.java +++ b/jdk/test/java/rmi/server/UnicastRemoteObject/useDynamicProxies/UseDynamicProxies_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,74 +29,74 @@ public final class UseDynamicProxies_Stub implements RemoteInterface { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_passInt_0; private static java.lang.reflect.Method $method_passObject_1; private static java.lang.reflect.Method $method_passString_2; - + static { - try { - $method_passInt_0 = RemoteInterface.class.getMethod("passInt", new java.lang.Class[] {int.class}); - $method_passObject_1 = RemoteInterface.class.getMethod("passObject", new java.lang.Class[] {java.lang.Object.class}); - $method_passString_2 = RemoteInterface.class.getMethod("passString", new java.lang.Class[] {java.lang.String.class}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_passInt_0 = RemoteInterface.class.getMethod("passInt", new java.lang.Class[] {int.class}); + $method_passObject_1 = RemoteInterface.class.getMethod("passObject", new java.lang.Class[] {java.lang.Object.class}); + $method_passString_2 = RemoteInterface.class.getMethod("passString", new java.lang.Class[] {java.lang.String.class}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public UseDynamicProxies_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of passInt(int) public int passInt(int $param_int_1) - throws java.io.IOException + throws java.io.IOException { - try { - Object $result = ref.invoke(this, $method_passInt_0, new java.lang.Object[] {new java.lang.Integer($param_int_1)}, 8655249712495061761L); - return ((java.lang.Integer) $result).intValue(); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.io.IOException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_passInt_0, new java.lang.Object[] {new java.lang.Integer($param_int_1)}, 8655249712495061761L); + return ((java.lang.Integer) $result).intValue(); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.io.IOException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of passObject(Object) public java.lang.Object passObject(java.lang.Object $param_Object_1) - throws java.io.IOException + throws java.io.IOException { - try { - Object $result = ref.invoke(this, $method_passObject_1, new java.lang.Object[] {$param_Object_1}, 3074202549763602823L); - return ((java.lang.Object) $result); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.io.IOException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_passObject_1, new java.lang.Object[] {$param_Object_1}, 3074202549763602823L); + return ((java.lang.Object) $result); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.io.IOException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of passString(String) public java.lang.String passString(java.lang.String $param_String_1) - throws java.io.IOException + throws java.io.IOException { - try { - Object $result = ref.invoke(this, $method_passString_2, new java.lang.Object[] {$param_String_1}, 6627880292288702000L); - return ((java.lang.String) $result); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.io.IOException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_passString_2, new java.lang.Object[] {$param_String_1}, 6627880292288702000L); + return ((java.lang.String) $result); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.io.IOException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java index e4634841305..a12af61e4d7 100644 --- a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java +++ b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -22,7 +22,7 @@ */ /* @test - * @bug 4118600 + * @bug 4118600 * @summary RMI UnmarshallException, interaction on stopping a thread. * * @bug 4177704 @@ -35,7 +35,7 @@ * @build CheckUnmarshall PoisonPill RuntimeExceptionParameter * @build CheckUnmarshalOnStopThread * @build CheckUnmarshalOnStopThread_Stub - * @run main/othervm/timeout=480 CheckUnmarshalOnStopThread + * @run main/othervm/timeout=480 CheckUnmarshalOnStopThread */ import java.rmi.*; @@ -44,7 +44,7 @@ import java.io.*; import java.rmi.registry.*; /** - * Description for 4118600: + * Description for 4118600: * * If an rmi call thread is stopped while unmarshalling a return * value), java.lang.ThreadDeath will be thrown during @@ -77,8 +77,8 @@ import java.rmi.registry.*; * occur. This test is only written to track UnmarshalExceptions; * success/failure does not depend on other types of problems. * - * Description for 4177704: - * + * Description for 4177704: + * * Similar situation as for 4177704 except that instead of just * ensuring that RMI properly handles Errors, the second part of the * test ensures that RMI deals with RuntimeExceptions correctly. @@ -88,110 +88,110 @@ import java.rmi.registry.*; * parameters. An object that throws a RuntimeException in its * writeObject method helps to carry out this part of the test. */ -public class CheckUnmarshalOnStopThread - extends UnicastRemoteObject - implements CheckUnmarshal +public class CheckUnmarshalOnStopThread + extends UnicastRemoteObject + implements CheckUnmarshal { final static int RUNTIME_PILL = 1; public static int typeToThrow = 0; /* - * remote object implementation + * remote object implementation */ CheckUnmarshalOnStopThread() throws RemoteException { } public PoisonPill getPoisonPill() throws RemoteException { - return new PoisonPill(new Integer(0)); + return new PoisonPill(new Integer(0)); } public Object ping() throws RemoteException { - return (Object) new Integer(0); + return (Object) new Integer(0); } public void passRuntimeExceptionParameter( - RuntimeExceptionParameter rep) throws RemoteException + RuntimeExceptionParameter rep) throws RemoteException { - // will never be called + // will never be called } public static void main(String [] args) { - Object dummy = new Object(); - CheckUnmarshal cu = null; - CheckUnmarshalOnStopThread cuonst = null; + Object dummy = new Object(); + CheckUnmarshal cu = null; + CheckUnmarshalOnStopThread cuonst = null; - System.err.println("\nregression test for bugs: " + - "4118600 and 4177704\n"); + System.err.println("\nregression test for bugs: " + + "4118600 and 4177704\n"); - try { - cuonst = new CheckUnmarshalOnStopThread(); - cu = (CheckUnmarshal) UnicastRemoteObject.toStub(cuonst); + try { + cuonst = new CheckUnmarshalOnStopThread(); + cu = (CheckUnmarshal) UnicastRemoteObject.toStub(cuonst); - // make sure that RMI will free connections appropriately - // under several situations: + // make sure that RMI will free connections appropriately + // under several situations: - // when Errors are thrown during parameter unmarshalling - System.err.println("testing to see if RMI will handle errors"); - ensureConnectionsAreFreed(cu, true); + // when Errors are thrown during parameter unmarshalling + System.err.println("testing to see if RMI will handle errors"); + ensureConnectionsAreFreed(cu, true); - // when RuntimeExceptions are thrown during parameter unmarshalling - System.err.println("testing to see if RMI will handle " + - "runtime exceptions"); - typeToThrow = RUNTIME_PILL; - ensureConnectionsAreFreed(cu, true); + // when RuntimeExceptions are thrown during parameter unmarshalling + System.err.println("testing to see if RMI will handle " + + "runtime exceptions"); + typeToThrow = RUNTIME_PILL; + ensureConnectionsAreFreed(cu, true); - // when RuntimeExceptions are thrown during parameter marshalling - System.err.println("testing to see if RMI will handle " + - "runtime exceptions thrown during " + - "parameter marshalling"); - ensureConnectionsAreFreed(cu, false); + // when RuntimeExceptions are thrown during parameter marshalling + System.err.println("testing to see if RMI will handle " + + "runtime exceptions thrown during " + + "parameter marshalling"); + ensureConnectionsAreFreed(cu, false); - System.err.println - ("\nsuccess: CheckUnmarshalOnStopThread test passed "); + System.err.println + ("\nsuccess: CheckUnmarshalOnStopThread test passed "); - } catch (Exception e) { - TestLibrary.bomb(e); - } finally { - cu = null; - deactivate(cuonst); - } + } catch (Exception e) { + TestLibrary.bomb(e); + } finally { + cu = null; + deactivate(cuonst); + } } - - static void ensureConnectionsAreFreed(CheckUnmarshal cu, boolean getPill) - throws Exception + + static void ensureConnectionsAreFreed(CheckUnmarshal cu, boolean getPill) + throws Exception { - // invoke a remote call that will corrupt a call connection - // that will not be freed (if the bug is not fixed) + // invoke a remote call that will corrupt a call connection + // that will not be freed (if the bug is not fixed) - for (int i = 0 ; i < 250 ; i++) { - try { - Object test = cu.ping(); - if (getPill) { - cu.getPoisonPill(); - } else { - cu.passRuntimeExceptionParameter( - new RuntimeExceptionParameter()); - } - } catch (Error e) { - // expect an Error from call unmarshalling, ignore it - } catch (RuntimeException e) { - // " RuntimeException " - } - } + for (int i = 0 ; i < 250 ; i++) { + try { + Object test = cu.ping(); + if (getPill) { + cu.getPoisonPill(); + } else { + cu.passRuntimeExceptionParameter( + new RuntimeExceptionParameter()); + } + } catch (Error e) { + // expect an Error from call unmarshalling, ignore it + } catch (RuntimeException e) { + // " RuntimeException " + } + } - System.err.println("remote calls passed, received no " + - "unmarshal exceptions\n\n"); + System.err.println("remote calls passed, received no " + + "unmarshal exceptions\n\n"); } static void deactivate(RemoteServer r) { - // make sure that the object goes away - try { - System.err.println("deactivating object."); - UnicastRemoteObject.unexportObject(r, true); - } catch (Exception e) { - e.getMessage(); - e.printStackTrace(); - } + // make sure that the object goes away + try { + System.err.println("deactivating object."); + UnicastRemoteObject.unexportObject(r, true); + } catch (Exception e) { + e.getMessage(); + e.printStackTrace(); + } } } diff --git a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread_Stub.java b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread_Stub.java index 1fa93b17883..612fe5db494 100644 --- a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread_Stub.java +++ b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,138 +29,138 @@ public final class CheckUnmarshalOnStopThread_Stub implements CheckUnmarshal, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("PoisonPill getPoisonPill()"), - new java.rmi.server.Operation("void passRuntimeExceptionParameter(RuntimeExceptionParameter)"), - new java.rmi.server.Operation("java.lang.Object ping()") + new java.rmi.server.Operation("PoisonPill getPoisonPill()"), + new java.rmi.server.Operation("void passRuntimeExceptionParameter(RuntimeExceptionParameter)"), + new java.rmi.server.Operation("java.lang.Object ping()") }; - + private static final long interfaceHash = -5923540687975666490L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_getPoisonPill_0; private static java.lang.reflect.Method $method_passRuntimeExceptionParameter_1; private static java.lang.reflect.Method $method_ping_2; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_getPoisonPill_0 = CheckUnmarshal.class.getMethod("getPoisonPill", new java.lang.Class[] {}); - $method_passRuntimeExceptionParameter_1 = CheckUnmarshal.class.getMethod("passRuntimeExceptionParameter", new java.lang.Class[] {RuntimeExceptionParameter.class}); - $method_ping_2 = CheckUnmarshal.class.getMethod("ping", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_getPoisonPill_0 = CheckUnmarshal.class.getMethod("getPoisonPill", new java.lang.Class[] {}); + $method_passRuntimeExceptionParameter_1 = CheckUnmarshal.class.getMethod("passRuntimeExceptionParameter", new java.lang.Class[] {RuntimeExceptionParameter.class}); + $method_ping_2 = CheckUnmarshal.class.getMethod("ping", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public CheckUnmarshalOnStopThread_Stub() { - super(); + super(); } public CheckUnmarshalOnStopThread_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of getPoisonPill() public PoisonPill getPoisonPill() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getPoisonPill_0, null, 5776441251039617360L); - return ((PoisonPill) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - PoisonPill $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (PoisonPill) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getPoisonPill_0, null, 5776441251039617360L); + return ((PoisonPill) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + PoisonPill $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (PoisonPill) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of passRuntimeExceptionParameter(RuntimeExceptionParameter) public void passRuntimeExceptionParameter(RuntimeExceptionParameter $param_RuntimeExceptionParameter_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_passRuntimeExceptionParameter_1, new java.lang.Object[] {$param_RuntimeExceptionParameter_1}, -4427599990679364365L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_RuntimeExceptionParameter_1); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_passRuntimeExceptionParameter_1, new java.lang.Object[] {$param_RuntimeExceptionParameter_1}, -4427599990679364365L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_RuntimeExceptionParameter_1); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of ping() public java.lang.Object ping() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_ping_2, null, 7635508643486276040L); - return ((java.lang.Object) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); - ref.invoke(call); - java.lang.Object $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.lang.Object) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_ping_2, null, 7635508643486276040L); + return ((java.lang.Object) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash); + ref.invoke(call); + java.lang.Object $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.Object) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshall.java b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshall.java index b1156581976..327081c9d8a 100644 --- a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshall.java +++ b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshall.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -20,7 +20,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ - + /** * */ @@ -37,4 +37,3 @@ import java.rmi.RemoteException; RuntimeExceptionParameter rep) throws RemoteException; } - diff --git a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/PoisonPill.java b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/PoisonPill.java index f9c488797af..3c885926c1f 100644 --- a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/PoisonPill.java +++ b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/PoisonPill.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -45,7 +45,7 @@ public class PoisonPill implements Serializable { throws IOException { if (CheckUnmarshalOnStopThread.typeToThrow != - CheckUnmarshalOnStopThread.RUNTIME_PILL) { + CheckUnmarshalOnStopThread.RUNTIME_PILL) { throw new Error("Wrote a test object whos readObject " + "method always throws an Error"); diff --git a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/RuntimeExceptionParameter.java b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/RuntimeExceptionParameter.java index efaaee82657..8d8f5e94c17 100644 --- a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/RuntimeExceptionParameter.java +++ b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/RuntimeExceptionParameter.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -38,7 +38,6 @@ class RuntimeExceptionParameter implements Serializable { { throw new RuntimeException("wrote a parameter whos writeObject " + "method always throws a RuntimeException" - ); + ); } } - diff --git a/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java b/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java index b171c827024..05f30142bee 100644 --- a/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java +++ b/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -54,69 +54,69 @@ public class FiniteGCLatency implements Remote, Unreferenced { private boolean unreferencedInvoked = false; public void unreferenced() { - System.err.println("unreferenced() method invoked"); - synchronized (lock) { - unreferencedInvoked = true; - lock.notify(); - } + System.err.println("unreferenced() method invoked"); + synchronized (lock) { + unreferencedInvoked = true; + lock.notify(); + } } public static void main(String[] args) { - System.err.println("\nRegression test for bug 4164696\n"); + System.err.println("\nRegression test for bug 4164696\n"); - /* - * Set the interval that RMI will request for GC latency (before RMI - * gets initialized and this property is read) to an unrealistically - * small value, so that this test shouldn't have to wait too long. - */ - System.setProperty("sun.rmi.dgc.client.gcInterval", - String.valueOf(GC_INTERVAL)); + /* + * Set the interval that RMI will request for GC latency (before RMI + * gets initialized and this property is read) to an unrealistically + * small value, so that this test shouldn't have to wait too long. + */ + System.setProperty("sun.rmi.dgc.client.gcInterval", + String.valueOf(GC_INTERVAL)); - FiniteGCLatency obj = new FiniteGCLatency(); + FiniteGCLatency obj = new FiniteGCLatency(); - try { - UnicastRemoteObject.exportObject(obj); - System.err.println("exported remote object"); + try { + UnicastRemoteObject.exportObject(obj); + System.err.println("exported remote object"); - LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); - System.err.println("created registry"); + LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); + System.err.println("created registry"); - Registry registry = LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); - registry.bind(BINDING, obj); - System.err.println("bound remote object in registry"); + Registry registry = LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); + registry.bind(BINDING, obj); + System.err.println("bound remote object in registry"); - synchronized (obj.lock) { - registry.unbind(BINDING); - System.err.println("unbound remote object from registry; " + - "waiting for unreferenced() callback..."); - obj.lock.wait(TIMEOUT); + synchronized (obj.lock) { + registry.unbind(BINDING); + System.err.println("unbound remote object from registry; " + + "waiting for unreferenced() callback..."); + obj.lock.wait(TIMEOUT); - if (obj.unreferencedInvoked) { - System.err.println("TEST PASSED: unreferenced() invoked"); - } else { - throw new RuntimeException( - "TEST FAILED: unrefereced() not invoked after " + - ((double) TIMEOUT / 1000.0) + " seconds"); - } - } + if (obj.unreferencedInvoked) { + System.err.println("TEST PASSED: unreferenced() invoked"); + } else { + throw new RuntimeException( + "TEST FAILED: unrefereced() not invoked after " + + ((double) TIMEOUT / 1000.0) + " seconds"); + } + } - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException( - "TEST FAILED: unexpected exception: " + e.toString()); - } - } finally { - /* - * When all is said and done, try to unexport the remote object - * so that the VM has a chance to exit. - */ - try { - UnicastRemoteObject.unexportObject(obj, true); - } catch (RemoteException e) { - } - } + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException( + "TEST FAILED: unexpected exception: " + e.toString()); + } + } finally { + /* + * When all is said and done, try to unexport the remote object + * so that the VM has a chance to exit. + */ + try { + UnicastRemoteObject.unexportObject(obj, true); + } catch (RemoteException e) { + } + } } } diff --git a/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency_Stub.java b/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency_Stub.java index 4acb848188d..97c275b4fd0 100644 --- a/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency_Stub.java +++ b/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,10 +29,10 @@ public final class FiniteGCLatency_Stub implements java.rmi.Remote { private static final long serialVersionUID = 2; - + // constructors public FiniteGCLatency_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + } diff --git a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java index 4458b3c5a05..6687b9202a8 100644 --- a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java +++ b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -62,71 +62,71 @@ public class LeaseCheckInterval implements Remote, Unreferenced { private boolean unreferencedInvoked = false; public void unreferenced() { - System.err.println("unreferenced() method invoked"); - synchronized (lock) { - unreferencedInvoked = true; - lock.notify(); - } + System.err.println("unreferenced() method invoked"); + synchronized (lock) { + unreferencedInvoked = true; + lock.notify(); + } } public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 4285878\n"); + System.err.println("\nRegression test for bug 4285878\n"); - /* - * Set the duration of leases granted to a very small value, so that - * we can test if expirations are detected in a roughly comparable - * time. - */ - System.setProperty("java.rmi.dgc.leaseValue", - String.valueOf(LEASE_VALUE)); + /* + * Set the duration of leases granted to a very small value, so that + * we can test if expirations are detected in a roughly comparable + * time. + */ + System.setProperty("java.rmi.dgc.leaseValue", + String.valueOf(LEASE_VALUE)); - LeaseCheckInterval obj = new LeaseCheckInterval(); + LeaseCheckInterval obj = new LeaseCheckInterval(); - try { - UnicastRemoteObject.exportObject(obj); - System.err.println("exported remote object"); + try { + UnicastRemoteObject.exportObject(obj); + System.err.println("exported remote object"); - Registry localRegistry = - LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); - System.err.println("created local registry"); + Registry localRegistry = + LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); + System.err.println("created local registry"); - localRegistry.bind(BINDING, obj); - System.err.println("bound remote object in local registry"); + localRegistry.bind(BINDING, obj); + System.err.println("bound remote object in local registry"); - synchronized (obj.lock) { - System.err.println("starting remote client VM..."); - (new JavaVM("SelfTerminator")).start(); + synchronized (obj.lock) { + System.err.println("starting remote client VM..."); + (new JavaVM("SelfTerminator")).start(); - System.err.println("waiting for unreferenced() callback..."); - obj.lock.wait(TIMEOUT); + System.err.println("waiting for unreferenced() callback..."); + obj.lock.wait(TIMEOUT); - if (obj.unreferencedInvoked) { - System.err.println("TEST PASSED: " + - "unreferenced() invoked in timely fashion"); - } else { - throw new RuntimeException( - "TEST FAILED: unreferenced() not invoked after " + - ((double) TIMEOUT / 1000.0) + " seconds"); - } - } + if (obj.unreferencedInvoked) { + System.err.println("TEST PASSED: " + + "unreferenced() invoked in timely fashion"); + } else { + throw new RuntimeException( + "TEST FAILED: unreferenced() not invoked after " + + ((double) TIMEOUT / 1000.0) + " seconds"); + } + } - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException( - "TEST FAILED: unexpected exception: " + e.toString()); - } - } finally { - /* - * When all is said and done, try to unexport the remote object - * so that the VM has a chance to exit. - */ - try { - UnicastRemoteObject.unexportObject(obj, true); - } catch (RemoteException e) { - } - } + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException( + "TEST FAILED: unexpected exception: " + e.toString()); + } + } finally { + /* + * When all is said and done, try to unexport the remote object + * so that the VM has a chance to exit. + */ + try { + UnicastRemoteObject.unexportObject(obj, true); + } catch (RemoteException e) { + } + } } } diff --git a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval_Stub.java b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval_Stub.java index 5f258fbfb40..950e30982a3 100644 --- a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval_Stub.java +++ b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,10 +29,10 @@ public final class LeaseCheckInterval_Stub implements java.rmi.Remote { private static final long serialVersionUID = 2; - + // constructors public LeaseCheckInterval_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + } diff --git a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java index 98d632fbca1..65e65f3e0b3 100644 --- a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java +++ b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,13 +32,13 @@ import java.rmi.registry.Registry; public class SelfTerminator { public static void main(String[] args) { - try { - Registry registry = - LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); - Remote stub = registry.lookup(LeaseCheckInterval.BINDING); - Runtime.getRuntime().halt(0); - } catch (Exception e) { - e.printStackTrace(); - } + try { + Registry registry = + LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); + Remote stub = registry.lookup(LeaseCheckInterval.BINDING); + Runtime.getRuntime().halt(0); + } catch (Exception e) { + e.printStackTrace(); + } } } diff --git a/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java b/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java index 2b918b6ea7b..ea3a25d2945 100644 --- a/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java +++ b/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -51,72 +51,72 @@ public class MarshalledObjectGet implements Remote, Unreferenced { private boolean unreferencedInvoked; public void unreferenced() { - System.err.println("unreferenced() method invoked"); - synchronized (lock) { - unreferencedInvoked = true; - lock.notify(); - } + System.err.println("unreferenced() method invoked"); + synchronized (lock) { + unreferencedInvoked = true; + lock.notify(); + } } public static void main(String[] args) { - System.err.println( - "\nTest to verify correction interaction of " + - "MarshalledObject.get and DGC registration\n"); + System.err.println( + "\nTest to verify correction interaction of " + + "MarshalledObject.get and DGC registration\n"); - /* - * Set the interval that RMI will request for GC latency (before RMI - * gets initialized and this property is read) to an unrealistically - * small value, so that this test shouldn't have to wait too long. - */ - System.setProperty("sun.rmi.dgc.client.gcInterval", - String.valueOf(GC_INTERVAL)); + /* + * Set the interval that RMI will request for GC latency (before RMI + * gets initialized and this property is read) to an unrealistically + * small value, so that this test shouldn't have to wait too long. + */ + System.setProperty("sun.rmi.dgc.client.gcInterval", + String.valueOf(GC_INTERVAL)); - MarshalledObjectGet obj = new MarshalledObjectGet(); + MarshalledObjectGet obj = new MarshalledObjectGet(); - try { - Remote stub = UnicastRemoteObject.exportObject(obj); - System.err.println("exported remote object"); + try { + Remote stub = UnicastRemoteObject.exportObject(obj); + System.err.println("exported remote object"); - MarshalledObject mobj = new MarshalledObject(stub); - Remote unmarshalledStub = (Remote) mobj.get(); - System.err.println("unmarshalled stub from marshalled object"); + MarshalledObject mobj = new MarshalledObject(stub); + Remote unmarshalledStub = (Remote) mobj.get(); + System.err.println("unmarshalled stub from marshalled object"); - synchronized (obj.lock) { - obj.unreferencedInvoked = false; + synchronized (obj.lock) { + obj.unreferencedInvoked = false; - unmarshalledStub = null; - System.gc(); - System.err.println("cleared unmarshalled stub"); - System.err.println("waiting for unreferenced() callback " + - "(SHOULD happen)..."); - obj.lock.wait(TIMEOUT); + unmarshalledStub = null; + System.gc(); + System.err.println("cleared unmarshalled stub"); + System.err.println("waiting for unreferenced() callback " + + "(SHOULD happen)..."); + obj.lock.wait(TIMEOUT); - if (obj.unreferencedInvoked) { - // TEST PASSED - } else { - throw new RuntimeException( - "TEST FAILED: unrefereced() not invoked after " + - ((double) TIMEOUT / 1000.0) + " seconds"); - } - } + if (obj.unreferencedInvoked) { + // TEST PASSED + } else { + throw new RuntimeException( + "TEST FAILED: unrefereced() not invoked after " + + ((double) TIMEOUT / 1000.0) + " seconds"); + } + } - System.err.println("TEST PASSED"); + System.err.println("TEST PASSED"); - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException( - "TEST FAILED: unexpected exception: " + e.toString()); - } - } finally { - if (obj != null) { - try { - UnicastRemoteObject.unexportObject(obj, true); - } catch (Exception e) { - } - } - } + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException( + "TEST FAILED: unexpected exception: " + e.toString()); + } + } finally { + if (obj != null) { + try { + UnicastRemoteObject.unexportObject(obj, true); + } catch (Exception e) { + } + } + } } } diff --git a/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet_Stub.java b/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet_Stub.java index e6bbe1fa5b6..55189cad77a 100644 --- a/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet_Stub.java +++ b/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,10 +29,10 @@ public final class MarshalledObjectGet_Stub implements java.rmi.Remote { private static final long serialVersionUID = 2; - + // constructors public MarshalledObjectGet_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + } diff --git a/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java b/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java index f9566c0245e..eafb5e041a0 100644 --- a/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java +++ b/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,12 +32,12 @@ * * @bug 4214123 * @summary Unreferenced.unreferenced(...) threads should run in the nonSystem group. - * To complete the fix for, 4182104, RMI unreferenced threads should also + * To complete the fix for, 4182104, RMI unreferenced threads should also * run in the nonSystem so that they do not need permissions to modify the * system thread group. * * @author Laird Dornin - * + * * @library ../../../testlibrary * @build UnreferencedContext * @build UnreferencedContext_Stub @@ -60,127 +60,127 @@ public class UnreferencedContext implements Remote, Unreferenced, Runnable { private ClassLoader unreferencedContext; public void run() { - System.err.println("unreferenced method created thread succesfully"); + System.err.println("unreferenced method created thread succesfully"); } public void unreferenced() { - // turn on security to ensure that the action below will not - // require extra permissions - System.setSecurityManager(new java.rmi.RMISecurityManager()); + // turn on security to ensure that the action below will not + // require extra permissions + System.setSecurityManager(new java.rmi.RMISecurityManager()); - // exercise functionality prohibited by 4214123 - (new Thread(this)).start(); + // exercise functionality prohibited by 4214123 + (new Thread(this)).start(); - System.err.println("unreferenced() method invoked"); - synchronized (lock) { - unreferencedInvoked = true; - unreferencedContext = - Thread.currentThread().getContextClassLoader(); - lock.notify(); - } + System.err.println("unreferenced() method invoked"); + synchronized (lock) { + unreferencedInvoked = true; + unreferencedContext = + Thread.currentThread().getContextClassLoader(); + lock.notify(); + } } public static void main(String[] args) { - System.err.println("\nRegression test for bug 4171278\n"); + System.err.println("\nRegression test for bug 4171278\n"); - /* - * Set the interval that RMI will request for GC latency (before RMI - * gets initialized and this property is read) to an unrealistically - * small value, so that this test shouldn't have to wait too long. - */ - System.setProperty("sun.rmi.dgc.client.gcInterval", - String.valueOf(GC_INTERVAL)); + /* + * Set the interval that RMI will request for GC latency (before RMI + * gets initialized and this property is read) to an unrealistically + * small value, so that this test shouldn't have to wait too long. + */ + System.setProperty("sun.rmi.dgc.client.gcInterval", + String.valueOf(GC_INTERVAL)); - UnreferencedContext obj = new UnreferencedContext(); + UnreferencedContext obj = new UnreferencedContext(); - try { - /* - * This little trick is necessary to make sure that the RMI server - * threads for objects created on the default port get created - * before we set our special context class loader, so that they - * don't *accidentally* inherit it when making the unreferenced() - * callback. - */ - UnicastRemoteObject.exportObject(obj); - UnicastRemoteObject.unexportObject(obj, true); + try { + /* + * This little trick is necessary to make sure that the RMI server + * threads for objects created on the default port get created + * before we set our special context class loader, so that they + * don't *accidentally* inherit it when making the unreferenced() + * callback. + */ + UnicastRemoteObject.exportObject(obj); + UnicastRemoteObject.unexportObject(obj, true); - /* - * Now create special context class loader before exporting the - * remote object for real, so that it should be set when the - * object's unreferenced() method is called. - */ - ClassLoader intendedContext = new URLClassLoader(new URL[0]); - Thread.currentThread().setContextClassLoader(intendedContext); - System.err.println( - "created and set intended context class loader: " + - intendedContext); + /* + * Now create special context class loader before exporting the + * remote object for real, so that it should be set when the + * object's unreferenced() method is called. + */ + ClassLoader intendedContext = new URLClassLoader(new URL[0]); + Thread.currentThread().setContextClassLoader(intendedContext); + System.err.println( + "created and set intended context class loader: " + + intendedContext); - UnicastRemoteObject.exportObject(obj); - System.err.println("exported remote object"); + UnicastRemoteObject.exportObject(obj); + System.err.println("exported remote object"); - LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); - System.err.println("created registry"); + LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); + System.err.println("created registry"); - Registry registry = LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); - registry.bind(BINDING, obj); - System.err.println("bound remote object in registry"); + Registry registry = LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); + registry.bind(BINDING, obj); + System.err.println("bound remote object in registry"); - synchronized (obj.lock) { - registry.unbind(BINDING); - System.err.println("unbound remote object from registry; " + - "waiting for unreferenced() callback..."); - /* - * This incantation seems sufficient to work around the - * ramifications of 4164696, so that this test will actually - * prove something useful about 1.2Beta4 or 1.2FCS before - * 4171278 was fixed. - */ - for (int i = 0; i < 10; i++) { - System.gc(); - obj.lock.wait(TIMEOUT / 10); - if (obj.unreferencedInvoked) { - break; - } - } + synchronized (obj.lock) { + registry.unbind(BINDING); + System.err.println("unbound remote object from registry; " + + "waiting for unreferenced() callback..."); + /* + * This incantation seems sufficient to work around the + * ramifications of 4164696, so that this test will actually + * prove something useful about 1.2Beta4 or 1.2FCS before + * 4171278 was fixed. + */ + for (int i = 0; i < 10; i++) { + System.gc(); + obj.lock.wait(TIMEOUT / 10); + if (obj.unreferencedInvoked) { + break; + } + } - if (obj.unreferencedInvoked) { - System.err.println( - "invoked with context class loader: " + - obj.unreferencedContext); + if (obj.unreferencedInvoked) { + System.err.println( + "invoked with context class loader: " + + obj.unreferencedContext); - if (obj.unreferencedContext == intendedContext) { - System.err.println( - "TEST PASSED: unreferenced() invoked" + - " with intended context class loader"); - } else { - throw new RuntimeException( - "TEST FAILED: unreferenced() invoked" + - " with incorrect context class loader"); - } - } else { - throw new RuntimeException( - "TEST FAILED: unreferenced() not invoked after " + - ((double) TIMEOUT / 1000.0) + " seconds or unreferenced failed to create a thread"); - } - } + if (obj.unreferencedContext == intendedContext) { + System.err.println( + "TEST PASSED: unreferenced() invoked" + + " with intended context class loader"); + } else { + throw new RuntimeException( + "TEST FAILED: unreferenced() invoked" + + " with incorrect context class loader"); + } + } else { + throw new RuntimeException( + "TEST FAILED: unreferenced() not invoked after " + + ((double) TIMEOUT / 1000.0) + " seconds or unreferenced failed to create a thread"); + } + } - } catch (Exception e) { - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } else { - throw new RuntimeException( - "TEST FAILED: unexpected exception: " + e.toString()); - } - } finally { - /* - * When all is said and done, try to unexport the remote object - * so that the VM has a chance to exit. - */ - try { - UnicastRemoteObject.unexportObject(obj, true); - } catch (RemoteException e) { - } - } + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new RuntimeException( + "TEST FAILED: unexpected exception: " + e.toString()); + } + } finally { + /* + * When all is said and done, try to unexport the remote object + * so that the VM has a chance to exit. + */ + try { + UnicastRemoteObject.unexportObject(obj, true); + } catch (RemoteException e) { + } + } } } diff --git a/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext_Stub.java b/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext_Stub.java index 2ff7499e605..0e35db25c19 100644 --- a/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext_Stub.java +++ b/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,10 +29,10 @@ public final class UnreferencedContext_Stub implements java.rmi.Remote { private static final long serialVersionUID = 2; - + // constructors public UnreferencedContext_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + } diff --git a/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java b/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java index b8a2cbfc897..02bb3d7f459 100644 --- a/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java +++ b/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -51,75 +51,75 @@ public class CloseServerSocketOnTermination { private static long TIMEOUT = 5000; public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 4924577\n"); + System.err.println("\nRegression test for bug 4924577\n"); - RMISocketFactory.setFailureHandler(new RMIFailureHandler() { - public boolean failure(Exception e) { return false; } - }); + RMISocketFactory.setFailureHandler(new RMIFailureHandler() { + public boolean failure(Exception e) { return false; } + }); - tryWith(new IOException()); - tryWith(new NullPointerException()); - tryWith(new OutOfMemoryError()); - tryWith(new NoClassDefFoundError()); - tryWith(new InternalError()); - tryWith(new Throwable()); + tryWith(new IOException()); + tryWith(new NullPointerException()); + tryWith(new OutOfMemoryError()); + tryWith(new NoClassDefFoundError()); + tryWith(new InternalError()); + tryWith(new Throwable()); - System.err.println("TEST PASSED"); + System.err.println("TEST PASSED"); } private static void tryWith(Throwable t) throws Exception { - Remote impl = new Remote() { }; - try { - CountDownLatch latch = new CountDownLatch(1); - UnicastRemoteObject.exportObject(impl, 0, null, new SSF(t, latch)); - if (!latch.await(TIMEOUT, TimeUnit.MILLISECONDS)) { - throw new Error("server socket not closed"); - } - } finally { - UnicastRemoteObject.unexportObject(impl, true); - } + Remote impl = new Remote() { }; + try { + CountDownLatch latch = new CountDownLatch(1); + UnicastRemoteObject.exportObject(impl, 0, null, new SSF(t, latch)); + if (!latch.await(TIMEOUT, TimeUnit.MILLISECONDS)) { + throw new Error("server socket not closed"); + } + } finally { + UnicastRemoteObject.unexportObject(impl, true); + } } private static class SSF implements RMIServerSocketFactory { - private final Throwable acceptFailure; - private final CountDownLatch closedLatch; - SSF(Throwable acceptFailure, CountDownLatch closedLatch) { - this.acceptFailure = acceptFailure; - this.closedLatch = closedLatch; - } - public ServerSocket createServerSocket(int port) throws IOException { - return new ServerSocket(port) { - private int acceptInvocations = 0; - public synchronized Socket accept() throws IOException { - if (acceptInvocations++ == 0) { - throwException(acceptFailure); - } - return super.accept(); - } - public void close() throws IOException { - closedLatch.countDown(); - super.close(); - } - }; - } + private final Throwable acceptFailure; + private final CountDownLatch closedLatch; + SSF(Throwable acceptFailure, CountDownLatch closedLatch) { + this.acceptFailure = acceptFailure; + this.closedLatch = closedLatch; + } + public ServerSocket createServerSocket(int port) throws IOException { + return new ServerSocket(port) { + private int acceptInvocations = 0; + public synchronized Socket accept() throws IOException { + if (acceptInvocations++ == 0) { + throwException(acceptFailure); + } + return super.accept(); + } + public void close() throws IOException { + closedLatch.countDown(); + super.close(); + } + }; + } - // hack to throw an arbitrary (possibly checked) Throwable - private static void throwException(Throwable t) { - try { - toThrow.set(t); - Thrower.class.newInstance(); - } catch (IllegalAccessException e) { - throw new AssertionError(); - } catch (InstantiationException e) { - throw new AssertionError(); - } finally { - toThrow.remove(); - } - } - private static ThreadLocal toThrow = - new ThreadLocal(); - private static class Thrower { - Thrower() throws Throwable { throw toThrow.get(); } - } + // hack to throw an arbitrary (possibly checked) Throwable + private static void throwException(Throwable t) { + try { + toThrow.set(t); + Thrower.class.newInstance(); + } catch (IllegalAccessException e) { + throw new AssertionError(); + } catch (InstantiationException e) { + throw new AssertionError(); + } finally { + toThrow.remove(); + } + } + private static ThreadLocal toThrow = + new ThreadLocal(); + private static class Thrower { + Thrower() throws Throwable { throw toThrow.get(); } + } } } diff --git a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java index 3cd17696cab..00dadb2f338 100644 --- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java +++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,15 +34,15 @@ * * @library ../../testlibrary * @build CheckFQDN CheckFQDNClient CheckFQDN_Stub TellServerName - * @run main/othervm/timeout=120 CheckFQDN + * @run main/othervm/timeout=120 CheckFQDN */ -/** +/** * Get the hostname used by rmi using different rmi properities: * * if set java.rmi.server.hostname, hostname should equal this * property. - * + * * if set java.rmi.server.useLocalHostname, hostname must contain a '.' * * if set no properties hostname should be an ipaddress. @@ -58,118 +58,118 @@ import java.rmi.server.*; import java.io.*; /** - * Export a remote object through which the exec'ed client vm can + * Export a remote object through which the exec'ed client vm can * inform the main test what its host name is. */ -public class CheckFQDN extends UnicastRemoteObject +public class CheckFQDN extends UnicastRemoteObject implements TellServerName { - + static String propertyBeingTested = null; static String propertyBeingTestedValue = null; public static void main(String args[]) { - Object dummy = new Object(); - CheckFQDN checkFQDN = null; - try { - checkFQDN = new CheckFQDN(); + Object dummy = new Object(); + CheckFQDN checkFQDN = null; + try { + checkFQDN = new CheckFQDN(); - System.err.println - ("\nRegression test for bug/rfe 4115683\n"); - - Registry registry = java.rmi.registry.LocateRegistry. - createRegistry(TestLibrary.REGISTRY_PORT); - registry.bind("CheckFQDN", checkFQDN); - - /* test the host name scheme in different environments.*/ - testProperty("java.rmi.server.useLocalHostname", "true", ""); - testProperty("java.rmi.server.hostname", "thisIsJustAnRMITest", ""); - testProperty("java.rmi.server.hostname", "thisIsJustAnRMITest", - " -Djava.rmi.server.useLocalHostname=true "); - testProperty("", "", ""); + System.err.println + ("\nRegression test for bug/rfe 4115683\n"); - } catch (Exception e) { - TestLibrary.bomb(e); - } finally { - if (checkFQDN != null) { - TestLibrary.unexport(checkFQDN); - } - } - System.err.println("\nTest for bug/ref 4115683 passed.\n"); + Registry registry = java.rmi.registry.LocateRegistry. + createRegistry(TestLibrary.REGISTRY_PORT); + registry.bind("CheckFQDN", checkFQDN); + + /* test the host name scheme in different environments.*/ + testProperty("java.rmi.server.useLocalHostname", "true", ""); + testProperty("java.rmi.server.hostname", "thisIsJustAnRMITest", ""); + testProperty("java.rmi.server.hostname", "thisIsJustAnRMITest", + " -Djava.rmi.server.useLocalHostname=true "); + testProperty("", "", ""); + + } catch (Exception e) { + TestLibrary.bomb(e); + } finally { + if (checkFQDN != null) { + TestLibrary.unexport(checkFQDN); + } + } + System.err.println("\nTest for bug/ref 4115683 passed.\n"); } - /** + /** * Spawn a vm and feed it a property which sets the client's rmi * hostname. */ - public static void testProperty(String property, - String propertyValue, - String extraProp) + public static void testProperty(String property, + String propertyValue, + String extraProp) { - try { - String propOption = ""; - String equal = ""; - if (!property.equals("")) { - propOption = " -D"; - equal = "="; - } + try { + String propOption = ""; + String equal = ""; + if (!property.equals("")) { + propOption = " -D"; + equal = "="; + } - JavaVM jvm = new JavaVM("CheckFQDNClient", - propOption + property + - equal + - propertyValue + extraProp, - ""); - - propertyBeingTested=property; - propertyBeingTestedValue=propertyValue; + JavaVM jvm = new JavaVM("CheckFQDNClient", + propOption + property + + equal + + propertyValue + extraProp, + ""); - // create a client to tell checkFQDN what its rmi name is. */ - jvm.start(); + propertyBeingTested=property; + propertyBeingTestedValue=propertyValue; - if (jvm.getVM().waitFor() != 0 ) { - TestLibrary.bomb("Test failed, error in client."); - } - - } catch (Exception e) { - TestLibrary.bomb(e); - } + // create a client to tell checkFQDN what its rmi name is. */ + jvm.start(); + + if (jvm.getVM().waitFor() != 0 ) { + TestLibrary.bomb("Test failed, error in client."); + } + + } catch (Exception e) { + TestLibrary.bomb(e); + } } CheckFQDN() throws RemoteException { } - /** - * Remote method to allow client vm to tell the main test what its + /** + * Remote method to allow client vm to tell the main test what its * host name is . */ - public void tellServerName(String serverName) - throws RemoteException { + public void tellServerName(String serverName) + throws RemoteException { - if (propertyBeingTested.equals("java.rmi.server.hostname")) { - if ( !propertyBeingTestedValue.equals(serverName)) { - TestLibrary.bomb(propertyBeingTested + - ":\n Client rmi server name does " + - "not equal the one specified " + - "by java.rmi.server.hostname: " + - serverName +" != " + - propertyBeingTestedValue); - } + if (propertyBeingTested.equals("java.rmi.server.hostname")) { + if ( !propertyBeingTestedValue.equals(serverName)) { + TestLibrary.bomb(propertyBeingTested + + ":\n Client rmi server name does " + + "not equal the one specified " + + "by java.rmi.server.hostname: " + + serverName +" != " + + propertyBeingTestedValue); + } - /** use local host name, must contain a '.' */ - } else if (propertyBeingTested.equals - ("java.rmi.server.useLocalHostname")) { - if (serverName.indexOf('.') < 0) { - TestLibrary.bomb(propertyBeingTested + - ":\nThe client servername contains no '.'"); - } - } else { - // no propety set, must be ip address - if ((serverName.indexOf('.') < 0) || - (!Character.isDigit(serverName.charAt(0)))) { - TestLibrary.bomb("Default name scheme:\n"+ - " The client servername contains no '.'"+ - "or is not an ip address"); - } - } - System.err.println("Servername used: " + serverName); + /** use local host name, must contain a '.' */ + } else if (propertyBeingTested.equals + ("java.rmi.server.useLocalHostname")) { + if (serverName.indexOf('.') < 0) { + TestLibrary.bomb(propertyBeingTested + + ":\nThe client servername contains no '.'"); + } + } else { + // no propety set, must be ip address + if ((serverName.indexOf('.') < 0) || + (!Character.isDigit(serverName.charAt(0)))) { + TestLibrary.bomb("Default name scheme:\n"+ + " The client servername contains no '.'"+ + "or is not an ip address"); + } + } + System.err.println("Servername used: " + serverName); } } diff --git a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java index 203413b9d00..ef644b197be 100644 --- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java +++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,7 @@ * * * Client that will run in its own vm and tell the main CheckFQDN test - * program what its rmi host name is, name obtained from TCPEndpoint. + * program what its rmi host name is, name obtained from TCPEndpoint. */ import java.rmi.*; @@ -40,72 +40,72 @@ import sun.rmi.transport.tcp.TCPEndpoint; public class CheckFQDNClient implements Runnable { final static int NAME_SERVICE_TIME_OUT = 12000; - + static TCPEndpoint ep = null; - /** + /** * main, lookup remote object and tell it the rmi * hostname of this client vm. */ public static void main (String args[]) { - - // start a registry and register a copy of this in it. - TellServerName tell; - String hostname = null; - - try { - hostname = retrieveServerName(); - System.err.println("Client host name: " + - hostname); - tell = (TellServerName) Naming.lookup("rmi://:" + - TestLibrary.REGISTRY_PORT - + "/CheckFQDN"); - tell.tellServerName(hostname); - System.err.println("client has exited"); + // start a registry and register a copy of this in it. + TellServerName tell; + String hostname = null; - } catch (Exception e ) { - throw new RuntimeException(e.getMessage()); - } - System.exit(0); + try { + hostname = retrieveServerName(); + System.err.println("Client host name: " + + hostname); + + tell = (TellServerName) Naming.lookup("rmi://:" + + TestLibrary.REGISTRY_PORT + + "/CheckFQDN"); + tell.tellServerName(hostname); + System.err.println("client has exited"); + + } catch (Exception e ) { + throw new RuntimeException(e.getMessage()); + } + System.exit(0); } - + /* what is the rmi hostname for this vm? */ public static String retrieveServerName () { - try { + try { - CheckFQDNClient chk = new CheckFQDNClient(); - - synchronized(chk) { - (new Thread (chk)).start(); - chk.wait(NAME_SERVICE_TIME_OUT); - } - - if (ep == null) { - throw new RuntimeException - ("Timeout getting the local endpoint."); - } - - // this is the name used by rmi for the client hostname - return ep.getHost(); - - }catch (Exception e){ - throw new RuntimeException (e.getMessage()); - } + CheckFQDNClient chk = new CheckFQDNClient(); + + synchronized(chk) { + (new Thread (chk)).start(); + chk.wait(NAME_SERVICE_TIME_OUT); + } + + if (ep == null) { + throw new RuntimeException + ("Timeout getting the local endpoint."); + } + + // this is the name used by rmi for the client hostname + return ep.getHost(); + + }catch (Exception e){ + throw new RuntimeException (e.getMessage()); + } } /* thread to geth the rmi hostname of this vm */ public void run () { - try { - synchronized(this) { - ep = TCPEndpoint.getLocalEndpoint(0); - } - } catch (Exception e) { - throw new RuntimeException(); - } finally { - synchronized(this) { - this.notify(); - } - } + try { + synchronized(this) { + ep = TCPEndpoint.getLocalEndpoint(0); + } + } catch (Exception e) { + throw new RuntimeException(); + } finally { + synchronized(this) { + this.notify(); + } + } } } diff --git a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN_Stub.java b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN_Stub.java index 93330b17c11..3c318cae946 100644 --- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN_Stub.java +++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,66 +29,66 @@ public final class CheckFQDN_Stub implements TellServerName, java.rmi.Remote { private static java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("void tellServerName(java.lang.String)") + new java.rmi.server.Operation("void tellServerName(java.lang.String)") }; - + private static final long interfaceHash = 4509625981775855367L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_tellServerName_0; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_tellServerName_0 = TellServerName.class.getMethod("tellServerName", new java.lang.Class[] {java.lang.String.class}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_tellServerName_0 = TellServerName.class.getMethod("tellServerName", new java.lang.Class[] {java.lang.String.class}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public CheckFQDN_Stub() { - super(); + super(); } public CheckFQDN_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of tellServerName(String) public void tellServerName(java.lang.String $param_String_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_tellServerName_0, new java.lang.Object[] {$param_String_1}, -5180633734615762942L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_String_1); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_tellServerName_0, new java.lang.Object[] {$param_String_1}, -5180633734615762942L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_String_1); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/transport/checkFQDN/TellServerName.java b/jdk/test/java/rmi/transport/checkFQDN/TellServerName.java index 0dbf0c6c300..d5625c5cbdb 100644 --- a/jdk/test/java/rmi/transport/checkFQDN/TellServerName.java +++ b/jdk/test/java/rmi/transport/checkFQDN/TellServerName.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,7 +24,7 @@ import java.rmi.*; import java.rmi.server.*; -/** +/** * interface to get server name from an execed vm * I am using an execed vm because I need to set * rmi's hostname serveral times with different properties. @@ -32,4 +32,3 @@ import java.rmi.server.*; interface TellServerName extends Remote { void tellServerName (String serverName) throws RemoteException; } - diff --git a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java index b5823dd5bde..94847ffc01e 100644 --- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java +++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -44,7 +44,7 @@ * the remote object. Each vmid needs a seperate LeaseInfo object in * the object table target DGCImpl.leaseTable. If the leak is fixed, * the leaseTable field will contain no objects. We use reflection to - * find the number of objects contained in this table. + * find the number of objects contained in this table. */ import java.rmi.*; @@ -57,13 +57,13 @@ import java.lang.reflect.*; import java.rmi.registry.*; public class CheckLeaseLeak extends UnicastRemoteObject implements LeaseLeak { - + public CheckLeaseLeak() throws RemoteException { } public void ping () throws RemoteException { } /** * Id to fake the DGC_ID, so we can later get a reference to the - * DGCImpl in the object table. + * DGCImpl in the object table. */ private final static int DGC_ID = 2; @@ -71,148 +71,148 @@ public class CheckLeaseLeak extends UnicastRemoteObject implements LeaseLeak { private final static int numberPingCalls = 0; private final static int CHECK_INTERVAL = 400; private final static int LEASE_VALUE = 20; - + public static void main (String[] args) { - CheckLeaseLeak leakServer = null; - int numLeft =0; + CheckLeaseLeak leakServer = null; + int numLeft =0; - /* - * we want DGC to collect leases *quickly* - * decrease the lease check interval - */ - TestLibrary.setInteger("sun.rmi.dgc.checkInterval", - CHECK_INTERVAL); - TestLibrary.setInteger("java.rmi.dgc.leaseValue", - LEASE_VALUE); + /* + * we want DGC to collect leases *quickly* + * decrease the lease check interval + */ + TestLibrary.setInteger("sun.rmi.dgc.checkInterval", + CHECK_INTERVAL); + TestLibrary.setInteger("java.rmi.dgc.leaseValue", + LEASE_VALUE); - try { - Registry registry = - java.rmi.registry.LocateRegistry. - createRegistry(TestLibrary.REGISTRY_PORT); + try { + Registry registry = + java.rmi.registry.LocateRegistry. + createRegistry(TestLibrary.REGISTRY_PORT); - leakServer = new CheckLeaseLeak(); - registry.rebind("/LeaseLeak", leakServer); + leakServer = new CheckLeaseLeak(); + registry.rebind("/LeaseLeak", leakServer); - /* create a bunch of clients in a *different* vm */ - for (int i = 0 ; i < ITERATIONS ; i ++ ) { - System.err.println("Created client: " + i); - - JavaVM jvm = new JavaVM("LeaseLeakClient", - " -Djava.security.policy=" + - TestParams.defaultPolicy, ""); - jvm.start(); + /* create a bunch of clients in a *different* vm */ + for (int i = 0 ; i < ITERATIONS ; i ++ ) { + System.err.println("Created client: " + i); - if (jvm.getVM().waitFor() == 1 ) { - TestLibrary.bomb("Client process failed"); - } - } - numLeft = getDGCLeaseTableSize(); - Thread.sleep(3000); - - } catch(Exception e) { - TestLibrary.bomb("CheckLeaseLeak Error: ", e); - } finally { - if (leakServer != null) { - TestLibrary.unexport(leakServer); - leakServer = null; - } - } + JavaVM jvm = new JavaVM("LeaseLeakClient", + " -Djava.security.policy=" + + TestParams.defaultPolicy, ""); + jvm.start(); - /* numLeft should be 2 - if 11 there is a problem. */ - if (numLeft > 2) { - TestLibrary.bomb("Too many objects in DGCImpl.leaseTable: "+ - numLeft); - } else { - System.err.println("Check leaseInfo leak passed with " + - numLeft - + " object(s) in the leaseTable"); - } + if (jvm.getVM().waitFor() == 1 ) { + TestLibrary.bomb("Client process failed"); + } + } + numLeft = getDGCLeaseTableSize(); + Thread.sleep(3000); + + } catch(Exception e) { + TestLibrary.bomb("CheckLeaseLeak Error: ", e); + } finally { + if (leakServer != null) { + TestLibrary.unexport(leakServer); + leakServer = null; + } + } + + /* numLeft should be 2 - if 11 there is a problem. */ + if (numLeft > 2) { + TestLibrary.bomb("Too many objects in DGCImpl.leaseTable: "+ + numLeft); + } else { + System.err.println("Check leaseInfo leak passed with " + + numLeft + + " object(s) in the leaseTable"); + } } /** * Obtain a reference to the main DGCImpl via reflection. Extract * the DGCImpl using the ObjectTable and the well known ID of the - * DGCImpl. + * DGCImpl. */ private static int getDGCLeaseTableSize () { - int numLeaseInfosLeft = 0; + int numLeaseInfosLeft = 0; - /** - * Will eventually be set to point at the leaseTable inside - * DGCImpl. - */ - Map leaseTable = null; - final Remote[] dgcImpl = new Remote[1]; - Field f; + /** + * Will eventually be set to point at the leaseTable inside + * DGCImpl. + */ + Map leaseTable = null; + final Remote[] dgcImpl = new Remote[1]; + Field f; - try { - f = (Field) java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction() { - public Object run() throws Exception { + try { + f = (Field) java.security.AccessController.doPrivileged + (new java.security.PrivilegedExceptionAction() { + public Object run() throws Exception { - ObjID dgcID = new ObjID(DGC_ID); - - /* - * Construct an ObjectEndpoint containing DGC's - * ObjID. - */ - Class oeClass = - Class.forName("sun.rmi.transport.ObjectEndpoint"); - Class[] constrParams = - new Class[]{ ObjID.class, Transport.class }; - Constructor oeConstructor = - oeClass.getDeclaredConstructor(constrParams); - oeConstructor.setAccessible(true); - Object oe = - oeConstructor.newInstance( - new Object[]{ dgcID, null }); - - /* - * Get Target that contains DGCImpl in ObjectTable - */ - Class objTableClass = - Class.forName("sun.rmi.transport.ObjectTable"); - Class getTargetParams[] = new Class[] { oeClass }; - Method objTableGetTarget = - objTableClass.getDeclaredMethod("getTarget", - getTargetParams); - objTableGetTarget.setAccessible(true); - Target dgcTarget = (Target) - objTableGetTarget.invoke(null, new Object[]{ oe }); - - /* get the DGCImpl from its Target */ - Method targetGetImpl = - dgcTarget.getClass().getDeclaredMethod - ("getImpl", null); - targetGetImpl.setAccessible(true); - dgcImpl[0] = - (Remote) targetGetImpl.invoke(dgcTarget, null); + ObjID dgcID = new ObjID(DGC_ID); - /* Get the lease table from the DGCImpl. */ - Field reflectedLeaseTable = - dgcImpl[0].getClass().getDeclaredField - ("leaseTable"); - reflectedLeaseTable.setAccessible(true); + /* + * Construct an ObjectEndpoint containing DGC's + * ObjID. + */ + Class oeClass = + Class.forName("sun.rmi.transport.ObjectEndpoint"); + Class[] constrParams = + new Class[]{ ObjID.class, Transport.class }; + Constructor oeConstructor = + oeClass.getDeclaredConstructor(constrParams); + oeConstructor.setAccessible(true); + Object oe = + oeConstructor.newInstance( + new Object[]{ dgcID, null }); - return reflectedLeaseTable; - } - }); + /* + * Get Target that contains DGCImpl in ObjectTable + */ + Class objTableClass = + Class.forName("sun.rmi.transport.ObjectTable"); + Class getTargetParams[] = new Class[] { oeClass }; + Method objTableGetTarget = + objTableClass.getDeclaredMethod("getTarget", + getTargetParams); + objTableGetTarget.setAccessible(true); + Target dgcTarget = (Target) + objTableGetTarget.invoke(null, new Object[]{ oe }); - /** - * This is the leaseTable that will fill up with LeaseInfo - * objects if the LeaseInfo memory leak is not fixed. - */ - leaseTable = (Map) f.get(dgcImpl[0]); + /* get the DGCImpl from its Target */ + Method targetGetImpl = + dgcTarget.getClass().getDeclaredMethod + ("getImpl", null); + targetGetImpl.setAccessible(true); + dgcImpl[0] = + (Remote) targetGetImpl.invoke(dgcTarget, null); - numLeaseInfosLeft = leaseTable.size(); + /* Get the lease table from the DGCImpl. */ + Field reflectedLeaseTable = + dgcImpl[0].getClass().getDeclaredField + ("leaseTable"); + reflectedLeaseTable.setAccessible(true); - } catch(Exception e) { - if (e instanceof java.security.PrivilegedActionException) - e = ((java.security.PrivilegedActionException) e). - getException(); - TestLibrary.bomb(e); - } + return reflectedLeaseTable; + } + }); - return numLeaseInfosLeft; + /** + * This is the leaseTable that will fill up with LeaseInfo + * objects if the LeaseInfo memory leak is not fixed. + */ + leaseTable = (Map) f.get(dgcImpl[0]); + + numLeaseInfosLeft = leaseTable.size(); + + } catch(Exception e) { + if (e instanceof java.security.PrivilegedActionException) + e = ((java.security.PrivilegedActionException) e). + getException(); + TestLibrary.bomb(e); + } + + return numLeaseInfosLeft; } } diff --git a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak_Stub.java b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak_Stub.java index 42f6fa901d6..52b5d89a53a 100644 --- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak_Stub.java +++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,60 +29,60 @@ public final class CheckLeaseLeak_Stub implements LeaseLeak, java.rmi.Remote { private static java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("void ping()") + new java.rmi.server.Operation("void ping()") }; - + private static final long interfaceHash = -8409781791984809394L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_ping_0; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_ping_0 = LeaseLeak.class.getMethod("ping", new java.lang.Class[] {}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_ping_0 = LeaseLeak.class.getMethod("ping", new java.lang.Class[] {}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public CheckLeaseLeak_Stub() { - super(); + super(); } public CheckLeaseLeak_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of ping() public void ping() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_ping_0, null, 5866401369815527589L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_ping_0, null, 5866401369815527589L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeak.java b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeak.java index d83e2ebc296..de412cda32e 100644 --- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeak.java +++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeak.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java index a9f452e7147..b42f23d2e66 100644 --- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java +++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,24 +25,24 @@ import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; -public class LeaseLeakClient { +public class LeaseLeakClient { public static void main(String args[]) { - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); - - try { - LeaseLeak leaseLeak = null; - - // put a reference on a remote object. - Registry registry = - java.rmi.registry.LocateRegistry.getRegistry( - TestLibrary.REGISTRY_PORT); - leaseLeak = (LeaseLeak) registry.lookup("/LeaseLeak"); - leaseLeak.ping(); - - } catch(Exception e) { - System.err.println("LeaseLeakClient Error: "+e.getMessage()); - e.printStackTrace(); - throw new RuntimeException(e.getMessage()); - } + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + + try { + LeaseLeak leaseLeak = null; + + // put a reference on a remote object. + Registry registry = + java.rmi.registry.LocateRegistry.getRegistry( + TestLibrary.REGISTRY_PORT); + leaseLeak = (LeaseLeak) registry.lookup("/LeaseLeak"); + leaseLeak.ping(); + + } catch(Exception e) { + System.err.println("LeaseLeakClient Error: "+e.getMessage()); + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } } } diff --git a/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java b/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java index fe0b9accbe0..54ca8fd2a71 100644 --- a/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java +++ b/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -50,80 +50,80 @@ public class CloseServerSocket implements Remote { private CloseServerSocket() { } public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 4457683\n"); + System.err.println("\nRegression test for bug 4457683\n"); - verifyPortFree(PORT); - Registry registry = LocateRegistry.createRegistry(PORT); - System.err.println("- exported registry: " + registry); - verifyPortInUse(PORT); - UnicastRemoteObject.unexportObject(registry, true); - System.err.println("- unexported registry"); - Thread.sleep(1); // work around BindException (bug?) - verifyPortFree(PORT); + verifyPortFree(PORT); + Registry registry = LocateRegistry.createRegistry(PORT); + System.err.println("- exported registry: " + registry); + verifyPortInUse(PORT); + UnicastRemoteObject.unexportObject(registry, true); + System.err.println("- unexported registry"); + Thread.sleep(1); // work around BindException (bug?) + verifyPortFree(PORT); - /* - * The follow portion of this test is disabled temporarily - * because 4457683 was partially backed out because of - * 6269166; for now, only server sockets originally opened for - * exports on non-anonymous ports will be closed when all of - * the corresponding remote objects have been exported. A - * separate bug will be filed to represent the remainder of - * 4457683 for anonymous-port exports. - */ + /* + * The follow portion of this test is disabled temporarily + * because 4457683 was partially backed out because of + * 6269166; for now, only server sockets originally opened for + * exports on non-anonymous ports will be closed when all of + * the corresponding remote objects have been exported. A + * separate bug will be filed to represent the remainder of + * 4457683 for anonymous-port exports. + */ -// SSF ssf = new SSF(); -// Remote impl = new CloseServerSocket(); -// Remote stub = UnicastRemoteObject.exportObject(impl, 0, null, ssf); -// System.err.println("- exported object: " + stub); -// UnicastRemoteObject.unexportObject(impl, true); -// System.err.println("- unexported object"); -// synchronized (ssf) { -// if (!ssf.serverSocketClosed) { -// throw new RuntimeException("TEST FAILED: " + -// "server socket not closed"); -// } -// } +// SSF ssf = new SSF(); +// Remote impl = new CloseServerSocket(); +// Remote stub = UnicastRemoteObject.exportObject(impl, 0, null, ssf); +// System.err.println("- exported object: " + stub); +// UnicastRemoteObject.unexportObject(impl, true); +// System.err.println("- unexported object"); +// synchronized (ssf) { +// if (!ssf.serverSocketClosed) { +// throw new RuntimeException("TEST FAILED: " + +// "server socket not closed"); +// } +// } - System.err.println("TEST PASSED"); + System.err.println("TEST PASSED"); } private static void verifyPortFree(int port) throws IOException { - ServerSocket ss = new ServerSocket(PORT); - ss.close(); - System.err.println("- port " + port + " is free"); + ServerSocket ss = new ServerSocket(PORT); + ss.close(); + System.err.println("- port " + port + " is free"); } private static void verifyPortInUse(int port) throws IOException { - try { - verifyPortFree(port); - } catch (BindException e) { - System.err.println("- port " + port + " is in use"); - return; - } + try { + verifyPortFree(port); + } catch (BindException e) { + System.err.println("- port " + port + " is in use"); + return; + } } private static class SSF implements RMIServerSocketFactory { - boolean serverSocketClosed = false; - SSF() { }; + boolean serverSocketClosed = false; + SSF() { }; - public ServerSocket createServerSocket(int port) throws IOException { - return new SS(port); - } + public ServerSocket createServerSocket(int port) throws IOException { + return new SS(port); + } - private class SS extends ServerSocket { - SS(int port) throws IOException { - super(port); - System.err.println("- created server socket: " + this); - }; + private class SS extends ServerSocket { + SS(int port) throws IOException { + super(port); + System.err.println("- created server socket: " + this); + }; - public void close() throws IOException { - synchronized (SSF.this) { - serverSocketClosed = true; - SSF.this.notifyAll(); - } - System.err.println("- closing server socket: " + this); - super.close(); - } - } + public void close() throws IOException { + synchronized (SSF.this) { + serverSocketClosed = true; + SSF.this.notifyAll(); + } + System.err.println("- closing server socket: " + this); + super.close(); + } + } } } diff --git a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java index fd01055ca37..820d4c410dd 100644 --- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java +++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -46,7 +46,7 @@ * was attempting to lock. * * This test causes the above conditions to occur and waits to see if - * a given set of remote calls finishes "quickly enough." + * a given set of remote calls finishes "quickly enough." */ import java.rmi.*; @@ -60,98 +60,98 @@ public class DGCDeadLock implements Runnable { static DGCDeadLock test = new DGCDeadLock(); static { - System.setProperty("sun.rmi.transport.cleanInterval", "50"); + System.setProperty("sun.rmi.transport.cleanInterval", "50"); } static public void main(String[] args) { - JavaVM testImplVM = null; - - System.err.println("\nregression test for 4118056\n"); - TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); + JavaVM testImplVM = null; + + System.err.println("\nregression test for 4118056\n"); + TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager"); try { - String options = " -Djava.security.policy=" + - TestParams.defaultPolicy + - " -Djava.rmi.dgc.leaseValue=500000" + - " -Dsun.rmi.dgc.checkInterval=" + - (HOLD_TARGET_TIME - 5000) + ""; + String options = " -Djava.security.policy=" + + TestParams.defaultPolicy + + " -Djava.rmi.dgc.leaseValue=500000" + + " -Dsun.rmi.dgc.checkInterval=" + + (HOLD_TARGET_TIME - 5000) + ""; - testImplVM = new JavaVM("TestImpl", options, ""); - testImplVM.start(); + testImplVM = new JavaVM("TestImpl", options, ""); + testImplVM.start(); - synchronized (test) { - Thread t = new Thread(test); - t.setDaemon(true); - t.start(); + synchronized (test) { + Thread t = new Thread(test); + t.setDaemon(true); + t.start(); - // wait for the remote calls to take place - test.wait(TEST_FAIL_TIME); - } + // wait for the remote calls to take place + test.wait(TEST_FAIL_TIME); + } - if (!finished) { - TestLibrary.bomb("Test failed, had exception or exercise" + - " routines took too long to " + - "execute"); - } - System.err.println("Test passed, exercises " + - "finished in time."); + if (!finished) { + TestLibrary.bomb("Test failed, had exception or exercise" + + " routines took too long to " + + "execute"); + } + System.err.println("Test passed, exercises " + + "finished in time."); } catch (Exception e) { - testImplVM = null; - TestLibrary.bomb("test failed", e); + testImplVM = null; + TestLibrary.bomb("test failed", e); } } public void run() { - try { - String echo = null; + try { + String echo = null; - // give the test remote object time to initialize. - Thread.currentThread().sleep(8000); + // give the test remote object time to initialize. + Thread.currentThread().sleep(8000); - // create a test client - Test foo = (Test) Naming.lookup("rmi://:" + - TestLibrary.REGISTRY_PORT + - "/Foo"); - echo = foo.echo("Hello world"); - System.err.println("Test object created."); + // create a test client + Test foo = (Test) Naming.lookup("rmi://:" + + TestLibrary.REGISTRY_PORT + + "/Foo"); + echo = foo.echo("Hello world"); + System.err.println("Test object created."); - /* give TestImpl time to lock the target in the - * object table and any dirtys finish. - */ - Thread.currentThread().sleep(5000); + /* give TestImpl time to lock the target in the + * object table and any dirtys finish. + */ + Thread.currentThread().sleep(5000); - //unreference "Foo" - foo = null; + //unreference "Foo" + foo = null; - //garbage collect and finalize foo - Runtime.getRuntime().gc(); - Runtime.getRuntime().runFinalization(); - - //import "Bar" - Test bar = (Test) Naming.lookup("rmi://:" + - TestLibrary.REGISTRY_PORT + - "/Bar"); - - /* infinite loop to show the liveness of Client, - * if we have deadlock remote call will not return - */ - try { - for (int i = 0; i < 500; i++) { - echo = bar.echo("Remote call" + i); - Thread.sleep(10); - } + //garbage collect and finalize foo + Runtime.getRuntime().gc(); + Runtime.getRuntime().runFinalization(); - // flag exercises finished - finished = true; + //import "Bar" + Test bar = (Test) Naming.lookup("rmi://:" + + TestLibrary.REGISTRY_PORT + + "/Bar"); - } catch (RemoteException e) { - } - - } catch (Exception e) { - TestLibrary.bomb("test failed", e); - } finally { - } + /* infinite loop to show the liveness of Client, + * if we have deadlock remote call will not return + */ + try { + for (int i = 0; i < 500; i++) { + echo = bar.echo("Remote call" + i); + Thread.sleep(10); + } + + // flag exercises finished + finished = true; + + } catch (RemoteException e) { + } + + } catch (Exception e) { + TestLibrary.bomb("test failed", e); + } finally { + } } } diff --git a/jdk/test/java/rmi/transport/dgcDeadLock/Test.java b/jdk/test/java/rmi/transport/dgcDeadLock/Test.java index 4706b3870e8..5fcd90c3884 100644 --- a/jdk/test/java/rmi/transport/dgcDeadLock/Test.java +++ b/jdk/test/java/rmi/transport/dgcDeadLock/Test.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff --git a/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java b/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java index d96fcc21126..0f23ae73a0c 100644 --- a/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java +++ b/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -34,7 +34,7 @@ import java.util.*; import java.rmi.registry.*; import java.rmi.server.*; -public class TestImpl extends UnicastRemoteObject +public class TestImpl extends UnicastRemoteObject implements Test { static Thread locker = null; @@ -46,197 +46,197 @@ public class TestImpl extends UnicastRemoteObject public String echo(String msg) throws RemoteException { - if (locker == null) { - // hold the target if not already held - locker = lockTargetExpireLeases(foo, DGCDeadLock.HOLD_TARGET_TIME); - } + if (locker == null) { + // hold the target if not already held + locker = lockTargetExpireLeases(foo, DGCDeadLock.HOLD_TARGET_TIME); + } return "Message received: " + msg; } static public void main(String[] args) { - Registry registry = null; + Registry registry = null; try { - registry = java.rmi.registry.LocateRegistry. - createRegistry(TestLibrary.REGISTRY_PORT); + registry = java.rmi.registry.LocateRegistry. + createRegistry(TestLibrary.REGISTRY_PORT); - //export "Foo" - foo = new TestImpl(); - Naming.rebind("rmi://:" + - TestLibrary.REGISTRY_PORT - + "/Foo", foo); + //export "Foo" + foo = new TestImpl(); + Naming.rebind("rmi://:" + + TestLibrary.REGISTRY_PORT + + "/Foo", foo); - try { - //export "Bar" after leases have been expired. - bar = new TestImpl(); - Naming.rebind("rmi://localhost:" + - TestLibrary.REGISTRY_PORT - + "/Bar", bar); - } catch (Exception e) { - throw new RemoteException(e.getMessage()); - } - Thread.sleep(DGCDeadLock.TEST_FAIL_TIME); - System.err.println("object vm exiting..."); - System.exit(0); + try { + //export "Bar" after leases have been expired. + bar = new TestImpl(); + Naming.rebind("rmi://localhost:" + + TestLibrary.REGISTRY_PORT + + "/Bar", bar); + } catch (Exception e) { + throw new RemoteException(e.getMessage()); + } + Thread.sleep(DGCDeadLock.TEST_FAIL_TIME); + System.err.println("object vm exiting..."); + System.exit(0); } catch (Exception e) { - System.err.println(e.getMessage()); - e.printStackTrace(); + System.err.println(e.getMessage()); + e.printStackTrace(); } finally { - TestLibrary.unexport(registry); - registry = null; - } + TestLibrary.unexport(registry); + registry = null; + } } static Thread lockTargetExpireLeases(Remote toLock, int timeOut) { - Thread t = new Thread((Runnable) new TargetLocker(toLock, timeOut)); - t.start(); - return t; + Thread t = new Thread((Runnable) new TargetLocker(toLock, timeOut)); + t.start(); + return t; } static class TargetLocker implements Runnable { - Remote toLock = null; - int timeOut = 0; + Remote toLock = null; + int timeOut = 0; - TargetLocker(Remote toLock, int timeOut) { - this.toLock = toLock; - this.timeOut = timeOut; - } + TargetLocker(Remote toLock, int timeOut) { + this.toLock = toLock; + this.timeOut = timeOut; + } - public void run() { - try { - // give dgc dirty calls time to finish. - Thread.currentThread().sleep(4000); + public void run() { + try { + // give dgc dirty calls time to finish. + Thread.currentThread().sleep(4000); - java.security.AccessController. - doPrivileged(new LockTargetCheckLeases(toLock, - timeOut)); + java.security.AccessController. + doPrivileged(new LockTargetCheckLeases(toLock, + timeOut)); - } catch (Exception e) { - System.err.println(e.getMessage()); - e.printStackTrace(); - System.exit(1); - } - } + } catch (Exception e) { + System.err.println(e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + } } - static class LockTargetCheckLeases - implements java.security.PrivilegedAction { + static class LockTargetCheckLeases + implements java.security.PrivilegedAction { - Remote toLock = null; - int timeOut = 0; + Remote toLock = null; + int timeOut = 0; - LockTargetCheckLeases(Remote toLock, int timeOut) { - this.toLock = toLock; - this.timeOut = timeOut; - } + LockTargetCheckLeases(Remote toLock, int timeOut) { + this.toLock = toLock; + this.timeOut = timeOut; + } - public Object run() { - try { - - Class args[] = new Class[1]; - - Class objTableClass = Class.forName - ("sun.rmi.transport.ObjectTable"); - - /* get the Target that corresponds to toLock from the - * ObjectTable - */ - args[0] = Class.forName("java.rmi.Remote"); - Method objTableGetTarget = - objTableClass.getDeclaredMethod("getTarget", args ); - objTableGetTarget.setAccessible(true); - - Target lockTarget = - ((Target) objTableGetTarget.invoke - (null , new Object [] {toLock} )); - - // make sure the lease on this object has expired. - expireLeases(lockTarget); - - // stop other threads from using the target for toLock. - synchronized (lockTarget) { - System.err.println("Locked the relevant target, sleeping " + - timeOut/1000 + " seconds"); - Thread.currentThread().sleep(timeOut); - System.err.println("Target unlocked"); - } + public Object run() { + try { - } catch (Exception e) { - System.err.println(e.getMessage()); - e.printStackTrace(); - System.exit(1); - } - return null; - } + Class args[] = new Class[1]; + + Class objTableClass = Class.forName + ("sun.rmi.transport.ObjectTable"); + + /* get the Target that corresponds to toLock from the + * ObjectTable + */ + args[0] = Class.forName("java.rmi.Remote"); + Method objTableGetTarget = + objTableClass.getDeclaredMethod("getTarget", args ); + objTableGetTarget.setAccessible(true); + + Target lockTarget = + ((Target) objTableGetTarget.invoke + (null , new Object [] {toLock} )); + + // make sure the lease on this object has expired. + expireLeases(lockTarget); + + // stop other threads from using the target for toLock. + synchronized (lockTarget) { + System.err.println("Locked the relevant target, sleeping " + + timeOut/1000 + " seconds"); + Thread.currentThread().sleep(timeOut); + System.err.println("Target unlocked"); + } + + } catch (Exception e) { + System.err.println(e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + return null; + } } /* leases have long values, so no dirty calls which would lock out * a clean call, but the leases need to expire anyway, so we do it - * explicitly. + * explicitly. */ static void expireLeases(Target t) throws Exception { - final Target target = t; + final Target target = t; - java.security.AccessController.doPrivileged( + java.security.AccessController.doPrivileged( - // put this into another class? - new java.security.PrivilegedAction() { - public Object run() { - try { + // put this into another class? + new java.security.PrivilegedAction() { + public Object run() { + try { - Class DGCClass = Class.forName("sun.rmi.transport.DGCImpl"); - Method getDGCImpl = - DGCClass.getDeclaredMethod("getDGCImpl", null ); - getDGCImpl.setAccessible(true); - - // make sure the lease on this object has expired. - DGC dgcImpl = ((DGC) getDGCImpl.invoke(null, null)); - - /* Get the lease table from the DGCImpl. */ - Field reflectedLeaseTable = - dgcImpl.getClass().getDeclaredField("leaseTable"); - reflectedLeaseTable.setAccessible(true); - - Map leaseTable = (Map) reflectedLeaseTable.get(dgcImpl); - - // dont really need this synchronization... - synchronized (leaseTable) { - Iterator en = leaseTable.values().iterator(); - while (en.hasNext()) { - Object info = en.next(); - - /* Get the notifySet in the leaseInfo object. */ - Field notifySetField = - info.getClass().getDeclaredField("notifySet"); - notifySetField.setAccessible(true); - HashSet notifySet = (HashSet) notifySetField.get(info); - - Iterator iter = notifySet.iterator(); - while (iter.hasNext()) { - Target notified = (Target) iter.next(); - - if (notified == target) { - - /* Get and set the expiration field from the info object. */ - Field expirationField = info.getClass(). - getDeclaredField("expiration"); - expirationField.setAccessible(true); - expirationField.setLong(info, 0); - } - } - } - } - } catch (Exception e) { - System.err.println(e.getMessage()); - e.printStackTrace(); - System.exit(1); - } - // no interesting return value for this privileged action - return null; - } - }); + Class DGCClass = Class.forName("sun.rmi.transport.DGCImpl"); + Method getDGCImpl = + DGCClass.getDeclaredMethod("getDGCImpl", null ); + getDGCImpl.setAccessible(true); + + // make sure the lease on this object has expired. + DGC dgcImpl = ((DGC) getDGCImpl.invoke(null, null)); + + /* Get the lease table from the DGCImpl. */ + Field reflectedLeaseTable = + dgcImpl.getClass().getDeclaredField("leaseTable"); + reflectedLeaseTable.setAccessible(true); + + Map leaseTable = (Map) reflectedLeaseTable.get(dgcImpl); + + // dont really need this synchronization... + synchronized (leaseTable) { + Iterator en = leaseTable.values().iterator(); + while (en.hasNext()) { + Object info = en.next(); + + /* Get the notifySet in the leaseInfo object. */ + Field notifySetField = + info.getClass().getDeclaredField("notifySet"); + notifySetField.setAccessible(true); + HashSet notifySet = (HashSet) notifySetField.get(info); + + Iterator iter = notifySet.iterator(); + while (iter.hasNext()) { + Target notified = (Target) iter.next(); + + if (notified == target) { + + /* Get and set the expiration field from the info object. */ + Field expirationField = info.getClass(). + getDeclaredField("expiration"); + expirationField.setAccessible(true); + expirationField.setLong(info, 0); + } + } + } + } + } catch (Exception e) { + System.err.println(e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + // no interesting return value for this privileged action + return null; + } + }); } } diff --git a/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl_Stub.java b/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl_Stub.java index 49ea79e9c10..f82df1fffbb 100644 --- a/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl_Stub.java +++ b/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,78 +29,78 @@ public final class TestImpl_Stub implements Test, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("java.lang.String echo(java.lang.String)") + new java.rmi.server.Operation("java.lang.String echo(java.lang.String)") }; - + private static final long interfaceHash = 8975711176019764637L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_echo_0; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_echo_0 = Test.class.getMethod("echo", new java.lang.Class[] {java.lang.String.class}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_echo_0 = Test.class.getMethod("echo", new java.lang.Class[] {java.lang.String.class}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public TestImpl_Stub() { - super(); + super(); } public TestImpl_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of echo(String) public java.lang.String echo(java.lang.String $param_String_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_echo_0, new java.lang.Object[] {$param_String_1}, 5525131960618330777L); - return ((java.lang.String) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_String_1); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - java.lang.String $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.lang.String) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_echo_0, new java.lang.Object[] {$param_String_1}, 5525131960618330777L); + return ((java.lang.String) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_String_1); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + java.lang.String $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.lang.String) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java b/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java index 1d26e6769a4..e14de6adc57 100644 --- a/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java +++ b/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -49,85 +49,85 @@ public class HandshakeFailure { public static void main(String[] args) throws Exception { - /* - * Listen on port... - */ - ServerSocket serverSocket = new ServerSocket(PORT); + /* + * Listen on port... + */ + ServerSocket serverSocket = new ServerSocket(PORT); - /* - * (Attempt RMI call to port in separate thread.) - */ - Registry registry = LocateRegistry.getRegistry(PORT); - Connector connector = new Connector(registry); - Thread t = new Thread(connector); - t.setDaemon(true); - t.start(); + /* + * (Attempt RMI call to port in separate thread.) + */ + Registry registry = LocateRegistry.getRegistry(PORT); + Connector connector = new Connector(registry); + Thread t = new Thread(connector); + t.setDaemon(true); + t.start(); - /* - * ...accept one connection from port and send non-JRMP data. - */ - Socket socket = serverSocket.accept(); - socket.getOutputStream().write("Wrong way".getBytes()); - socket.close(); + /* + * ...accept one connection from port and send non-JRMP data. + */ + Socket socket = serverSocket.accept(); + socket.getOutputStream().write("Wrong way".getBytes()); + socket.close(); - /* - * Wait for call attempt to finish, and analyze result. - */ - t.join(TIMEOUT); - synchronized (connector) { - if (connector.success) { - throw new RuntimeException( - "TEST FAILED: remote call succeeded??"); - } - if (connector.exception == null) { - throw new RuntimeException( - "TEST FAILED: remote call did not time out"); - } else { - System.err.println("remote call failed with exception:"); - connector.exception.printStackTrace(); - System.err.println(); + /* + * Wait for call attempt to finish, and analyze result. + */ + t.join(TIMEOUT); + synchronized (connector) { + if (connector.success) { + throw new RuntimeException( + "TEST FAILED: remote call succeeded??"); + } + if (connector.exception == null) { + throw new RuntimeException( + "TEST FAILED: remote call did not time out"); + } else { + System.err.println("remote call failed with exception:"); + connector.exception.printStackTrace(); + System.err.println(); - if (connector.exception instanceof MarshalException) { - System.err.println( - "TEST FAILED: MarshalException thrown, expecting " + - "java.rmi.ConnectException or ConnectIOException"); - } else if (connector.exception instanceof ConnectException || - connector.exception instanceof ConnectIOException) - { - System.err.println( - "TEST PASSED: java.rmi.ConnectException or " + - "ConnectIOException thrown"); - } else { - throw new RuntimeException( - "TEST FAILED: unexpected Exception thrown", - connector.exception); - } - } - } + if (connector.exception instanceof MarshalException) { + System.err.println( + "TEST FAILED: MarshalException thrown, expecting " + + "java.rmi.ConnectException or ConnectIOException"); + } else if (connector.exception instanceof ConnectException || + connector.exception instanceof ConnectIOException) + { + System.err.println( + "TEST PASSED: java.rmi.ConnectException or " + + "ConnectIOException thrown"); + } else { + throw new RuntimeException( + "TEST FAILED: unexpected Exception thrown", + connector.exception); + } + } + } } private static class Connector implements Runnable { - private final Registry registry; + private final Registry registry; - boolean success = false; + boolean success = false; Exception exception = null; - Connector(Registry registry) { - this.registry = registry; - } + Connector(Registry registry) { + this.registry = registry; + } - public void run() { - try { - registry.lookup("Dale Cooper"); - synchronized (this) { - success = true; - } - } catch (Exception e) { - synchronized (this) { - exception = e; - } - } - } + public void run() { + try { + registry.lookup("Dale Cooper"); + synchronized (this) { + success = true; + } + } catch (Exception e) { + synchronized (this) { + exception = e; + } + } + } } } diff --git a/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java b/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java index 43b8e96ad72..c74c021b486 100644 --- a/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java +++ b/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -51,81 +51,81 @@ public class HandshakeTimeout { public static void main(String[] args) throws Exception { - System.setProperty("sun.rmi.transport.tcp.handshakeTimeout", - String.valueOf(TIMEOUT / 2)); + System.setProperty("sun.rmi.transport.tcp.handshakeTimeout", + String.valueOf(TIMEOUT / 2)); - /* - * Listen on port, but never process connections made to it. - */ - ServerSocket serverSocket = new ServerSocket(PORT); + /* + * Listen on port, but never process connections made to it. + */ + ServerSocket serverSocket = new ServerSocket(PORT); - /* - * Attempt RMI call to port in separate thread. - */ - Registry registry = LocateRegistry.getRegistry(PORT); - Connector connector = new Connector(registry); - Thread t = new Thread(connector); - t.setDaemon(true); - t.start(); + /* + * Attempt RMI call to port in separate thread. + */ + Registry registry = LocateRegistry.getRegistry(PORT); + Connector connector = new Connector(registry); + Thread t = new Thread(connector); + t.setDaemon(true); + t.start(); - /* - * Wait for call attempt to finished, and analyze result. - */ - t.join(TIMEOUT); - synchronized (connector) { - if (connector.success) { - throw new RuntimeException( - "TEST FAILED: remote call succeeded??"); - } - if (connector.exception == null) { - throw new RuntimeException( - "TEST FAILED: remote call did not time out"); - } else { - System.err.println("remote call failed with exception:"); - connector.exception.printStackTrace(); - System.err.println(); + /* + * Wait for call attempt to finished, and analyze result. + */ + t.join(TIMEOUT); + synchronized (connector) { + if (connector.success) { + throw new RuntimeException( + "TEST FAILED: remote call succeeded??"); + } + if (connector.exception == null) { + throw new RuntimeException( + "TEST FAILED: remote call did not time out"); + } else { + System.err.println("remote call failed with exception:"); + connector.exception.printStackTrace(); + System.err.println(); - if (connector.exception instanceof MarshalException) { - System.err.println( - "TEST FAILED: MarshalException thrown, expecting " + - "java.rmi.ConnectException or ConnectIOException"); - } else if (connector.exception instanceof ConnectException || - connector.exception instanceof ConnectIOException) - { - System.err.println( - "TEST PASSED: java.rmi.ConnectException or " + - "ConnectIOException thrown"); - } else { - throw new RuntimeException( - "TEST FAILED: unexpected Exception thrown", - connector.exception); - } - } - } + if (connector.exception instanceof MarshalException) { + System.err.println( + "TEST FAILED: MarshalException thrown, expecting " + + "java.rmi.ConnectException or ConnectIOException"); + } else if (connector.exception instanceof ConnectException || + connector.exception instanceof ConnectIOException) + { + System.err.println( + "TEST PASSED: java.rmi.ConnectException or " + + "ConnectIOException thrown"); + } else { + throw new RuntimeException( + "TEST FAILED: unexpected Exception thrown", + connector.exception); + } + } + } } private static class Connector implements Runnable { - private final Registry registry; + private final Registry registry; - boolean success = false; + boolean success = false; Exception exception = null; - Connector(Registry registry) { - this.registry = registry; - } + Connector(Registry registry) { + this.registry = registry; + } - public void run() { - try { - registry.lookup("Dale Cooper"); - synchronized (this) { - success = true; - } - } catch (Exception e) { - synchronized (this) { - exception = e; - } - } - } + public void run() { + try { + registry.lookup("Dale Cooper"); + synchronized (this) { + success = true; + } + } catch (Exception e) { + synchronized (this) { + exception = e; + } + } + } } } diff --git a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java b/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java index 6f26b9b5554..8fbba5460cd 100644 --- a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java +++ b/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -53,65 +53,60 @@ interface MyRemoteInterface extends Remote { Remote getRemoteObject() throws RemoteException; } -public class HttpSocketTest extends UnicastRemoteObject +public class HttpSocketTest extends UnicastRemoteObject implements MyRemoteInterface { private static final String NAME = "HttpSocketTest"; private static final String REGNAME = - "//:" + TestLibrary.REGISTRY_PORT + "/" + NAME; + "//:" + TestLibrary.REGISTRY_PORT + "/" + NAME; public HttpSocketTest() throws RemoteException{} private Remote ro; public static void main(String[] args) - throws Exception + throws Exception { - - Registry registry = null; - TestLibrary.suggestSecurityManager(null); - - // Set the socket factory. - System.err.println("installing socket factory"); - RMISocketFactory.setSocketFactory(new RMIHttpToPortSocketFactory()); + Registry registry = null; - try { + TestLibrary.suggestSecurityManager(null); + + // Set the socket factory. + System.err.println("installing socket factory"); + RMISocketFactory.setSocketFactory(new RMIHttpToPortSocketFactory()); + + try { System.err.println("Starting registry"); registry = LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); } catch (Exception e) { - TestLibrary.bomb(e); - } + TestLibrary.bomb(e); + } - try { + try { - registry.rebind( NAME, new HttpSocketTest() ); - MyRemoteInterface httpTest = - (MyRemoteInterface)Naming.lookup( REGNAME ); - httpTest.setRemoteObject( new HttpSocketTest() ); - Remote r = httpTest.getRemoteObject(); + registry.rebind( NAME, new HttpSocketTest() ); + MyRemoteInterface httpTest = + (MyRemoteInterface)Naming.lookup( REGNAME ); + httpTest.setRemoteObject( new HttpSocketTest() ); + Remote r = httpTest.getRemoteObject(); - } catch (Exception e) { - TestLibrary.bomb(e); - } + } catch (Exception e) { + TestLibrary.bomb(e); + } } public void setRemoteObject( Remote ro ) throws RemoteException { - this.ro = ro; + this.ro = ro; } public Remote getRemoteObject() throws RemoteException { - return( this.ro ); + return( this.ro ); } } - - - - - diff --git a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest_Stub.java b/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest_Stub.java index d12b389d476..a8b2e342441 100644 --- a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest_Stub.java +++ b/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,102 +29,102 @@ public final class HttpSocketTest_Stub implements MyRemoteInterface, java.rmi.Remote { private static final java.rmi.server.Operation[] operations = { - new java.rmi.server.Operation("java.rmi.Remote getRemoteObject()"), - new java.rmi.server.Operation("void setRemoteObject(java.rmi.Remote)") + new java.rmi.server.Operation("java.rmi.Remote getRemoteObject()"), + new java.rmi.server.Operation("void setRemoteObject(java.rmi.Remote)") }; - + private static final long interfaceHash = 3775375480010579665L; - + private static final long serialVersionUID = 2; - + private static boolean useNewInvoke; private static java.lang.reflect.Method $method_getRemoteObject_0; private static java.lang.reflect.Method $method_setRemoteObject_1; - + static { - try { - java.rmi.server.RemoteRef.class.getMethod("invoke", - new java.lang.Class[] { - java.rmi.Remote.class, - java.lang.reflect.Method.class, - java.lang.Object[].class, - long.class - }); - useNewInvoke = true; - $method_getRemoteObject_0 = MyRemoteInterface.class.getMethod("getRemoteObject", new java.lang.Class[] {}); - $method_setRemoteObject_1 = MyRemoteInterface.class.getMethod("setRemoteObject", new java.lang.Class[] {java.rmi.Remote.class}); - } catch (java.lang.NoSuchMethodException e) { - useNewInvoke = false; - } + try { + java.rmi.server.RemoteRef.class.getMethod("invoke", + new java.lang.Class[] { + java.rmi.Remote.class, + java.lang.reflect.Method.class, + java.lang.Object[].class, + long.class + }); + useNewInvoke = true; + $method_getRemoteObject_0 = MyRemoteInterface.class.getMethod("getRemoteObject", new java.lang.Class[] {}); + $method_setRemoteObject_1 = MyRemoteInterface.class.getMethod("setRemoteObject", new java.lang.Class[] {java.rmi.Remote.class}); + } catch (java.lang.NoSuchMethodException e) { + useNewInvoke = false; + } } - + // constructors public HttpSocketTest_Stub() { - super(); + super(); } public HttpSocketTest_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of getRemoteObject() public java.rmi.Remote getRemoteObject() - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - Object $result = ref.invoke(this, $method_getRemoteObject_0, null, -2578437860804964265L); - return ((java.rmi.Remote) $result); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); - ref.invoke(call); - java.rmi.Remote $result; - try { - java.io.ObjectInput in = call.getInputStream(); - $result = (java.rmi.Remote) in.readObject(); - } catch (java.io.IOException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } catch (java.lang.ClassNotFoundException e) { - throw new java.rmi.UnmarshalException("error unmarshalling return", e); - } finally { - ref.done(call); - } - return $result; - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + Object $result = ref.invoke(this, $method_getRemoteObject_0, null, -2578437860804964265L); + return ((java.rmi.Remote) $result); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + ref.invoke(call); + java.rmi.Remote $result; + try { + java.io.ObjectInput in = call.getInputStream(); + $result = (java.rmi.Remote) in.readObject(); + } catch (java.io.IOException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } catch (java.lang.ClassNotFoundException e) { + throw new java.rmi.UnmarshalException("error unmarshalling return", e); + } finally { + ref.done(call); + } + return $result; + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } - + // implementation of setRemoteObject(Remote) public void setRemoteObject(java.rmi.Remote $param_Remote_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - if (useNewInvoke) { - ref.invoke(this, $method_setRemoteObject_1, new java.lang.Object[] {$param_Remote_1}, -7518632118115022871L); - } else { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); - try { - java.io.ObjectOutput out = call.getOutputStream(); - out.writeObject($param_Remote_1); - } catch (java.io.IOException e) { - throw new java.rmi.MarshalException("error marshalling arguments", e); - } - ref.invoke(call); - ref.done(call); - } - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + if (useNewInvoke) { + ref.invoke(this, $method_setRemoteObject_1, new java.lang.Object[] {$param_Remote_1}, -7518632118115022871L); + } else { + java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + try { + java.io.ObjectOutput out = call.getOutputStream(); + out.writeObject($param_Remote_1); + } catch (java.io.IOException e) { + throw new java.rmi.MarshalException("error marshalling arguments", e); + } + ref.invoke(call); + ref.done(call); + } + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java b/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java index 23075675a90..8f1bd834b31 100644 --- a/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java +++ b/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -60,109 +60,109 @@ public class PinClientSocketFactory { private static final int SESSIONS = 50; public interface Factory extends Remote { - Session getSession() throws RemoteException; + Session getSession() throws RemoteException; } public interface Session extends Remote { - void ping() throws RemoteException; + void ping() throws RemoteException; } private static class FactoryImpl implements Factory { - FactoryImpl() { } - public Session getSession() throws RemoteException { - Session impl = new SessionImpl(); - UnicastRemoteObject.exportObject(impl, 0, new CSF(), new SSF()); - // return impl instead of stub to work around 4114579 - return impl; - } + FactoryImpl() { } + public Session getSession() throws RemoteException { + Session impl = new SessionImpl(); + UnicastRemoteObject.exportObject(impl, 0, new CSF(), new SSF()); + // return impl instead of stub to work around 4114579 + return impl; + } } private static class SessionImpl implements Session { - SessionImpl() { } - public void ping() { } + SessionImpl() { } + public void ping() { } } public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 4486732\n"); + System.err.println("\nRegression test for bug 4486732\n"); - Factory factoryImpl = new FactoryImpl(); - Factory factoryStub = - (Factory) UnicastRemoteObject.exportObject(factoryImpl, 0); - for (int i = 0; i < SESSIONS; i++) { - Session session = factoryStub.getSession(); - session.ping(); - } - UnicastRemoteObject.unexportObject(factoryImpl, true); + Factory factoryImpl = new FactoryImpl(); + Factory factoryStub = + (Factory) UnicastRemoteObject.exportObject(factoryImpl, 0); + for (int i = 0; i < SESSIONS; i++) { + Session session = factoryStub.getSession(); + session.ping(); + } + UnicastRemoteObject.unexportObject(factoryImpl, true); - Registry registryImpl = LocateRegistry.createRegistry(PORT); - CSF csf = new CSF(); - Reference registryRef = new WeakReference(csf); - Registry registryStub = LocateRegistry.getRegistry("", PORT, csf); - csf = null; - registryStub.list(); - registryStub = null; - UnicastRemoteObject.unexportObject(registryImpl, true); + Registry registryImpl = LocateRegistry.createRegistry(PORT); + CSF csf = new CSF(); + Reference registryRef = new WeakReference(csf); + Registry registryStub = LocateRegistry.getRegistry("", PORT, csf); + csf = null; + registryStub.list(); + registryStub = null; + UnicastRemoteObject.unexportObject(registryImpl, true); - System.gc(); - // allow connections to time out - Thread.sleep(3 * Long.getLong("sun.rmi.transport.connectionTimeout", - 15000)); - System.gc(); + System.gc(); + // allow connections to time out + Thread.sleep(3 * Long.getLong("sun.rmi.transport.connectionTimeout", + 15000)); + System.gc(); - if (CSF.deserializedInstances.size() != SESSIONS) { - throw new Error("unexpected number of deserialized instances: " + - CSF.deserializedInstances.size()); - } + if (CSF.deserializedInstances.size() != SESSIONS) { + throw new Error("unexpected number of deserialized instances: " + + CSF.deserializedInstances.size()); + } - int nonNullCount = 0; - for (Reference ref : CSF.deserializedInstances) { - csf = ref.get(); - if (csf != null) { - System.err.println("non-null deserialized instance: " + csf); - nonNullCount++; - } - } - if (nonNullCount > 0) { - throw new Error("TEST FAILED: " + - nonNullCount + " non-null deserialized instances"); - } + int nonNullCount = 0; + for (Reference ref : CSF.deserializedInstances) { + csf = ref.get(); + if (csf != null) { + System.err.println("non-null deserialized instance: " + csf); + nonNullCount++; + } + } + if (nonNullCount > 0) { + throw new Error("TEST FAILED: " + + nonNullCount + " non-null deserialized instances"); + } - csf = registryRef.get(); - if (csf != null) { - System.err.println("non-null registry instance: " + csf); - throw new Error("TEST FAILED: non-null registry instance"); - } + csf = registryRef.get(); + if (csf != null) { + System.err.println("non-null registry instance: " + csf); + throw new Error("TEST FAILED: non-null registry instance"); + } - System.err.println("TEST PASSED"); + System.err.println("TEST PASSED"); } private static class CSF implements RMIClientSocketFactory, Serializable { - static final List> deserializedInstances = - Collections.synchronizedList(new ArrayList>()); - private static final AtomicInteger count = new AtomicInteger(0); - private int num = count.incrementAndGet(); - CSF() { } - public Socket createSocket(String host, int port) throws IOException { - return new Socket(host, port); - } - public int hashCode() { - return num; - } - public boolean equals(Object obj) { - return obj instanceof CSF && ((CSF) obj).num == num; - } - private void readObject(ObjectInputStream in) - throws IOException, ClassNotFoundException - { - in.defaultReadObject(); - deserializedInstances.add(new WeakReference(this)); - } + static final List> deserializedInstances = + Collections.synchronizedList(new ArrayList>()); + private static final AtomicInteger count = new AtomicInteger(0); + private int num = count.incrementAndGet(); + CSF() { } + public Socket createSocket(String host, int port) throws IOException { + return new Socket(host, port); + } + public int hashCode() { + return num; + } + public boolean equals(Object obj) { + return obj instanceof CSF && ((CSF) obj).num == num; + } + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + deserializedInstances.add(new WeakReference(this)); + } } private static class SSF implements RMIServerSocketFactory { - SSF() { } - public ServerSocket createServerSocket(int port) throws IOException { - return new ServerSocket(port); - } + SSF() { } + public ServerSocket createServerSocket(int port) throws IOException { + return new ServerSocket(port); + } } } diff --git a/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java b/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java index 590a1ce6e91..b85ad3a80c9 100644 --- a/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java +++ b/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -45,45 +45,45 @@ import java.rmi.server.UnicastRemoteObject; public class PinLastArguments { public interface Ping extends Remote { - void ping(Object first, Object second) throws RemoteException; + void ping(Object first, Object second) throws RemoteException; } private static class PingImpl implements Ping { - PingImpl() { } - public void ping(Object first, Object second) { - System.err.println("ping invoked: " + first + ", " + second); - } + PingImpl() { } + public void ping(Object first, Object second) { + System.err.println("ping invoked: " + first + ", " + second); + } } public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 6332349\n"); + System.err.println("\nRegression test for bug 6332349\n"); - Ping impl = new PingImpl(); - Reference ref = new WeakReference(impl); - try { - Ping stub = (Ping) UnicastRemoteObject.exportObject(impl, 0); - Object notSerializable = new Object(); - stub.ping(impl, null); - try { - stub.ping(impl, notSerializable); - } catch (MarshalException e) { - if (e.getCause() instanceof NotSerializableException) { - System.err.println("ping invocation failed as expected"); - } else { - throw e; - } - } - } finally { - UnicastRemoteObject.unexportObject(impl, true); - } - impl = null; + Ping impl = new PingImpl(); + Reference ref = new WeakReference(impl); + try { + Ping stub = (Ping) UnicastRemoteObject.exportObject(impl, 0); + Object notSerializable = new Object(); + stub.ping(impl, null); + try { + stub.ping(impl, notSerializable); + } catch (MarshalException e) { + if (e.getCause() instanceof NotSerializableException) { + System.err.println("ping invocation failed as expected"); + } else { + throw e; + } + } + } finally { + UnicastRemoteObject.unexportObject(impl, true); + } + impl = null; - System.gc(); + System.gc(); - if (ref.get() != null) { - throw new Error("TEST FAILED: impl not garbage collected"); - } + if (ref.get() != null) { + throw new Error("TEST FAILED: impl not garbage collected"); + } - System.err.println("TEST PASSED"); + System.err.println("TEST PASSED"); } } diff --git a/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java b/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java index bf74bf847cc..fa810c4437c 100644 --- a/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java +++ b/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -46,22 +46,22 @@ public class RapidExportUnexport { private static final long TIMEOUT = 60000; public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 6275081\n"); + System.err.println("\nRegression test for bug 6275081\n"); - Remote impl = new Remote() { }; - long start = System.currentTimeMillis(); - for (int i = 0; i < REPS; i++) { - System.err.println(i); - UnicastRemoteObject.exportObject(impl, PORT); - UnicastRemoteObject.unexportObject(impl, true); - Thread.sleep(1); // work around BindException (bug?) - } - long delta = System.currentTimeMillis() - start; - System.err.println(REPS + " export/unexport operations took " + - delta + "ms"); - if (delta > TIMEOUT) { - throw new Error("TEST FAILED: took over " + TIMEOUT + "ms"); - } - System.err.println("TEST PASSED"); + Remote impl = new Remote() { }; + long start = System.currentTimeMillis(); + for (int i = 0; i < REPS; i++) { + System.err.println(i); + UnicastRemoteObject.exportObject(impl, PORT); + UnicastRemoteObject.unexportObject(impl, true); + Thread.sleep(1); // work around BindException (bug?) + } + long delta = System.currentTimeMillis() - start; + System.err.println(REPS + " export/unexport operations took " + + delta + "ms"); + if (delta > TIMEOUT) { + throw new Error("TEST FAILED: took over " + TIMEOUT + "ms"); + } + System.err.println("TEST PASSED"); } } diff --git a/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java b/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java index a9c4d8b595b..0bdd65d5bb8 100644 --- a/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java +++ b/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -50,134 +50,134 @@ import java.net.*; public class ReadTimeoutTest { - private static final int DELAY = 5000; // milliseconds + private static final int DELAY = 5000; // milliseconds public static void main(String[] args) - throws Exception + throws Exception { - // Make trouble for ourselves - if (System.getSecurityManager() == null) - System.setSecurityManager(new RMISecurityManager()); - - // Flaky code alert - hope this is executed before TCPTransport. - System.setProperty("sun.rmi.transport.tcp.readTimeout", Integer.toString(DELAY)); + // Make trouble for ourselves + if (System.getSecurityManager() == null) + System.setSecurityManager(new RMISecurityManager()); - // Set the socket factory. - System.err.println("(installing socket factory)"); - SomeFactory fac = new SomeFactory(); - RMISocketFactory.setSocketFactory(fac); + // Flaky code alert - hope this is executed before TCPTransport. + System.setProperty("sun.rmi.transport.tcp.readTimeout", Integer.toString(DELAY)); - // Create remote object - TestImpl impl = new TestImpl(); + // Set the socket factory. + System.err.println("(installing socket factory)"); + SomeFactory fac = new SomeFactory(); + RMISocketFactory.setSocketFactory(fac); - // Export and get which port. - System.err.println("(exporting remote object)"); - TestIface stub = impl.export(); - Socket DoS = null; - try { - int port = fac.whichPort(); + // Create remote object + TestImpl impl = new TestImpl(); - // Sanity - if (port == 0) - throw new Error("TEST FAILED: export didn't reserve a port(?)"); - - // Now, connect to that port - //Thread.sleep(2000); - System.err.println("(connecting to listening port on 127.0.0.1:" + - port + ")"); - DoS = new Socket("127.0.0.1", port); - InputStream stream = DoS.getInputStream(); + // Export and get which port. + System.err.println("(exporting remote object)"); + TestIface stub = impl.export(); + Socket DoS = null; + try { + int port = fac.whichPort(); - // Read on the socket in the background - boolean[] successful = new boolean[] { false }; - (new SomeReader(stream, successful)).start(); + // Sanity + if (port == 0) + throw new Error("TEST FAILED: export didn't reserve a port(?)"); - // Wait for completion - int nretries = 4; - while (nretries-- > 0) { - if (successful[0]) - break; - Thread.sleep(DELAY); - } + // Now, connect to that port + //Thread.sleep(2000); + System.err.println("(connecting to listening port on 127.0.0.1:" + + port + ")"); + DoS = new Socket("127.0.0.1", port); + InputStream stream = DoS.getInputStream(); - if (successful[0]) { - System.err.println("TEST PASSED."); - } else { - throw new Error("TEST FAILED."); - } + // Read on the socket in the background + boolean[] successful = new boolean[] { false }; + (new SomeReader(stream, successful)).start(); - } finally { - try { - if (DoS != null) - DoS.close(); // aborts the reader if still blocked - impl.unexport(); - } catch (Throwable unmatter) { - } - } + // Wait for completion + int nretries = 4; + while (nretries-- > 0) { + if (successful[0]) + break; + Thread.sleep(DELAY); + } - // Should exit here + if (successful[0]) { + System.err.println("TEST PASSED."); + } else { + throw new Error("TEST FAILED."); + } + + } finally { + try { + if (DoS != null) + DoS.close(); // aborts the reader if still blocked + impl.unexport(); + } catch (Throwable unmatter) { + } + } + + // Should exit here } private static class SomeFactory - extends RMISocketFactory + extends RMISocketFactory { - private int servport = 0; + private int servport = 0; - public Socket createSocket(String h, int p) - throws IOException - { - return (new Socket(h, p)); - } + public Socket createSocket(String h, int p) + throws IOException + { + return (new Socket(h, p)); + } - /** Create a server socket and remember which port it's on. - * Aborts if createServerSocket(0) is called twice, because then - * it doesn't know whether to remember the first or second port. - */ - public ServerSocket createServerSocket(int p) - throws IOException - { - ServerSocket ss; - ss = new ServerSocket(p); - if (p == 0) { - if (servport != 0) { - System.err.println("TEST FAILED: " + - "Duplicate createServerSocket(0)"); - throw new Error("Test aborted (createServerSocket)"); - } - servport = ss.getLocalPort(); - } - return (ss); - } + /** Create a server socket and remember which port it's on. + * Aborts if createServerSocket(0) is called twice, because then + * it doesn't know whether to remember the first or second port. + */ + public ServerSocket createServerSocket(int p) + throws IOException + { + ServerSocket ss; + ss = new ServerSocket(p); + if (p == 0) { + if (servport != 0) { + System.err.println("TEST FAILED: " + + "Duplicate createServerSocket(0)"); + throw new Error("Test aborted (createServerSocket)"); + } + servport = ss.getLocalPort(); + } + return (ss); + } - /** Return which port was reserved by createServerSocket(0). - * If the return value was 0, createServerSocket(0) wasn't called. - */ - public int whichPort() { - return (servport); - } + /** Return which port was reserved by createServerSocket(0). + * If the return value was 0, createServerSocket(0) wasn't called. + */ + public int whichPort() { + return (servport); + } } // end class SomeFactory protected static class SomeReader extends Thread { - private InputStream readon; - private boolean[] vec; + private InputStream readon; + private boolean[] vec; - public SomeReader(InputStream s, boolean[] successvec) { - super(); - this.setDaemon(true); - this.readon = s; - this.vec = successvec; - } + public SomeReader(InputStream s, boolean[] successvec) { + super(); + this.setDaemon(true); + this.readon = s; + this.vec = successvec; + } - public void run() { - try { - int c = this.readon.read(); - if (c != -1) - throw new Error ("Server returned " + c); - this.vec[0] = true; + public void run() { + try { + int c = this.readon.read(); + if (c != -1) + throw new Error ("Server returned " + c); + this.vec[0] = true; - } catch (IOException e) { - e.printStackTrace(); - } - } + } catch (IOException e) { + e.printStackTrace(); + } + } } // end class SomeReader } diff --git a/jdk/test/java/rmi/transport/readTimeout/TestIface.java b/jdk/test/java/rmi/transport/readTimeout/TestIface.java index 793afbba06a..a7096a0b2ca 100644 --- a/jdk/test/java/rmi/transport/readTimeout/TestIface.java +++ b/jdk/test/java/rmi/transport/readTimeout/TestIface.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,5 +27,5 @@ public interface TestIface extends Remote { public String testCall(String ign) - throws RemoteException; + throws RemoteException; } diff --git a/jdk/test/java/rmi/transport/readTimeout/TestImpl.java b/jdk/test/java/rmi/transport/readTimeout/TestImpl.java index eae651b5247..3fc6af8b29a 100644 --- a/jdk/test/java/rmi/transport/readTimeout/TestImpl.java +++ b/jdk/test/java/rmi/transport/readTimeout/TestImpl.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,19 +32,18 @@ public class TestImpl } public TestIface export() - throws RemoteException + throws RemoteException { - return (TestIface)UnicastRemoteObject.exportObject(this); + return (TestIface)UnicastRemoteObject.exportObject(this); } public void unexport() - throws NoSuchObjectException + throws NoSuchObjectException { - UnicastRemoteObject.unexportObject(this, true); + UnicastRemoteObject.unexportObject(this, true); } public String testCall(String ign) { - return ("OK"); + return ("OK"); } } - diff --git a/jdk/test/java/rmi/transport/readTimeout/TestImpl_Stub.java b/jdk/test/java/rmi/transport/readTimeout/TestImpl_Stub.java index 74c716d9136..223ce7915c5 100644 --- a/jdk/test/java/rmi/transport/readTimeout/TestImpl_Stub.java +++ b/jdk/test/java/rmi/transport/readTimeout/TestImpl_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,38 +29,38 @@ public final class TestImpl_Stub implements TestIface { private static final long serialVersionUID = 2; - + private static java.lang.reflect.Method $method_testCall_0; - + static { - try { - $method_testCall_0 = TestIface.class.getMethod("testCall", new java.lang.Class[] {java.lang.String.class}); - } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError( - "stub class initialization failed"); - } + try { + $method_testCall_0 = TestIface.class.getMethod("testCall", new java.lang.Class[] {java.lang.String.class}); + } catch (java.lang.NoSuchMethodException e) { + throw new java.lang.NoSuchMethodError( + "stub class initialization failed"); + } } - + // constructors public TestImpl_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + // methods from remote interfaces - + // implementation of testCall(String) public java.lang.String testCall(java.lang.String $param_String_1) - throws java.rmi.RemoteException + throws java.rmi.RemoteException { - try { - Object $result = ref.invoke(this, $method_testCall_0, new java.lang.Object[] {$param_String_1}, -4495720265115653109L); - return ((java.lang.String) $result); - } catch (java.lang.RuntimeException e) { - throw e; - } catch (java.rmi.RemoteException e) { - throw e; - } catch (java.lang.Exception e) { - throw new java.rmi.UnexpectedException("undeclared checked exception", e); - } + try { + Object $result = ref.invoke(this, $method_testCall_0, new java.lang.Object[] {$param_String_1}, -4495720265115653109L); + return ((java.lang.String) $result); + } catch (java.lang.RuntimeException e) { + throw e; + } catch (java.rmi.RemoteException e) { + throw e; + } catch (java.lang.Exception e) { + throw new java.rmi.UnexpectedException("undeclared checked exception", e); + } } } diff --git a/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java b/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java index be40e1553a7..cf386280945 100644 --- a/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java +++ b/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -53,32 +53,32 @@ public class ReuseDefaultPort implements Remote { private ReuseDefaultPort() { } public static void main(String[] args) throws Exception { - System.err.println("\nRegression test for bug 6269166\n"); - RMISocketFactory.setSocketFactory(new SF()); - Remote impl = new ReuseDefaultPort(); - Remote stub = UnicastRemoteObject.exportObject(impl, 0); - System.err.println("- exported object: " + stub); - try { - Registry registry = LocateRegistry.createRegistry(PORT); - System.err.println("- exported registry: " + registry); - System.err.println("TEST PASSED"); - } finally { - UnicastRemoteObject.unexportObject(impl, true); - } + System.err.println("\nRegression test for bug 6269166\n"); + RMISocketFactory.setSocketFactory(new SF()); + Remote impl = new ReuseDefaultPort(); + Remote stub = UnicastRemoteObject.exportObject(impl, 0); + System.err.println("- exported object: " + stub); + try { + Registry registry = LocateRegistry.createRegistry(PORT); + System.err.println("- exported registry: " + registry); + System.err.println("TEST PASSED"); + } finally { + UnicastRemoteObject.unexportObject(impl, true); + } } private static class SF extends RMISocketFactory { - private static RMISocketFactory defaultFactory = - RMISocketFactory.getDefaultSocketFactory(); - SF() { } - public Socket createSocket(String host, int port) throws IOException { - return defaultFactory.createSocket(host, port); - } - public ServerSocket createServerSocket(int port) throws IOException { - if (port == 0) { - port = PORT; - } - return defaultFactory.createServerSocket(port); - } + private static RMISocketFactory defaultFactory = + RMISocketFactory.getDefaultSocketFactory(); + SF() { } + public Socket createSocket(String host, int port) throws IOException { + return defaultFactory.createSocket(host, port); + } + public ServerSocket createServerSocket(int port) throws IOException { + if (port == 0) { + port = PORT; + } + return defaultFactory.createServerSocket(port); + } } } diff --git a/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java b/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java index a2855ffe4a7..245942ddcd7 100644 --- a/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java +++ b/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -60,80 +60,80 @@ public class RuntimeThreadInheritanceLeak implements Remote { public static void main(String[] args) { - System.err.println("\nRegression test for bug 4404702\n"); + System.err.println("\nRegression test for bug 4404702\n"); - /* - * HACK: Work around the fact that java.util.logging.LogManager's - * (singleton) construction also has this bug-- it will register a - * "shutdown hook", i.e. a thread, which will inherit and pin the - * current thread's context class loader for the lifetime of the VM-- - * by causing the LogManager to be initialized now, instead of by - * RMI when our special context class loader is set. - */ - java.util.logging.LogManager.getLogManager(); + /* + * HACK: Work around the fact that java.util.logging.LogManager's + * (singleton) construction also has this bug-- it will register a + * "shutdown hook", i.e. a thread, which will inherit and pin the + * current thread's context class loader for the lifetime of the VM-- + * by causing the LogManager to be initialized now, instead of by + * RMI when our special context class loader is set. + */ + java.util.logging.LogManager.getLogManager(); - /* - * HACK: Work around the fact that the non-native, thread-based - * SecureRandom seed generator (ThreadedSeedGenerator) seems to - * have this bug too (which had been causing this test to fail - * when run with jtreg on Windows XP-- see 4910382). - */ - (new java.security.SecureRandom()).nextInt(); + /* + * HACK: Work around the fact that the non-native, thread-based + * SecureRandom seed generator (ThreadedSeedGenerator) seems to + * have this bug too (which had been causing this test to fail + * when run with jtreg on Windows XP-- see 4910382). + */ + (new java.security.SecureRandom()).nextInt(); - RuntimeThreadInheritanceLeak obj = new RuntimeThreadInheritanceLeak(); + RuntimeThreadInheritanceLeak obj = new RuntimeThreadInheritanceLeak(); - try { - ClassLoader loader = URLClassLoader.newInstance(new URL[0]); - ReferenceQueue refQueue = new ReferenceQueue(); - Reference loaderRef = new WeakReference(loader, refQueue); - System.err.println("created loader: " + loader); + try { + ClassLoader loader = URLClassLoader.newInstance(new URL[0]); + ReferenceQueue refQueue = new ReferenceQueue(); + Reference loaderRef = new WeakReference(loader, refQueue); + System.err.println("created loader: " + loader); - Thread.currentThread().setContextClassLoader(loader); - UnicastRemoteObject.exportObject(obj); - Thread.currentThread().setContextClassLoader( - ClassLoader.getSystemClassLoader()); - System.err.println( - "exported remote object with loader as context class loader"); + Thread.currentThread().setContextClassLoader(loader); + UnicastRemoteObject.exportObject(obj); + Thread.currentThread().setContextClassLoader( + ClassLoader.getSystemClassLoader()); + System.err.println( + "exported remote object with loader as context class loader"); - loader = null; - System.err.println("nulled strong reference to loader"); + loader = null; + System.err.println("nulled strong reference to loader"); - UnicastRemoteObject.unexportObject(obj, true); - System.err.println("unexported remote object"); + UnicastRemoteObject.unexportObject(obj, true); + System.err.println("unexported remote object"); - /* - * HACK: Work around the fact that the sun.misc.GC daemon thread - * also has this bug-- it will have inherited our loader as its - * context class loader-- by giving it a chance to pass away. - */ - Thread.sleep(2000); - System.gc(); + /* + * HACK: Work around the fact that the sun.misc.GC daemon thread + * also has this bug-- it will have inherited our loader as its + * context class loader-- by giving it a chance to pass away. + */ + Thread.sleep(2000); + System.gc(); - System.err.println( - "waiting to be notified of loader being weakly reachable..."); - Reference dequeued = refQueue.remove(TIMEOUT); - if (dequeued == null) { - System.err.println( - "TEST FAILED: loader not deteced weakly reachable"); - dumpThreads(); - throw new RuntimeException( - "TEST FAILED: loader not detected weakly reachable"); - } + System.err.println( + "waiting to be notified of loader being weakly reachable..."); + Reference dequeued = refQueue.remove(TIMEOUT); + if (dequeued == null) { + System.err.println( + "TEST FAILED: loader not deteced weakly reachable"); + dumpThreads(); + throw new RuntimeException( + "TEST FAILED: loader not detected weakly reachable"); + } - System.err.println( - "TEST PASSED: loader detected weakly reachable"); - dumpThreads(); + System.err.println( + "TEST PASSED: loader detected weakly reachable"); + dumpThreads(); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new RuntimeException("TEST FAILED: unexpected exception", e); - } finally { - try { - UnicastRemoteObject.unexportObject(obj, true); - } catch (RemoteException e) { - } - } + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException("TEST FAILED: unexpected exception", e); + } finally { + try { + UnicastRemoteObject.unexportObject(obj, true); + } catch (RemoteException e) { + } + } } /** @@ -141,19 +141,19 @@ public class RuntimeThreadInheritanceLeak implements Remote { * including their context class loaders. **/ private static void dumpThreads() { - System.err.println( - "current live threads and their context class loaders:"); - Map threads = Thread.getAllStackTraces(); - for (Iterator iter = threads.entrySet().iterator(); iter.hasNext();) { - Map.Entry e = (Map.Entry) iter.next(); - Thread t = (Thread) e.getKey(); - System.err.println(" thread: " + t); - System.err.println(" context class loader: " + - t.getContextClassLoader()); - StackTraceElement[] trace = (StackTraceElement[]) e.getValue(); - for (int i = 0; i < trace.length; i++) { - System.err.println(" " + trace[i]); - } - } + System.err.println( + "current live threads and their context class loaders:"); + Map threads = Thread.getAllStackTraces(); + for (Iterator iter = threads.entrySet().iterator(); iter.hasNext();) { + Map.Entry e = (Map.Entry) iter.next(); + Thread t = (Thread) e.getKey(); + System.err.println(" thread: " + t); + System.err.println(" context class loader: " + + t.getContextClassLoader()); + StackTraceElement[] trace = (StackTraceElement[]) e.getValue(); + for (int i = 0; i < trace.length; i++) { + System.err.println(" " + trace[i]); + } + } } } diff --git a/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak_Stub.java b/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak_Stub.java index 016142118f9..bc17d11e8db 100644 --- a/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak_Stub.java +++ b/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak_Stub.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,10 +29,10 @@ public final class RuntimeThreadInheritanceLeak_Stub implements java.rmi.Remote { private static final long serialVersionUID = 2; - + // constructors public RuntimeThreadInheritanceLeak_Stub(java.rmi.server.RemoteRef ref) { - super(ref); + super(ref); } - + } From 659a8dc7d5553fd0edee1c08a77361c480bb767d Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 1 Apr 2008 16:14:18 -0700 Subject: [PATCH 246/274] 6681646: Relocking of a scalar replaced object during deoptimization is broken Relocking of a thread-local object during deoptimization is broken Reviewed-by: kbr, jrose, never --- .../src/share/vm/runtime/deoptimization.cpp | 55 ++++++++++++------- .../src/share/vm/runtime/deoptimization.hpp | 2 +- hotspot/src/share/vm/runtime/vframe.cpp | 2 +- hotspot/src/share/vm/runtime/vframe.hpp | 5 +- hotspot/src/share/vm/runtime/vframe_hp.cpp | 4 +- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 444925938be..ccca77a5e13 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -143,6 +143,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread // relock objects if synchronization on them was eliminated. if (DoEscapeAnalysis) { if (EliminateAllocations) { + assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); GrowableArray* objects = chunk->at(0)->scope()->objects(); bool reallocated = false; if (objects != NULL) { @@ -162,19 +163,26 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread } } if (EliminateLocks) { +#ifndef PRODUCT + bool first = true; +#endif for (int i = 0; i < chunk->length(); i++) { - GrowableArray* monitors = chunk->at(i)->scope()->monitors(); - if (monitors != NULL) { - relock_objects(&deoptee, &map, monitors); + compiledVFrame* cvf = chunk->at(i); + assert (cvf->scope() != NULL,"expect only compiled java frames"); + GrowableArray* monitors = cvf->monitors(); + if (monitors->is_nonempty()) { + relock_objects(monitors, thread); #ifndef PRODUCT if (TraceDeoptimization) { ttyLocker ttyl; - tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); for (int j = 0; j < monitors->length(); j++) { - MonitorValue* mv = monitors->at(j); - if (mv->eliminated()) { - StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner()); - tty->print_cr(" object <" INTPTR_FORMAT "> locked", owner->get_obj()()); + MonitorInfo* mi = monitors->at(j); + if (mi->eliminated()) { + if (first) { + first = false; + tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); + } + tty->print_cr(" object <" INTPTR_FORMAT "> locked", mi->owner()); } } } @@ -799,18 +807,27 @@ void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableAr // relock objects for which synchronization was eliminated -void Deoptimization::relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray* monitors) { +void Deoptimization::relock_objects(GrowableArray* monitors, JavaThread* thread) { for (int i = 0; i < monitors->length(); i++) { - MonitorValue* mv = monitors->at(i); - StackValue* owner = StackValue::create_stack_value(fr, reg_map, mv->owner()); - if (mv->eliminated()) { - Handle obj = owner->get_obj(); - assert(obj.not_null(), "reallocation was missed"); - BasicLock* lock = StackValue::resolve_monitor_lock(fr, mv->basic_lock()); - lock->set_displaced_header(obj->mark()); - obj->set_mark((markOop) lock); + MonitorInfo* mon_info = monitors->at(i); + if (mon_info->eliminated()) { + assert(mon_info->owner() != NULL, "reallocation was missed"); + Handle obj = Handle(mon_info->owner()); + markOop mark = obj->mark(); + if (UseBiasedLocking && mark->has_bias_pattern()) { + // New allocated objects may have the mark set to anonymously biased. + // Also the deoptimized method may called methods with synchronization + // where the thread-local object is bias locked to the current thread. + assert(mark->is_biased_anonymously() || + mark->biased_locker() == thread, "should be locked to current thread"); + // Reset mark word to unbiased prototype. + markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); + obj->set_mark(unbiased_prototype); + } + BasicLock* lock = mon_info->lock(); + ObjectSynchronizer::slow_enter(obj, lock, thread); } - assert(owner->get_obj()->is_locked(), "object must be locked now"); + assert(mon_info->owner()->is_locked(), "object must be locked now"); } } @@ -916,7 +933,7 @@ static void collect_monitors(compiledVFrame* cvf, GrowableArray* objects GrowableArray* monitors = cvf->monitors(); for (int i = 0; i < monitors->length(); i++) { MonitorInfo* mon_info = monitors->at(i); - if (mon_info->owner() != NULL) { + if (mon_info->owner() != NULL && !mon_info->eliminated()) { objects_to_revoke->append(Handle(mon_info->owner())); } } diff --git a/hotspot/src/share/vm/runtime/deoptimization.hpp b/hotspot/src/share/vm/runtime/deoptimization.hpp index 63565704a69..6edb6a08936 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.hpp +++ b/hotspot/src/share/vm/runtime/deoptimization.hpp @@ -105,7 +105,7 @@ class Deoptimization : AllStatic { static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj); static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects); - static void relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray* monitors); + static void relock_objects(GrowableArray* monitors, JavaThread* thread); NOT_PRODUCT(static void print_objects(GrowableArray* objects);) #endif // COMPILER2 diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp index fdb2864df39..3e9b65bfc03 100644 --- a/hotspot/src/share/vm/runtime/vframe.cpp +++ b/hotspot/src/share/vm/runtime/vframe.cpp @@ -206,7 +206,7 @@ GrowableArray* interpretedVFrame::monitors() const { for (BasicObjectLock* current = (fr().previous_monitor_in_interpreter_frame(fr().interpreter_frame_monitor_begin())); current >= fr().interpreter_frame_monitor_end(); current = fr().previous_monitor_in_interpreter_frame(current)) { - result->push(new MonitorInfo(current->obj(), current->lock())); + result->push(new MonitorInfo(current->obj(), current->lock(), false)); } return result; } diff --git a/hotspot/src/share/vm/runtime/vframe.hpp b/hotspot/src/share/vm/runtime/vframe.hpp index b62a6f76ffb..2b1b827b1fd 100644 --- a/hotspot/src/share/vm/runtime/vframe.hpp +++ b/hotspot/src/share/vm/runtime/vframe.hpp @@ -230,15 +230,18 @@ class MonitorInfo : public ResourceObj { private: oop _owner; // the object owning the monitor BasicLock* _lock; + bool _eliminated; public: // Constructor - MonitorInfo(oop owner, BasicLock* lock) { + MonitorInfo(oop owner, BasicLock* lock, bool eliminated) { _owner = owner; _lock = lock; + _eliminated = eliminated; } // Accessors oop owner() const { return _owner; } BasicLock* lock() const { return _lock; } + bool eliminated() const { return _eliminated; } }; class vframeStreamCommon : StackObj { diff --git a/hotspot/src/share/vm/runtime/vframe_hp.cpp b/hotspot/src/share/vm/runtime/vframe_hp.cpp index 3399e23a5d8..35f0713a23f 100644 --- a/hotspot/src/share/vm/runtime/vframe_hp.cpp +++ b/hotspot/src/share/vm/runtime/vframe_hp.cpp @@ -190,7 +190,7 @@ GrowableArray* compiledVFrame::monitors() const { // Casting away const frame& fr = (frame&) _fr; MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm), - fr.compiled_synchronized_native_monitor(nm)); + fr.compiled_synchronized_native_monitor(nm), false); monitors->push(info); return monitors; } @@ -202,7 +202,7 @@ GrowableArray* compiledVFrame::monitors() const { for (int index = 0; index < monitors->length(); index++) { MonitorValue* mv = monitors->at(index); StackValue *owner_sv = create_stack_value(mv->owner()); // it is an oop - result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()))); + result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()), mv->eliminated())); } return result; } From 70bcd151a03823c0034918b74bf8ecc44cefbf89 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 2 Apr 2008 11:20:52 +0100 Subject: [PATCH 247/274] 6569789: Compiler test lang/TYPE/type153/type15304/type15304.html fails since jdk7 b05 Improved glb on type-inference Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Infer.java | 13 ++++++ .../generics/inference/6569789/T6569789.java | 44 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 langtools/test/tools/javac/generics/inference/6569789/T6569789.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 071d2fc60f2..3539a50c9e0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -157,6 +157,19 @@ public class Infer { if (isSubClass(bs.head, that.hibounds)) that.inst = types.fromUnknownFun.apply(bs.head); } + if (that.inst == null) { + int classCount = 0, interfaceCount = 0; + for (Type t : that.hibounds) { + if (t.tag == CLASS) { + if (t.isInterface()) + interfaceCount++; + else + classCount++; + } + } + if ((that.hibounds.size() == classCount + interfaceCount) && classCount == 1) + that.inst = types.makeCompoundType(that.hibounds); + } if (that.inst == null || !types.isSubtypeUnchecked(that.inst, that.hibounds, warn)) throw ambiguousNoInstanceException .setMessage("no.unique.maximal.instance.exists", diff --git a/langtools/test/tools/javac/generics/inference/6569789/T6569789.java b/langtools/test/tools/javac/generics/inference/6569789/T6569789.java new file mode 100644 index 00000000000..d7036ff98f7 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/6569789/T6569789.java @@ -0,0 +1,44 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6569789 + * @summary Compiler test lang/TYPE/type153/type15304/type15304.html fails since jdk7 b05 + * @compile T6569789.java + */ + +class C {} +interface I {} +interface I1 {} +interface I2 {} +class CT extends C implements I, I1, I2 {} + +public class T6569789 { + public static void m() { + CT ct = new CT(); + testMethod(ct); + } + + static void testMethod(T t) {} +} \ No newline at end of file From 8ef814eb9cf39794f4126044b8d699195ba77b2c Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 2 Apr 2008 11:38:16 +0100 Subject: [PATCH 248/274] 6509042: javac rejects class literals in enum constructors Javac now distinguish between enum class literals and static fields Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Attr.java | 14 +++++-- langtools/test/tools/javac/enum/T6509042.java | 41 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/javac/enum/T6509042.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index f597bc7f3e6..89fa13892f7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2199,7 +2199,7 @@ public class Attr extends JCTree.Visitor { (env.tree.getTag() != JCTree.ASSIGN || TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { - if (!onlyWarning || isNonStaticEnumField(v)) { + if (!onlyWarning || isStaticEnumField(v)) { log.error(tree.pos(), "illegal.forward.ref"); } else if (useBeforeDeclarationWarning) { log.warning(tree.pos(), "forward.ref", v); @@ -2233,7 +2233,7 @@ public class Attr extends JCTree.Visitor { // initializer expressions of an enum constant e to refer // to itself or to an enum constant of the same type that // is declared to the right of e." - if (isNonStaticEnumField(v)) { + if (isStaticEnumField(v)) { ClassSymbol enclClass = env.info.scope.owner.enclClass(); if (enclClass == null || enclClass.owner == null) @@ -2254,8 +2254,14 @@ public class Attr extends JCTree.Visitor { } } - private boolean isNonStaticEnumField(VarSymbol v) { - return Flags.isEnum(v.owner) && Flags.isStatic(v) && !Flags.isConstant(v); + /** Is the given symbol a static, non-constant field of an Enum? + * Note: enum literals should not be regarded as such + */ + private boolean isStaticEnumField(VarSymbol v) { + return Flags.isEnum(v.owner) && + Flags.isStatic(v) && + !Flags.isConstant(v) && + v.name != names._class; } /** Can the given symbol be the owner of code which forms part diff --git a/langtools/test/tools/javac/enum/T6509042.java b/langtools/test/tools/javac/enum/T6509042.java new file mode 100644 index 00000000000..53a59bfc74b --- /dev/null +++ b/langtools/test/tools/javac/enum/T6509042.java @@ -0,0 +1,41 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6509042 + * + * @summary javac rejects class literals in enum constructors + * @author Maurizio Cimadamore + * + * @compile T6509042.java + */ +enum T6509042 { + A, B; + + Class cl = T6509042.class; + + T6509042() { + Class cl2 = T6509042.class; + } +} From 1be460dbdd9cf0ded00118c01a119489b718cf6e Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 2 Apr 2008 11:44:23 +0100 Subject: [PATCH 249/274] 6531090: Cannot access methods/fields of a captured type belonging to an intersection type Fixed lookup of field/methods on intersection types Reviewed-by: jjg --- .../com/sun/tools/javac/code/Types.java | 7 +- .../com/sun/tools/javac/comp/Resolve.java | 8 +- .../javac/generics/6531090/T6531090a.java | 59 +++++++++++++ .../javac/generics/6531090/T6531090b.java | 82 +++++++++++++++++++ 4 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/javac/generics/6531090/T6531090a.java create mode 100644 langtools/test/tools/javac/generics/6531090/T6531090b.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 070bf9d541f..c9cc2cef6be 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -1298,7 +1298,7 @@ public class Types { return t; Type st = supertype(t); - if (st.tag == CLASS || st.tag == ERROR) { + if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) { Type x = asSuper(st, sym); if (x != null) return x; @@ -1320,7 +1320,10 @@ public class Types { @Override public Type visitTypeVar(TypeVar t, Symbol sym) { - return asSuper(t.bound, sym); + if (t.tsym == sym) + return t; + else + return asSuper(t.bound, sym); } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 1df0bb72571..f567133ddae 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -407,6 +407,8 @@ public class Resolve { Type site, Name name, TypeSymbol c) { + while (c.type.tag == TYPEVAR) + c = c.type.getUpperBound().tsym; Symbol bestSoFar = varNotFound; Symbol sym; Scope.Entry e = c.members().lookup(name); @@ -418,7 +420,7 @@ public class Resolve { e = e.next(); } Type st = types.supertype(c.type); - if (st != null && st.tag == CLASS) { + if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) { sym = findField(env, site, name, st.tsym); if (sym.kind < bestSoFar.kind) bestSoFar = sym; } @@ -733,7 +735,9 @@ public class Resolve { boolean allowBoxing, boolean useVarargs, boolean operator) { - for (Type ct = intype; ct.tag == CLASS; ct = types.supertype(ct)) { + for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) { + while (ct.tag == TYPEVAR) + ct = ct.getUpperBound(); ClassSymbol c = (ClassSymbol)ct.tsym; if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) abstractok = false; diff --git a/langtools/test/tools/javac/generics/6531090/T6531090a.java b/langtools/test/tools/javac/generics/6531090/T6531090a.java new file mode 100644 index 00000000000..f00235ebfbe --- /dev/null +++ b/langtools/test/tools/javac/generics/6531090/T6531090a.java @@ -0,0 +1,59 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6531090 + * + * @summary Cannot access methods/fields of a captured type belonging to an intersection type + * @author Maurizio Cimadamore + * + */ +public class T6531090a { + + static class E {} + + static class F extends E implements I1 {} + + static interface I {} + + static interface I1 {} + + static class G extends F implements I {} + + static class C { + T field; + } + + public static void main(String... args) { + test(new C()); + } + + static void test(C arg) { + F vf = arg.field; + I vi = arg.field; + I1 vi1 = arg.field; + E ve = arg.field; + W vt = arg.field; + } +} diff --git a/langtools/test/tools/javac/generics/6531090/T6531090b.java b/langtools/test/tools/javac/generics/6531090/T6531090b.java new file mode 100644 index 00000000000..ede819f32d6 --- /dev/null +++ b/langtools/test/tools/javac/generics/6531090/T6531090b.java @@ -0,0 +1,82 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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 6531090 + * + * @summary Cannot access methods/fields of a captured type belonging to an intersection type + * @author Maurizio Cimadamore + * + */ +public class T6531090b { + + static class A { + public void a() {} + public A a; + } + static class B extends A { + public void b(){} + public B b; + } + static interface I{ + void i(); + } + static interface I1{ + void i1(); + } + static class E extends B implements I, I1{ + public void i() {} + public void i1() {} + } + static class C{ + T t; + W w; + C(W w, T t) { + this.w = w; + this.t = t; + } + } + + public static void main(String... args) { + C c = new C(new E(), new E()); + testMemberMethods(c); + testMemberFields(c); + } + + static void testMemberMethods(C arg) { + arg.t.a(); + arg.t.b(); + arg.t.i1(); + arg.w.a(); + arg.w.b(); + arg.w.i1(); + } + + static void testMemberFields(C arg) { + A ta = arg.t.a; + B tb = arg.t.b; + A wa = arg.w.a; + B wb = arg.w.b; + } +} From 2dddf4033e5e38d37344c6793976075035b9e9fc Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Wed, 2 Apr 2008 22:44:45 -0400 Subject: [PATCH 250/274] 6668231: Presence of a critical subjectAltName causes JSSE's SunX509 to fail trusted checks Make the critical extension known to end entity checker. Reviewed-by: wetmore, mullan --- .../security/validator/EndEntityChecker.java | 10 + .../CriticalSubjectAltName.java | 262 ++++++++++++++++++ .../https/HttpsURLConnection/crisubn.jks | Bin 0 -> 2794 bytes .../https/HttpsURLConnection/trusted.jks | Bin 0 -> 743 bytes 4 files changed, 272 insertions(+) create mode 100644 jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java create mode 100644 jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/crisubn.jks create mode 100644 jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/trusted.jks diff --git a/jdk/src/share/classes/sun/security/validator/EndEntityChecker.java b/jdk/src/share/classes/sun/security/validator/EndEntityChecker.java index f0fb1787fa3..189db3dd058 100644 --- a/jdk/src/share/classes/sun/security/validator/EndEntityChecker.java +++ b/jdk/src/share/classes/sun/security/validator/EndEntityChecker.java @@ -87,6 +87,9 @@ class EndEntityChecker { // the Microsoft Server-Gated-Cryptography EKU extension OID private final static String OID_EKU_MS_SGC = "1.3.6.1.4.1.311.10.3.3"; + // the recognized extension OIDs + private final static String OID_SUBJECT_ALT_NAME = "2.5.29.17"; + private final static String NSCT_SSL_CLIENT = NetscapeCertTypeExtension.SSL_CLIENT; @@ -171,6 +174,13 @@ class EndEntityChecker { throws CertificateException { // basic constraints irrelevant in EE certs exts.remove(SimpleValidator.OID_BASIC_CONSTRAINTS); + + // If the subject field contains an empty sequence, the subjectAltName + // extension MUST be marked critical. + // We do not check the validity of the critical extension, just mark + // it recognizable here. + exts.remove(OID_SUBJECT_ALT_NAME); + if (!exts.isEmpty()) { throw new CertificateException("Certificate contains unsupported " + "critical extensions: " + exts); diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java new file mode 100644 index 00000000000..ffd70754168 --- /dev/null +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java @@ -0,0 +1,262 @@ +/* + * Copyright 2001-2008 Sun Microsystems, Inc. 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 6668231 + * @summary Presence of a critical subjectAltName causes JSSE's SunX509 to + * fail trusted checks + * @author Xuelei Fan + * + * This test depends on binary keystore, crisubn.jks and trusted.jks. Because + * JAVA keytool cannot generate X509 certificate with SubjectAltName extension, + * the certificates are generated with openssl toolkits and then imported into + * JAVA keystore. + * + * The crisubn.jks holds a private key entry and the corresponding X509 + * certificate issued with an empty Subject field, and a critical + * SubjectAltName extension. + * + * The trusted.jks holds the trusted certificate. + */ +import java.io.*; +import java.net.*; +import javax.net.ssl.*; +import java.security.cert.Certificate; + +public class CriticalSubjectAltName implements HostnameVerifier { + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = true; + + /* + * Where do we find the keystores? + */ + static String pathToStores = "./"; + static String keyStoreFile = "crisubn.jks"; + static String trustStoreFile = "trusted.jks"; + static String passwd = "passphrase"; + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * If the client or server is doing some kind of object creation + * that the other side depends on, and that thread prematurely + * exits, you may experience a hang. The test harness will + * terminate all hung threads after its timeout has expired, + * currently 3 minutes by default, but you might try to be + * smart about it.... + */ + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); + SSLServerSocket sslServerSocket = + (SSLServerSocket) sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); + OutputStream sslOS = sslSocket.getOutputStream(); + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sslOS)); + bw.write("HTTP/1.1 200 OK\r\n\r\n\r\n"); + bw.flush(); + Thread.sleep(5000); + sslSocket.close(); + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + URL url = new URL("https://localhost:"+serverPort+"/index.html"); + HttpsURLConnection urlc = (HttpsURLConnection)url.openConnection(); + urlc.setHostnameVerifier(this); + urlc.getInputStream(); + + if (urlc.getResponseCode() == -1) { + throw new RuntimeException("getResponseCode() returns -1"); + } + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + String keyFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", "./") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + if (debug) + System.setProperty("javax.net.debug", "all"); + + /* + * Start the tests. + */ + new CriticalSubjectAltName(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + CriticalSubjectAltName() throws Exception { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + serverThread.join(); + } else { + clientThread.join(); + } + + /* + * When we get here, the test is pretty much over. + * + * If the main thread excepted, that propagates back + * immediately. If the other thread threw an exception, we + * should report back. + */ + if (serverException != null) + throw serverException; + if (clientException != null) + throw clientException; + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + doServerSide(); + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + doClientSide(); + } + } + + // Simple test method to blindly agree that hostname and certname match + public boolean verify(String hostname, SSLSession session) { + return true; + } + +} diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/crisubn.jks b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/crisubn.jks new file mode 100644 index 0000000000000000000000000000000000000000..aee7d9f33792257b9c20599e198cb52e84e44303 GIT binary patch literal 2794 zcmeH}SyYqP7RSFY6DE)XhOvxArPHh)P2vH9D zK;l9Yq$IAGXgZ{+jE9Jji3vm`l1L=;Gs<{lGDI>q-!h#BW)lGl!H9!u?Px6@Yhc~z+0d)cWb1FHUdDD>v?R^y?> ze;zQg?ISZkOBt5BW<$wvqqyX$uf?nGwdz}{NU{MD?FGj2`myVMwKfS;+ss$_MmD;w znMZ>y&~qET-j`mGs#dbs-}Ha7_e|)mwZnTW8XIoBj3gleg@%wIxbtoaVHqId z+6AP?j|?jEo48OgjZNiWISS;RQ>?|Na%-rb>IXjx<5D{vkyM$F@sYUvGY?Z6rR(mn zN|aB_H~87VS!JloHElFlCGD-XGOQKk(GHxCw6wU&J=IVqLaF!Q<``QAshTBX_(7-Lwc^apJww79s*vsUTR{Wc2v zs{~p+6u0+cj|ci#)v3gxZf8&d?1&%J&u;jpZPjqKOQ+sr)a}{NMHj|`oog@vuE%;L zzfBd#&%%e(%tZ&`T^q;UyAZ8e?emoB$ka3V}*sKIu{;ZQX}67x>9%gS2ICp zH4R#hU<coWLbNTG*;N`cF;Q1{pad6})&{!wmOG3)S`#{9htC(V|1 za@LE&yR|~!tXGpSk0h}|+8iRJi6fTnsW&ZB9=u+2Y@OIwl;x$r@V$uBS9DzCIC~z| zA_fC5a7$Dc^MC1F&ahpXz{TC*d>pQ{R{1D`hu0nb)><)BVQAtGeUCPF+~<|k>MT*C zJH_F(XBW>SQg`xiFSnPxXP<8(D-Ecm>xbeTB3{%b&iHmcwd`e$LW8=G<9=@1Dzixr z<~~`Ty_~1@omDnZn5O@{`|yC(%#bI?&Y+Iuap|^Ywi^glU{~foY{8RD@z;GK& z+H77z_Loja>6F-y&16PB=8XY`3#zFJV))&BV!ms zyXOY84a^7Kwi{GCr4OU5W%m0KVrRA|?MymFD;?wZsZNuHSM+R&x$?Arm{v&A@rPUBjQ^^MfqYD8a`49%{ zpJfkby|D)IC@m!omsonVyStON9X*=PfIq7sZ5uj+85SHC2pjJ(SfRt{{JhKdhPPb( z;XbzT&<{^m1|hBA7_0&*{W*gnJ;??bH9IJE=tCBPo*WPr8%ei{fs=*@MHofXnK?)U z~3aEn!4n;G(ciyuP8 zsznt3Yrrlj+@A9!>zTzOU2`Ay>1Isn-M8#9$aki`XFzP+SZ}^DJgOMiLwn|ZS6^-! zm=EZW)_Y6+R?Z~7y1XSz+>s&@j-Aw%zQY}b{u%-P8Ug-mK>L3f0WuHHo!wu+LAs>S O7Sr#R-7eCxQu+@^S{GCR literal 0 HcmV?d00001 diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/trusted.jks b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/trusted.jks new file mode 100644 index 0000000000000000000000000000000000000000..0202bec16205771e8143c9bb2ca5d13d015dc6bf GIT binary patch literal 743 zcmezO_TO6u1_mY|W(3nLiSfyaK#n8_!;~outPy&q29`kiRR&E=%Yc}F0W%XL6B8qY z0WTY;R+~rLcV0$D7FGrWcSCLiPB!LH7B*p~&|pJh13?gnLzpW#KQ~o3xFoS8)lkrY zA0)^n%mETq@GnX?6foce2{8+^gM{+)QVrz9c?}E=jExNp4NXi;%%jA4jVugIjLe~2 z>RHq{AK4F#tPISJy$lA8olK3531z*mub}oJLyX0e!p0moXR{Jz7)>q%pMNfZZviL*$mme1+g`zUHSEQ_D zVrFDuT->C)WBL^Wc888FGF0sD&`eo6LTbCN7g*I7loNv$2 z)gZc>vuf!o>o6H@#muGF2fdlCd0csOxO$?_RBhqju)A@Zc(~x^c#j{SiX;WLe&6g+ zF0|S~clG|RP|b-sHdYIk25z4Hl||+>*Q=smy;U`LzW Date: Thu, 3 Apr 2008 18:01:55 -0700 Subject: [PATCH 251/274] 6570242: Regression test failures with Javac on win32 Takes this test out of service until the reall bug is fixed Reviewed-by: jjg --- langtools/test/tools/javac/api/6431257/T6431257.java | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/test/tools/javac/api/6431257/T6431257.java b/langtools/test/tools/javac/api/6431257/T6431257.java index 4d751eb5190..3be14e2c027 100644 --- a/langtools/test/tools/javac/api/6431257/T6431257.java +++ b/langtools/test/tools/javac/api/6431257/T6431257.java @@ -27,6 +27,7 @@ * @summary JSR 199: Changes to JavaFileManager to support JSR 269 Filer API * @author Peter von der Ah\u00e9 * @library ../lib + * @ignore Need to fix this test when 6508981 is fixed. * @compile T6431257.java package-info.java * @run main T6431257 foo.bar.baz foo/bar/baz */ From e6ce57d09edba63a31db2ea3dff71b98485f716b Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Sun, 6 Apr 2008 10:15:03 -0700 Subject: [PATCH 252/274] 6683078: Update JCE framework and provider builds to work on read-only filesystems 6644659: Error in default target of make/javax/crypto in OpenJDK build Reviewed-by: valeriep, ohair --- jdk/make/com/sun/crypto/provider/Makefile | 76 +++++++++---- jdk/make/common/shared/Defs.gmk | 11 +- jdk/make/javax/crypto/Defs-jce.gmk | 13 ++- jdk/make/javax/crypto/Makefile | 126 +++++++++++++++------- jdk/make/sun/security/mscapi/Makefile | 47 ++++++-- jdk/make/sun/security/pkcs11/Makefile | 47 ++++++-- 6 files changed, 240 insertions(+), 80 deletions(-) diff --git a/jdk/make/com/sun/crypto/provider/Makefile b/jdk/make/com/sun/crypto/provider/Makefile index 3d948d03537..64e4320b19a 100644 --- a/jdk/make/com/sun/crypto/provider/Makefile +++ b/jdk/make/com/sun/crypto/provider/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2008 Sun Microsystems, Inc. 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 @@ -87,8 +87,7 @@ # sign Alias for sign-jar # sign-jar Builds/signs sunjce_provider.jar (no install) # -# obfus Builds/obfuscates/signs/installs -# sunjce_provider.jar +# obfus Builds/obfuscates/signs sunjce_provider.jar # # release Builds all targets in preparation # for workspace integration. @@ -101,8 +100,25 @@ BUILDDIR = ../../../.. PACKAGE = com.sun.crypto.provider PRODUCT = sun + +# +# The following is for when we need to do postprocessing +# (signing/obfuscation) against a read-only build. If the OUTPUTDIR +# isn't writable, the build currently crashes out. +# +ifndef OPENJDK + ifdef ALT_JCE_BUILD_DIR + # ===================================================== + # Where to place the output, in case we're building from a read-only + # build area. (e.g. a release engineering build.) + JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR} + IGNORE_WRITABLE_OUTPUTDIR_TEST=true + else + JCE_BUILD_DIR=${TEMPDIR} + endif +endif + include $(BUILDDIR)/common/Defs.gmk -include $(BUILDDIR)/javax/crypto/Defs-jce.gmk # # Location for the newly built classfiles. @@ -147,6 +163,8 @@ endif # OPENJDK # UNSIGNED_DIR = $(TEMPDIR)/unsigned +include $(BUILDDIR)/javax/crypto/Defs-jce.gmk + # ===================================================== # Build the unsigned sunjce_provider.jar file. @@ -184,44 +202,66 @@ ifndef OPENJDK # Sign the provider jar file. Not needed for OpenJDK. # -SIGNED_DIR = $(TEMPDIR)/signed +SIGNED_DIR = $(JCE_BUILD_DIR)/signed sign: sign-jar sign-jar: $(SIGNED_DIR)/sunjce_provider.jar +ifndef ALT_JCE_BUILD_DIR $(SIGNED_DIR)/sunjce_provider.jar: $(UNSIGNED_DIR)/sunjce_provider.jar - $(sign-file) +else +# +# We have to remove the build dependency, otherwise, we'll try to rebuild it +# which we can't do on a read-only filesystem. +# +$(SIGNED_DIR)/sunjce_provider.jar: + @if [ ! -r $(UNSIGNED_DIR)/sunjce_provider.jar ] ; then \ + $(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunjce_provider.jar"; \ + exit 1; \ + fi +endif + $(call sign-file, $(UNSIGNED_DIR)/sunjce_provider.jar) # ===================================================== # Obfuscate/sign/install the JDK build. Not needed for OpenJDK. # -OBFUS_DIR = $(TEMPDIR)/obfus +OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/sunjce CLOSED_DIR = $(BUILDDIR)/closed/com/sun/crypto/provider obfus: $(OBFUS_DIR)/sunjce_provider.jar $(release-warning) -$(OBFUS_DIR)/sunjce_provider.jar: build-jar $(JCE_MANIFEST_FILE) +ifndef ALT_JCE_BUILD_DIR +$(OBFUS_DIR)/sunjce_provider.jar: build-jar $(JCE_MANIFEST_FILE) \ + $(OBFUS_DIR)/sunjce.dox +else +$(OBFUS_DIR)/sunjce_provider.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/sunjce.dox + @if [ ! -d $(CLASSDESTDIR) ] ; then \ + $(ECHO) "Couldn't find $(CLASSDESTDIR)"; \ + exit 1; \ + fi +endif + @$(ECHO) ">>>Obfuscating SunJCE Provider..." $(presign) $(preobfus) - @$(ECHO) ">>>Obfuscating Sun JCE Provider..." $(prep-target) $(CD) $(OBFUS_DIR); \ - $(OBFUSCATOR) -fv \ - $(CURRENT_DIRECTORY)/$(CLOSED_DIR)/obfus/sunjce.dox + $(OBFUSCATOR) -fv sunjce.dox @$(CD) $(OBFUS_DIR); $(java-vm-cleanup) $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ -C $(OBFUS_DIR)/build com \ $(JAR_JFLAGS) $(sign-target) - $(MKDIR) -p $(dir $(JAR_DESTFILE)) - $(RM) $(JAR_DESTFILE) - $(CP) $@ $(JAR_DESTFILE) @$(java-vm-cleanup) +$(OBFUS_DIR)/sunjce.dox: $(CLOSED_DIR)/obfus/sunjce.dox + @$(ECHO) ">>>Creating sunjce.dox" + $(prep-target) + $(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@ + # # The current obfuscator has a limitation in that it currently only # supports up to v49 class file format. Force v49 classfiles in our @@ -235,9 +275,9 @@ TARGET_CLASS_VERSION = 5 # release: $(OBFUS_DIR)/sunjce_provider.jar - $(RM) $(RELEASE_DIR)/sunjce_provider.jar - $(MKDIR) -p $(RELEASE_DIR) - $(CP) $(OBFUS_DIR)/sunjce_provider.jar $(RELEASE_DIR) + $(RM) $(JCE_BUILD_DIR)/release/sunjce_provider.jar + $(MKDIR) -p $(JCE_BUILD_DIR)/release + $(CP) $(OBFUS_DIR)/sunjce_provider.jar $(JCE_BUILD_DIR)/release $(release-warning) endif # OPENJDK @@ -275,7 +315,7 @@ endif # clobber clean:: - $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) + $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR) .PHONY: build-jar jar install-jar ifndef OPENJDK diff --git a/jdk/make/common/shared/Defs.gmk b/jdk/make/common/shared/Defs.gmk index 0eb8c729a96..c57baafc118 100644 --- a/jdk/make/common/shared/Defs.gmk +++ b/jdk/make/common/shared/Defs.gmk @@ -1,5 +1,5 @@ # -# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -449,11 +449,20 @@ endif # Check for spaces and null value OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR) OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR) + +# +# When signing the JCE framework and provider, we could be using built +# bits on a read-only filesystem. If so, this test will fail and crash +# the build. +# +ifndef IGNORE_WRITABLE_OUTPUTDIR_TEST # Create the output directory and make sure it exists and is writable _create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1) ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null) _outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable") endif +endif + # Define absolute path if needed and check for spaces and null value ifndef ABS_OUTPUTDIR ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR)) diff --git a/jdk/make/javax/crypto/Defs-jce.gmk b/jdk/make/javax/crypto/Defs-jce.gmk index c1ef30d5448..46fe1118dca 100644 --- a/jdk/make/javax/crypto/Defs-jce.gmk +++ b/jdk/make/javax/crypto/Defs-jce.gmk @@ -1,5 +1,5 @@ # -# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2008 Sun Microsystems, Inc. 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 @@ -31,7 +31,7 @@ include $(BUILDDIR)/common/Release.gmk JCE_MANIFEST_FILE = $(TEMPDIR)/manifest.mf $(JCE_MANIFEST_FILE): $(MAINMANIFEST) $(prep-target) - ( $(SED) "s/@@RELEASE@@/$(RELEASE)/" $(MAINMANIFEST); \ + ( $(SED) "s/@@RELEASE@@/$(RELEASE)/" $<; \ $(ECHO) "Extension-Name: javax.crypto"; \ $(ECHO) "Implementation-Vendor-Id: com.sun"; ) > $@ @@ -75,6 +75,7 @@ endef define sign-target $(BOOT_JARSIGNER_CMD) -keystore $(SIGNING_KEYSTORE) \ $@ $(SIGNING_ALIAS) < $(SIGNING_PASSPHRASE) + @$(java-vm-cleanup) @$(ECHO) "\nJar codesigning finished." endef @@ -88,13 +89,15 @@ define release-warning endef # -# Convenience macro for steps needed to sign a jar file. +# Convenience macros for signing a jar file. +# +# Call through $(call sign-file, target file) # define sign-file $(presign) - $(install-file) + $(prep-target) + $(CP) $1 $@ $(sign-target) - @$(java-vm-cleanup) endef # diff --git a/jdk/make/javax/crypto/Makefile b/jdk/make/javax/crypto/Makefile index 98b8a9158bf..86588e855ef 100644 --- a/jdk/make/javax/crypto/Makefile +++ b/jdk/make/javax/crypto/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2007-2008 Sun Microsystems, Inc. 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 @@ -96,7 +96,7 @@ # sign-jar Builds/signs jce.jar file (no install) # sign-policy Builds/signs policy files (no install) # -# obfus Builds/obfuscates/signs/installs jce.jar +# obfus Builds/obfuscates/signs jce.jar # # release Builds all targets in preparation # for workspace integration. @@ -110,8 +110,24 @@ BUILDDIR = ../.. PACKAGE = javax.crypto PRODUCT = sun +# +# The following is for when we need to do postprocessing +# (signing/obfuscation) against a read-only build. If the OUTPUTDIR +# isn't writable, the build currently crashes out. +# +ifndef OPENJDK + ifdef ALT_JCE_BUILD_DIR + # ===================================================== + # Where to place the output, in case we're building from a read-only + # build area. (e.g. a release engineering build.) + JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR} + IGNORE_WRITABLE_OUTPUTDIR_TEST=true + else + JCE_BUILD_DIR=${TEMPDIR} + endif +endif + include $(BUILDDIR)/common/Defs.gmk -include Defs-jce.gmk # # Location for the newly built classfiles. @@ -158,6 +174,8 @@ endif # OPENJDK # UNSIGNED_DIR = $(TEMPDIR)/unsigned +include Defs-jce.gmk + # ===================================================== # Build the unsigned jce.jar file. Signing/obfuscation comes later. @@ -299,7 +317,7 @@ ifndef OPENJDK # Sign the various jar files. Not needed for OpenJDK. # -SIGNED_DIR = $(TEMPDIR)/signed +SIGNED_DIR = $(JCE_BUILD_DIR)/signed SIGNED_POLICY_BUILDDIR = $(SIGNED_DIR)/policy SIGNED_POLICY_FILES = \ @@ -312,61 +330,87 @@ sign-jar: $(SIGNED_DIR)/jce.jar sign-policy: $(SIGNED_POLICY_FILES) +ifndef ALT_JCE_BUILD_DIR $(SIGNED_DIR)/jce.jar: $(UNSIGNED_DIR)/jce.jar - $(sign-file) +else +# +# We have to remove the build dependency, otherwise, we'll try to rebuild it +# which we can't do on a read-only filesystem. +# +$(SIGNED_DIR)/jce.jar: + @if [ ! -r $(UNSIGNED_DIR)/jce.jar ] ; then \ + $(ECHO) "Couldn't find $(UNSIGNED_DIR)/jce.jar"; \ + exit 1; \ + fi +endif + $(call sign-file, $(UNSIGNED_DIR)/jce.jar) $(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar: \ -$(UNSIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar - $(sign-file) + $(UNSIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar + $(call sign-file, $<) $(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar: \ -$(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar - $(sign-file) + $(UNSIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar + $(call sign-file, $<) $(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar: \ -$(UNSIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar - $(sign-file) + $(UNSIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar + $(call sign-file, $<) $(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar: \ -$(UNSIGNED_POLICY_BUILDDIR)/limited/local_policy.jar - $(sign-file) + $(UNSIGNED_POLICY_BUILDDIR)/limited/local_policy.jar + $(call sign-file, $<) # ===================================================== # Obfuscate/sign/install the JDK build. Not needed for OpenJDK. # -OBFUS_DIR = $(TEMPDIR)/obfus +OBFUS_DIR = $(JCE_BUILD_DIR)/obfus/jce CLOSED_DIR = $(BUILDDIR)/closed/javax/crypto obfus: $(OBFUS_DIR)/jce.jar $(release-warning) -$(OBFUS_DIR)/jce.jar: build-jar $(JCE_MANIFEST_FILE) +ifndef ALT_JCE_BUILD_DIR +$(OBFUS_DIR)/jce.jar: build-jar $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox +else +# +# We have to remove the build dependency, otherwise, we'll try to rebuild it +# which we can't do on a read-only filesystem. +# +$(OBFUS_DIR)/jce.jar: $(JCE_MANIFEST_FILE) $(OBFUS_DIR)/framework.dox + @if [ ! -d $(CLASSDESTDIR) ] ; then \ + $(ECHO) "Couldn't find $(CLASSDESTDIR)"; \ + exit 1; \ + fi +endif + @$(ECHO) ">>>Obfuscating JCE framework..." $(presign) $(preobfus) - @$(ECHO) ">>>Obfuscating JCE framework..." $(prep-target) $(CD) $(OBFUS_DIR); \ - $(OBFUSCATOR) -fv \ - $(CURRENT_DIRECTORY)/$(CLOSED_DIR)/obfus/framework.dox + $(OBFUSCATOR) -fv framework.dox @$(CD) $(OBFUS_DIR); $(java-vm-cleanup) + @# @# The sun.security.internal classes are currently not obfuscated @# due to an obfus problem. Manually copy them to the build directory @# so that they are included in the jce.jar file. + @# $(CP) -r $(CLASSDESTDIR)/sun $(OBFUS_DIR)/build - $(RM) $(UNSIGNED_DIR)/jce.jar $(BOOT_JAR_CMD) cmf $(JCE_MANIFEST_FILE) $@ \ -C $(OBFUS_DIR)/build javax \ -C $(OBFUS_DIR)/build sun \ $(JAR_JFLAGS) $(sign-target) - $(MKDIR) -p $(dir $(JAR_DESTFILE)) - $(RM) $(JAR_DESTFILE) - $(CP) $@ $(JAR_DESTFILE) @$(java-vm-cleanup) +$(OBFUS_DIR)/framework.dox: $(CLOSED_DIR)/obfus/framework.dox + @$(ECHO) ">>>Creating framework.dox" + $(prep-target) + $(SED) "s:@@TEMPDIR@@:$(ABS_TEMPDIR):" $< > $@ + # # The current obfuscator has a limitation in that it currently only # supports up to v49 class file format. Force v49 classfiles in our @@ -380,26 +424,27 @@ TARGET_CLASS_VERSION = 5 # unlimited policy file distribution, etc. # -release: $(OBFUS_DIR)/jce.jar sign-policy +release: $(OBFUS_DIR)/jce.jar sign-policy $(CLOSED_DIR)/doc/COPYRIGHT.html \ + $(CLOSED_DIR)/doc/README.txt $(RM) -r \ - $(RELEASE_DIR)/UnlimitedJCEPolicy \ - $(RELEASE_DIR)/jce.jar \ - $(RELEASE_DIR)/US_export_policy.jar \ - $(RELEASE_DIR)/local_policy.jar \ - $(RELEASE_DIR)/UnlimitedJCEPolicy.zip - $(MKDIR) -p $(RELEASE_DIR)/UnlimitedJCEPolicy - $(CP) $(OBFUS_DIR)/jce.jar $(RELEASE_DIR) - $(CP) -r \ - $(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar \ - $(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar \ - $(RELEASE_DIR) + $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy \ + $(JCE_BUILD_DIR)/release/jce.jar \ + $(JCE_BUILD_DIR)/release/US_export_policy.jar \ + $(JCE_BUILD_DIR)/release/local_policy.jar \ + $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy.zip + $(MKDIR) -p $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy + $(CP) $(OBFUS_DIR)/jce.jar $(JCE_BUILD_DIR)/release + $(CP) \ + $(SIGNED_POLICY_BUILDDIR)/limited/US_export_policy.jar \ + $(SIGNED_POLICY_BUILDDIR)/limited/local_policy.jar \ + $(JCE_BUILD_DIR)/release $(CP) \ $(SIGNED_POLICY_BUILDDIR)/unlimited/US_export_policy.jar \ - $(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar \ - $(RELEASE_DIR)/UnlimitedJCEPolicy - $(CP) $(CLOSED_DIR)/doc/COPYRIGHT.html \ - $(CLOSED_DIR)/doc/README.txt $(RELEASE_DIR)/UnlimitedJCEPolicy - cd $(RELEASE_DIR) ; \ + $(SIGNED_POLICY_BUILDDIR)/unlimited/local_policy.jar \ + $(CLOSED_DIR)/doc/COPYRIGHT.html \ + $(CLOSED_DIR)/doc/README.txt \ + $(JCE_BUILD_DIR)/release/UnlimitedJCEPolicy + cd $(JCE_BUILD_DIR)/release ; \ $(ZIPEXE) -qr UnlimitedJCEPolicy.zip UnlimitedJCEPolicy $(release-warning) @@ -478,7 +523,8 @@ endif clobber clean:: $(RM) -r $(JAR_DESTFILE) $(POLICY_DESTDIR)/US_export_policy.jar \ - $(POLICY_DESTDIR)/local_policy.jar $(DELETE_DIRS) $(TEMPDIR) + $(POLICY_DESTDIR)/local_policy.jar $(DELETE_DIRS) $(TEMPDIR) \ + $(JCE_BUILD_DIR) .PHONY: build-jar jar build-policy unlimited limited install-jar \ install-limited install-unlimited diff --git a/jdk/make/sun/security/mscapi/Makefile b/jdk/make/sun/security/mscapi/Makefile index e6b2372b69b..8223b536709 100644 --- a/jdk/make/sun/security/mscapi/Makefile +++ b/jdk/make/sun/security/mscapi/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -92,8 +92,25 @@ BUILDDIR = ../../.. PACKAGE = sun.security.mscapi LIBRARY = sunmscapi PRODUCT = sun + +# +# The following is for when we need to do postprocessing +# (signing/obfuscation) against a read-only build. If the OUTPUTDIR +# isn't writable, the build currently crashes out. +# +ifndef OPENJDK + ifdef ALT_JCE_BUILD_DIR + # ===================================================== + # Where to place the output, in case we're building from a read-only + # build area. (e.g. a release engineering build.) + JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR} + IGNORE_WRITABLE_OUTPUTDIR_TEST=true + else + JCE_BUILD_DIR=${TEMPDIR} + endif +endif + include $(BUILDDIR)/common/Defs.gmk -include $(BUILDDIR)/javax/crypto/Defs-jce.gmk CPLUSPLUSLIBRARY=true @@ -163,6 +180,8 @@ all: build-jar install-prebuilt $(build-warning) endif +include $(BUILDDIR)/javax/crypto/Defs-jce.gmk + # ===================================================== # Build the unsigned sunmscapi.jar file. @@ -200,14 +219,26 @@ ifndef OPENJDK # Sign the provider jar file. Not needed for OpenJDK. # -SIGNED_DIR = $(TEMPDIR)/signed +SIGNED_DIR = $(JCE_BUILD_DIR)/signed sign: sign-jar sign-jar: $(SIGNED_DIR)/sunmscapi.jar +ifndef ALT_JCE_BUILD_DIR $(SIGNED_DIR)/sunmscapi.jar: $(UNSIGNED_DIR)/sunmscapi.jar - $(sign-file) +else +# +# We have to remove the build dependency, otherwise, we'll try to rebuild it +# which we can't do on a read-only filesystem. +# +$(SIGNED_DIR)/sunmscapi.jar: + @if [ ! -r $(UNSIGNED_DIR)/sunmscapi.jar ] ; then \ + $(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunmscapi.jar"; \ + exit 1; \ + fi +endif + $(call sign-file, $(UNSIGNED_DIR)/sunmscapi.jar) # ===================================================== @@ -215,9 +246,9 @@ $(SIGNED_DIR)/sunmscapi.jar: $(UNSIGNED_DIR)/sunmscapi.jar # release: $(SIGNED_DIR)/sunmscapi.jar - $(RM) $(RELEASE_DIR)/sunmscapi.jar - $(MKDIR) -p $(RELEASE_DIR) - $(CP) $(SIGNED_DIR)/sunmscapi.jar $(RELEASE_DIR) + $(RM) $(JCE_BUILD_DIR)/release/sunmscapi.jar + $(MKDIR) -p $(JCE_BUILD_DIR)/release + $(CP) $(SIGNED_DIR)/sunmscapi.jar $(JCE_BUILD_DIR)/release $(release-warning) endif # OPENJDK @@ -255,7 +286,7 @@ endif # clobber clean:: - $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) + $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR) .PHONY: build-jar jar install-jar ifndef OPENJDK diff --git a/jdk/make/sun/security/pkcs11/Makefile b/jdk/make/sun/security/pkcs11/Makefile index 32d77f90d94..4508b20f843 100644 --- a/jdk/make/sun/security/pkcs11/Makefile +++ b/jdk/make/sun/security/pkcs11/Makefile @@ -1,5 +1,5 @@ # -# Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2003-2008 Sun Microsystems, Inc. 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 @@ -92,8 +92,25 @@ BUILDDIR = ../../.. PACKAGE = sun.security.pkcs11 LIBRARY = j2pkcs11 PRODUCT = sun + +# +# The following is for when we need to do postprocessing +# (signing/obfuscation) against a read-only build. If the OUTPUTDIR +# isn't writable, the build currently crashes out. +# +ifndef OPENJDK + ifdef ALT_JCE_BUILD_DIR + # ===================================================== + # Where to place the output, in case we're building from a read-only + # build area. (e.g. a release engineering build.) + JCE_BUILD_DIR=${ALT_JCE_BUILD_DIR} + IGNORE_WRITABLE_OUTPUTDIR_TEST=true + else + JCE_BUILD_DIR=${TEMPDIR} + endif +endif + include $(BUILDDIR)/common/Defs.gmk -include $(BUILDDIR)/javax/crypto/Defs-jce.gmk # # C and Java Files @@ -163,6 +180,8 @@ all: build-jar install-prebuilt $(build-warning) endif +include $(BUILDDIR)/javax/crypto/Defs-jce.gmk + # ===================================================== # Build the unsigned sunpkcs11.jar file. @@ -200,14 +219,26 @@ ifndef OPENJDK # Sign the provider jar file. Not needed for OpenJDK. # -SIGNED_DIR = $(TEMPDIR)/signed +SIGNED_DIR = $(JCE_BUILD_DIR)/signed sign: sign-jar sign-jar: $(SIGNED_DIR)/sunpkcs11.jar +ifndef ALT_JCE_BUILD_DIR $(SIGNED_DIR)/sunpkcs11.jar: $(UNSIGNED_DIR)/sunpkcs11.jar - $(sign-file) +else +# +# We have to remove the build dependency, otherwise, we'll try to rebuild it +# which we can't do on a read-only filesystem. +# +$(SIGNED_DIR)/sunpkcs11.jar: + @if [ ! -r $(UNSIGNED_DIR)/sunpkcs11.jar ] ; then \ + $(ECHO) "Couldn't find $(UNSIGNED_DIR)/sunpkcs11.jar"; \ + exit 1; \ + fi +endif + $(call sign-file, $(UNSIGNED_DIR)/sunpkcs11.jar) # ===================================================== @@ -215,9 +246,9 @@ $(SIGNED_DIR)/sunpkcs11.jar: $(UNSIGNED_DIR)/sunpkcs11.jar # release: $(SIGNED_DIR)/sunpkcs11.jar - $(RM) $(RELEASE_DIR)/sunpkcs11.jar - $(MKDIR) -p $(RELEASE_DIR) - $(CP) $(SIGNED_DIR)/sunpkcs11.jar $(RELEASE_DIR) + $(RM) $(JCE_BUILD_DIR)/release/sunpkcs11.jar + $(MKDIR) -p $(JCE_BUILD_DIR)/release + $(CP) $(SIGNED_DIR)/sunpkcs11.jar $(JCE_BUILD_DIR)/release $(release-warning) endif # OPENJDK @@ -255,7 +286,7 @@ endif # clobber clean:: - $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) + $(RM) -r $(JAR_DESTFILE) $(TEMPDIR) $(JCE_BUILD_DIR) .PHONY: build-jar jar install-jar ifndef OPENJDK From 2ec586cd174a07b17c8438a20c1dc944282de6d5 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Wed, 9 Apr 2008 11:18:55 -0700 Subject: [PATCH 253/274] Added tag jdk7-b25 for changeset 41658053480c --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index ff06c88a2bf..10146e2ba8a 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -1 +1,2 @@ cfeea66a3fa8ca3686a7cfa2d0ce8ab0169f168d jdk7-b24 +cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25 From d4ea3d391bcaf56a7859bac48d70e3a6d40287dc Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Wed, 9 Apr 2008 11:18:56 -0700 Subject: [PATCH 254/274] Added tag jdk7-b25 for changeset 4e9d88727ae3 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index f50e5065b96..751872e11c7 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -1 +1,2 @@ 55540e827aef970ecc010b7e06b912d991c8e3ce jdk7-b24 +5e61d5df62586474414d1058e9186441aa908f51 jdk7-b25 From 86c8eed0dbb76abad73cbdf9e39c378df74e4018 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Wed, 9 Apr 2008 11:18:58 -0700 Subject: [PATCH 255/274] Added tag jdk7-b25 for changeset 408b55da75b0 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index c3230a6f10b..8eaaa375622 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -1 +1,2 @@ a61af66fc99eb5ec9d50c05b0c599757b1289ceb jdk7-b24 +7836be3e92d0a4f9ee7566f602c91f5609534e66 jdk7-b25 From a8420df5f3ffbb6d6b80cf40a19a25c5c58ba654 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Wed, 9 Apr 2008 11:19:02 -0700 Subject: [PATCH 256/274] Added tag jdk7-b25 for changeset 510a9a867e27 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 0c27eee3f67..47dcd3f15dc 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -1 +1,2 @@ 6ce5f4757bde08f7470cbb9f0b46da8f2f3d4f56 jdk7-b24 +a3b3ba7d6034dc754b51ddc3d281399ac1cae5f1 jdk7-b25 From 08dc0809951800f6371ef1a431055900451f2a24 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Wed, 9 Apr 2008 11:19:03 -0700 Subject: [PATCH 257/274] Added tag jdk7-b25 for changeset 3b2c9223cdf5 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index f96f9279308..2266cda1b7f 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -1 +1,2 @@ 0961a4a211765fea071b8dac419003ee0c3d5973 jdk7-b24 +59fd8224ba2da5c2d8d4c68e33cf33ab41ce8de0 jdk7-b25 From d045aa8a11f8645a608e43066ebabe2e95a1d07a Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Wed, 9 Apr 2008 11:19:07 -0700 Subject: [PATCH 258/274] Added tag jdk7-b25 for changeset 8d655ddd5a03 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 898e4a75668..6eaa20bbab7 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -1 +1,2 @@ 37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 jdk7-b24 +75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25 From 7e94966c915852da9e778cd7575caa2fbe3c1593 Mon Sep 17 00:00:00 2001 From: Xiomara Jayasena Date: Wed, 9 Apr 2008 11:19:15 -0700 Subject: [PATCH 259/274] Added tag jdk7-b25 for changeset 2afbdd3321d0 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 92efaa97332..4730daa9010 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -1 +1,2 @@ 9a66ca7c79fab293c1bb0534e0d208c7e4f58b01 jdk7-b24 +58039502942e52f4144a33f36290a2bd2f3581e6 jdk7-b25 From da0bf7574c827a7a33d02dbedccb9406e04be2d1 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Thu, 10 Apr 2008 09:02:22 -0700 Subject: [PATCH 260/274] 6684582: Launcher needs improved error reporting Indicate the missing main class in the error message Reviewed-by: darcy, kbr --- jdk/src/share/bin/emessages.h | 4 +-- jdk/src/share/bin/java.c | 6 ++-- jdk/test/tools/launcher/Arrrghs.java | 32 +++++++++------------ jdk/test/tools/launcher/Arrrghs.sh | 43 ++++++++++++++++++++++++++-- 4 files changed, 60 insertions(+), 25 deletions(-) diff --git a/jdk/src/share/bin/emessages.h b/jdk/src/share/bin/emessages.h index f11c396ad60..03824bba5d1 100644 --- a/jdk/src/share/bin/emessages.h +++ b/jdk/src/share/bin/emessages.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -50,7 +50,7 @@ #define JAR_ERROR2 "Error: Unable to access jarfile %s" #define JAR_ERROR3 "Error: Invalid or corrupt jarfile %s" -#define CLS_ERROR1 "Error: Could not find the main class.\n" JNI_ERROR +#define CLS_ERROR1 "Error: Could not find the main class %s.\n" JNI_ERROR #define CLS_ERROR2 "Error: Failed to load Main Class: %s\n%s" #define CLS_ERROR3 "Error: No main method found in specified class.\n" GEN_ERROR #define CLS_ERROR4 "Error: Main method not public\n" GEN_ERROR diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c index 47c2fc17cd0..f7cbcdc95bc 100644 --- a/jdk/src/share/bin/java.c +++ b/jdk/src/share/bin/java.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems, Inc. 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 @@ -414,7 +414,7 @@ JavaMain(void * _args) mainClass = LoadClass(env, classname); if(mainClass == NULL) { /* exception occured */ ReportExceptionDescription(env); - ReportErrorMessage(CLS_ERROR1); + ReportErrorMessage(CLS_ERROR1, classname); goto leave; } (*env)->ReleaseStringUTFChars(env, mainClassName, classname); @@ -433,7 +433,7 @@ JavaMain(void * _args) mainClass = LoadClass(env, classname); if(mainClass == NULL) { /* exception occured */ ReportExceptionDescription(env); - ReportErrorMessage(CLS_ERROR1); + ReportErrorMessage(CLS_ERROR1, classname); goto leave; } (*env)->ReleaseStringUTFChars(env, mainClassName, classname); diff --git a/jdk/test/tools/launcher/Arrrghs.java b/jdk/test/tools/launcher/Arrrghs.java index 8f93df67198..34bfcee369b 100644 --- a/jdk/test/tools/launcher/Arrrghs.java +++ b/jdk/test/tools/launcher/Arrrghs.java @@ -1,17 +1,5 @@ -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. 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 +21,19 @@ import java.util.StringTokenizer; * have any questions. */ +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; -public class Arrrghs{ +public class Arrrghs { /** * A group of tests to ensure that arguments are passed correctly to @@ -113,12 +112,10 @@ public class Arrrghs{ return retval; } - - private static boolean doExec0(ProcessBuilder pb, String expectedArguments) { boolean retval = false; try { - pb.redirectErrorStream(_debug); + pb.redirectErrorStream(true); Process p = pb.start(); retval = detectCookie(p.getInputStream(), expectedArguments); p.waitFor(); @@ -167,7 +164,6 @@ public class Arrrghs{ } } - if (_debug) System.out.println("Starting Arrrghs tests"); // Basic test if (!doExec("-a -b -c -d")) exitValue++; diff --git a/jdk/test/tools/launcher/Arrrghs.sh b/jdk/test/tools/launcher/Arrrghs.sh index c2fe084d02f..f5ee6b0a75b 100644 --- a/jdk/test/tools/launcher/Arrrghs.sh +++ b/jdk/test/tools/launcher/Arrrghs.sh @@ -1,13 +1,13 @@ #!/bin/sh # @test Arrrghs.sh -# @bug 5030233 6214916 6356475 6571029 +# @bug 5030233 6214916 6356475 6571029 6684582 # @build Arrrghs # @run shell Arrrghs.sh # @summary Argument parsing validation. # @author Joseph E. Kowalski # -# Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2004-2008 Sun Microsystems, Inc. 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 @@ -103,6 +103,44 @@ TestHelp() { fi } +# +# Test to ensure that a missing main class is indicated in the error message +# +TestMissingMainClass() { + # First create a small jar file with no main + printf "public class Foo {}\n" > Foo.java + $TESTJAVA/bin/javac Foo.java + if [ $? -ne 0 ]; then + printf "Error: compilation of Foo.java failed\n" + exit 1 + fi + printf "Main-Class: Bar\n" > manifest + $TESTJAVA/bin/jar -cvfm some.jar manifest Foo.class + if [ ! -f some.jar ]; then + printf "Error: did not find some.jar\n" + exit 1 + fi + + # test a non-existence main-class using -jar + mess="`$TESTJAVA/bin/java -jar some.jar 2>&1 1>/dev/null`" + echo $mess | grep 'Bar' 2>&1 > /dev/null + if [ $? -ne 0 ]; then + printf "Error: did not find main class missing message\n" + exit 1 + fi + + # test a non-existent main-class using classpath + mess="`$TESTJAVA/bin/java -cp some.jar Bar 2>&1 1>/dev/null`" + echo $mess | grep 'Bar' 2>&1 > /dev/null + if [ $? -ne 0 ]; then + printf "Error: did not find main class missing message\n" + exit 1 + fi + + # cleanup + rm -f some.jar Foo.* manifest +} + # # Main processing: # @@ -117,6 +155,7 @@ TestCP javac -cp TestCP javac -classpath TestXUsage TestHelp +TestMissingMainClass # # Tests for 6214916 From 98ecfdaa4705f9b995d376126c0893c9c4730a1b Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Thu, 10 Apr 2008 10:47:13 -0700 Subject: [PATCH 261/274] 6610094: Add generic support for platform MXBeans of any type (also fixed 6681031) Add new methods in ManagementFactory class to obtain platform MXBeans Reviewed-by: alanb, dfuchs, emcmanus --- .../management/HotSpotDiagnosticMXBean.java | 9 +- .../lang/management/ClassLoadingMXBean.java | 8 +- .../lang/management/CompilationMXBean.java | 6 +- .../management/GarbageCollectorMXBean.java | 4 + .../lang/management/ManagementFactory.java | 201 +++++++- .../java/lang/management/MemoryMXBean.java | 6 +- .../lang/management/MemoryManagerMXBean.java | 6 +- .../lang/management/MemoryPoolMXBean.java | 6 +- .../management/OperatingSystemMXBean.java | 6 +- .../lang/management/PlatformComponent.java | 382 ++++++++++++++ .../management/PlatformManagedObject.java | 61 +++ .../java/lang/management/RuntimeMXBean.java | 6 +- .../java/lang/management/ThreadInfo.java | 10 +- .../java/lang/management/ThreadMXBean.java | 6 +- .../classes/java/util/logging/Logging.java | 5 + .../java/util/logging/LoggingMXBean.java | 9 +- .../sun/management/ClassLoadingImpl.java | 8 +- .../sun/management/CompilationImpl.java | 9 +- .../sun/management/GarbageCollectorImpl.java | 5 + .../classes/sun/management/GcInfoBuilder.java | 2 +- .../sun/management/GcInfoCompositeData.java | 20 +- .../sun/management/HotSpotDiagnostic.java | 8 +- .../sun/management/HotspotCompilation.java | 2 +- .../sun/management/HotspotInternal.java | 9 +- .../sun/management/LockDataConverter.java | 8 +- .../sun/management/ManagementFactory.java | 467 +----------------- .../management/ManagementFactoryHelper.java | 340 +++++++++++++ .../sun/management/MappedMXBeanType.java | 14 +- .../classes/sun/management/MemoryImpl.java | 23 +- .../sun/management/MemoryManagerImpl.java | 7 + .../MemoryNotifInfoCompositeData.java | 4 +- .../sun/management/MemoryPoolImpl.java | 18 +- .../management/MemoryUsageCompositeData.java | 4 +- .../management/MonitorInfoCompositeData.java | 4 +- .../NotificationEmitterSupport.java | 2 +- .../sun/management/OperatingSystemImpl.java | 7 + .../classes/sun/management/RuntimeImpl.java | 11 +- .../StackTraceElementCompositeData.java | 4 +- .../classes/sun/management/ThreadImpl.java | 27 +- .../management/ThreadInfoCompositeData.java | 4 +- .../share/classes/sun/management/Util.java | 80 +-- .../sun/management/VMManagementImpl.java | 4 +- .../sun/management/VMOptionCompositeData.java | 4 +- .../HotSpotDiagnosticMXBean/DumpHeap.java | 6 +- .../GetDiagnosticOptions.java | 5 +- .../HotSpotDiagnosticMXBean/GetVMOption.java | 6 +- .../HotSpotDiagnosticMXBean/SetVMOption.java | 7 +- .../ManagementFactory/GetPlatformMXBeans.java | 180 +++++++ .../PlatformMXBeanTest.java | 69 +++ 49 files changed, 1484 insertions(+), 615 deletions(-) create mode 100644 jdk/src/share/classes/java/lang/management/PlatformComponent.java create mode 100644 jdk/src/share/classes/java/lang/management/PlatformManagedObject.java create mode 100644 jdk/src/share/classes/sun/management/ManagementFactoryHelper.java create mode 100644 jdk/test/java/lang/management/ManagementFactory/GetPlatformMXBeans.java create mode 100644 jdk/test/java/lang/management/OperatingSystemMXBean/PlatformMXBeanTest.java diff --git a/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java index 45c1b55a861..f736dc500bd 100644 --- a/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java +++ b/jdk/src/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java @@ -25,6 +25,8 @@ package com.sun.management; +import java.lang.management.PlatformManagedObject; + /** * Diagnostic management interface for the HotSpot Virtual Machine. * The diagnostic MBean is registered to the platform MBeanServer @@ -35,8 +37,13 @@ package com.sun.management; *
    * com.sun.management:type=HotSpotDiagnostic *
    +.* + * It can be obtained by calling the + * {@link PlatformManagedObject#getObjectName} method. + * + * @see ManagementFactory#getPlatformMXBeans(Class) */ -public interface HotSpotDiagnosticMXBean { +public interface HotSpotDiagnosticMXBean extends PlatformManagedObject { /** * Dumps the heap to the outputFile file in the same * format as the hprof heap dump. diff --git a/jdk/src/share/classes/java/lang/management/ClassLoadingMXBean.java b/jdk/src/share/classes/java/lang/management/ClassLoadingMXBean.java index 62f31e48769..762e14cb2f5 100644 --- a/jdk/src/share/classes/java/lang/management/ClassLoadingMXBean.java +++ b/jdk/src/share/classes/java/lang/management/ClassLoadingMXBean.java @@ -35,7 +35,7 @@ package java.lang.management; * that can be obtained by calling * the {@link ManagementFactory#getClassLoadingMXBean} method or * from the {@link ManagementFactory#getPlatformMBeanServer - * platform MBeanServer} method. + * platform MBeanServer}. * *

    The ObjectName for uniquely identifying the MXBean for * the class loading system within an MBeanServer is: @@ -44,6 +44,10 @@ package java.lang.management; * java.lang:type=ClassLoading} * * + * It can be obtained by calling the + * {@link PlatformManagedObject#getObjectName} method. + * + * @see ManagementFactory#getPlatformMXBeans(Class) * @see * JMX Specification. * @see @@ -52,7 +56,7 @@ package java.lang.management; * @author Mandy Chung * @since 1.5 */ -public interface ClassLoadingMXBean { +public interface ClassLoadingMXBean extends PlatformManagedObject { /** * Returns the total number of classes that have been loaded since diff --git a/jdk/src/share/classes/java/lang/management/CompilationMXBean.java b/jdk/src/share/classes/java/lang/management/CompilationMXBean.java index 94f97bb4507..ea93a2b0ccb 100644 --- a/jdk/src/share/classes/java/lang/management/CompilationMXBean.java +++ b/jdk/src/share/classes/java/lang/management/CompilationMXBean.java @@ -44,6 +44,10 @@ package java.lang.management; * java.lang:type=Compilation} * * + * It can be obtained by calling the + * {@link PlatformManagedObject#getObjectName} method. + * + * @see ManagementFactory#getPlatformMXBeans(Class) * @see * JMX Specification. * @see @@ -52,7 +56,7 @@ package java.lang.management; * @author Mandy Chung * @since 1.5 */ -public interface CompilationMXBean { +public interface CompilationMXBean extends PlatformManagedObject { /** * Returns the name of the Just-in-time (JIT) compiler. * diff --git a/jdk/src/share/classes/java/lang/management/GarbageCollectorMXBean.java b/jdk/src/share/classes/java/lang/management/GarbageCollectorMXBean.java index f737a9c2ec5..50ee93d8d79 100644 --- a/jdk/src/share/classes/java/lang/management/GarbageCollectorMXBean.java +++ b/jdk/src/share/classes/java/lang/management/GarbageCollectorMXBean.java @@ -48,9 +48,13 @@ package java.lang.management; * java.lang:type=GarbageCollector},name=collector's name * * + * It can be obtained by calling the + * {@link PlatformManagedObject#getObjectName} method. + * * A platform usually includes additional platform-dependent information * specific to a garbage collection algorithm for monitoring. * + * @see ManagementFactory#getPlatformMXBeans(Class) * @see MemoryMXBean * * @see diff --git a/jdk/src/share/classes/java/lang/management/ManagementFactory.java b/jdk/src/share/classes/java/lang/management/ManagementFactory.java index dff4f19a4e3..c9e12708ef8 100644 --- a/jdk/src/share/classes/java/lang/management/ManagementFactory.java +++ b/jdk/src/share/classes/java/lang/management/ManagementFactory.java @@ -24,17 +24,31 @@ */ package java.lang.management; +import javax.management.DynamicMBean; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; +import javax.management.MBeanServerFactory; import javax.management.MBeanServerPermission; +import javax.management.NotificationEmitter; +import javax.management.ObjectInstance; import javax.management.ObjectName; +import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MalformedObjectNameException; +import javax.management.MBeanRegistrationException; +import javax.management.NotCompliantMBeanException; +import javax.management.StandardEmitterMBean; +import javax.management.StandardMBean; +import java.util.Collections; +import java.util.ArrayList; import java.util.List; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import javax.management.JMX; +import sun.management.ManagementFactoryHelper; /** * The ManagementFactory class is a factory class for getting @@ -49,13 +63,16 @@ import javax.management.JMX; *