From 30f059b5fce32e14fc0cb890b8a950be5e582356 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Mon, 12 Aug 2013 17:37:02 +0200 Subject: [PATCH 001/293] 8015107: NPG: Use consistent naming for metaspace concepts Reviewed-by: coleenp, mgerdin, hseigel --- .../classes/sun/jvm/hotspot/runtime/VM.java | 2 +- .../sun/jvm/hotspot/tools/HeapSummary.java | 24 ++++----- .../cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 8 +-- .../cpu/sparc/vm/c1_MacroAssembler_sparc.cpp | 4 +- .../src/cpu/sparc/vm/macroAssembler_sparc.cpp | 18 +++---- hotspot/src/cpu/sparc/vm/sparc.ad | 8 +-- .../src/cpu/sparc/vm/stubGenerator_sparc.cpp | 6 +-- .../src/cpu/sparc/vm/vtableStubs_sparc.cpp | 4 +- hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp | 2 +- .../src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 20 ++++---- .../src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 4 +- .../src/cpu/x86/vm/c1_MacroAssembler_x86.cpp | 8 +-- hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp | 24 ++++----- hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp | 4 +- hotspot/src/cpu/x86/vm/x86_64.ad | 6 +-- .../concurrentMarkSweepGeneration.cpp | 4 +- hotspot/src/share/vm/memory/metaspace.cpp | 32 ++++++------ hotspot/src/share/vm/memory/metaspace.hpp | 4 +- .../src/share/vm/memory/metaspaceCounters.cpp | 4 +- hotspot/src/share/vm/memory/universe.cpp | 2 +- hotspot/src/share/vm/memory/universe.hpp | 6 +-- hotspot/src/share/vm/oops/arrayOop.hpp | 2 +- hotspot/src/share/vm/oops/instanceOop.hpp | 4 +- hotspot/src/share/vm/oops/oop.inline.hpp | 18 +++---- hotspot/src/share/vm/opto/cfgnode.cpp | 2 +- hotspot/src/share/vm/opto/compile.cpp | 4 +- hotspot/src/share/vm/opto/connode.cpp | 2 +- hotspot/src/share/vm/opto/library_call.cpp | 2 +- hotspot/src/share/vm/opto/live.cpp | 2 +- hotspot/src/share/vm/opto/macro.cpp | 2 +- hotspot/src/share/vm/opto/memnode.cpp | 4 +- hotspot/src/share/vm/opto/type.cpp | 2 +- hotspot/src/share/vm/runtime/arguments.cpp | 44 +++++++++-------- hotspot/src/share/vm/runtime/globals.hpp | 10 ++-- hotspot/src/share/vm/services/memoryPool.cpp | 2 +- .../src/share/vm/services/memoryService.cpp | 2 +- .../arguments/TestCompressedClassFlags.java | 49 +++++++++++++++++++ ...> CompressedClassSpaceSizeInJmapHeap.java} | 14 +++--- .../gc/metaspace/TestMetaspaceMemoryPool.java | 4 +- .../metaspace/TestMetaspacePerfCounters.java | 14 +++--- .../CDSCompressedKPtrs.java | 6 +-- .../CDSCompressedKPtrsError.java | 16 +++--- .../CompressedKlassPointerAndOops.java | 4 +- 43 files changed, 228 insertions(+), 175 deletions(-) create mode 100644 hotspot/test/gc/arguments/TestCompressedClassFlags.java rename hotspot/test/gc/metaspace/{ClassMetaspaceSizeInJmapHeap.java => CompressedClassSpaceSizeInJmapHeap.java} (83%) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java index f84da894ac2..319d2430af2 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -792,7 +792,7 @@ public class VM { public boolean isCompressedKlassPointersEnabled() { if (compressedKlassPointersEnabled == null) { - Flag flag = getCommandLineFlag("UseCompressedKlassPointers"); + Flag flag = getCommandLineFlag("UseCompressedClassPointers"); compressedKlassPointersEnabled = (flag == null) ? Boolean.FALSE: (flag.getBool()? Boolean.TRUE: Boolean.FALSE); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index a0123dd4c99..daab682aaef 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -66,18 +66,18 @@ public class HeapSummary extends Tool { printGCAlgorithm(flagMap); System.out.println(); System.out.println("Heap Configuration:"); - printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap)); - printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap)); - printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap)); - printValMB("NewSize = ", getFlagValue("NewSize", flagMap)); - printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap)); - printValMB("OldSize = ", getFlagValue("OldSize", flagMap)); - printValue("NewRatio = ", getFlagValue("NewRatio", flagMap)); - printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap)); - printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap)); - printValMB("ClassMetaspaceSize = ", getFlagValue("ClassMetaspaceSize", flagMap)); - printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap)); - printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes()); + printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap)); + printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap)); + printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap)); + printValMB("NewSize = ", getFlagValue("NewSize", flagMap)); + printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap)); + printValMB("OldSize = ", getFlagValue("OldSize", flagMap)); + printValue("NewRatio = ", getFlagValue("NewRatio", flagMap)); + printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap)); + printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap)); + printValMB("CompressedClassSpaceSize = ", getFlagValue("CompressedClassSpaceSize", flagMap)); + printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap)); + printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes()); System.out.println(); System.out.println("Heap Usage:"); diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index 12d51571ccb..cb4c04a388b 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -105,7 +105,7 @@ bool LIR_Assembler::is_single_instruction(LIR_Op* op) { if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false; } - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { if (src->is_address() && !src->is_stack() && src->type() == T_ADDRESS && src->as_address_ptr()->disp() == oopDesc::klass_offset_in_bytes()) return false; } @@ -963,7 +963,7 @@ int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType typ case T_METADATA: __ ld_ptr(base, offset, to_reg->as_register()); break; case T_ADDRESS: #ifdef _LP64 - if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedKlassPointers) { + if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedClassPointers) { __ lduw(base, offset, to_reg->as_register()); __ decode_klass_not_null(to_reg->as_register()); } else @@ -2208,7 +2208,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // We don't know the array types are compatible if (basic_type != T_OBJECT) { // Simple test for basic type arrays - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // We don't need decode because we just need to compare __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp); __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); @@ -2342,7 +2342,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // but not necessarily exactly of type default_type. Label known_ok, halt; metadata2reg(op->expected_type()->constant_encoding(), tmp); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // tmp holds the default type. It currently comes uncompressed after the // load of a constant, so encode it. __ encode_klass_not_null(tmp); diff --git a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp index bf4074b30fd..6d10ab81aaf 100644 --- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp @@ -186,7 +186,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register set((intx)markOopDesc::prototype(), t1); } st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // Save klass mov(klass, t1); encode_klass_not_null(t1); @@ -196,7 +196,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register } if (len->is_valid()) { st(len, obj, arrayOopDesc::length_offset_in_bytes()); - } else if (UseCompressedKlassPointers) { + } else if (UseCompressedClassPointers) { // otherwise length is in the class gap store_klass_gap(G0, obj); } diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp index d2c4e3b0261..9f1f2e53371 100644 --- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -3911,7 +3911,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) { // The number of bytes in this code is used by // MachCallDynamicJavaNode::ret_addr_offset() // if this changes, change that. - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass); decode_klass_not_null(klass); } else { @@ -3920,7 +3920,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) { } void MacroAssembler::store_klass(Register klass, Register dst_oop) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(dst_oop != klass, "not enough registers"); encode_klass_not_null(klass); st(klass, dst_oop, oopDesc::klass_offset_in_bytes()); @@ -3930,7 +3930,7 @@ void MacroAssembler::store_klass(Register klass, Register dst_oop) { } void MacroAssembler::store_klass_gap(Register s, Register d) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(s != d, "not enough registers"); st(s, d, oopDesc::klass_gap_offset_in_bytes()); } @@ -4089,7 +4089,7 @@ void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) { } void MacroAssembler::encode_klass_not_null(Register r) { - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); assert(r != G6_heapbase, "bad register choice"); set((intptr_t)Universe::narrow_klass_base(), G6_heapbase); @@ -4105,7 +4105,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) { if (src == dst) { encode_klass_not_null(src); } else { - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); set((intptr_t)Universe::narrow_klass_base(), dst); sub(src, dst, dst); @@ -4119,7 +4119,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) { // generated by decode_klass_not_null() and reinit_heapbase(). Hence, if // the instructions they generate change, then this method needs to be updated. int MacroAssembler::instr_size_for_decode_klass_not_null() { - assert (UseCompressedKlassPointers, "only for compressed klass ptrs"); + assert (UseCompressedClassPointers, "only for compressed klass ptrs"); // set + add + set int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 + insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base()); @@ -4135,7 +4135,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() { void MacroAssembler::decode_klass_not_null(Register r) { // Do not add assert code to this unless you change vtableStubs_sparc.cpp // pd_code_size_limit. - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); assert(r != G6_heapbase, "bad register choice"); set((intptr_t)Universe::narrow_klass_base(), G6_heapbase); @@ -4151,7 +4151,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) { } else { // Do not add assert code to this unless you change vtableStubs_sparc.cpp // pd_code_size_limit. - assert (UseCompressedKlassPointers, "must be compressed"); + assert (UseCompressedClassPointers, "must be compressed"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); if (Universe::narrow_klass_shift() != 0) { assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice"); @@ -4167,7 +4167,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) { } void MacroAssembler::reinit_heapbase() { - if (UseCompressedOops || UseCompressedKlassPointers) { + if (UseCompressedOops || UseCompressedClassPointers) { if (Universe::heap() != NULL) { set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase); } else { diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index a72bffdadeb..58c113a0c1a 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -557,7 +557,7 @@ int MachCallDynamicJavaNode::ret_addr_offset() { int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); int klass_load_size; - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(Universe::heap() != NULL, "java heap should be initialized"); klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord; } else { @@ -1657,7 +1657,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const { void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { st->print_cr("\nUEP:"); #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(Universe::heap() != NULL, "java heap should be initialized"); st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass"); st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base"); @@ -1897,7 +1897,7 @@ bool Matcher::narrow_oop_use_complex_address() { bool Matcher::narrow_klass_use_complex_address() { NOT_LP64(ShouldNotCallThis()); - assert(UseCompressedKlassPointers, "only for compressed klass code"); + assert(UseCompressedClassPointers, "only for compressed klass code"); return false; } @@ -2561,7 +2561,7 @@ encode %{ int off = __ offset(); __ load_klass(O0, G3_scratch); int klass_load_size; - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { assert(Universe::heap() != NULL, "java heap should be initialized"); klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord; } else { diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp index 214940cdbfb..612ae118ee4 100644 --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -2945,7 +2945,7 @@ class StubGenerator: public StubCodeGenerator { BLOCK_COMMENT("arraycopy argument klass checks"); // get src->klass() - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ delayed()->nop(); // ??? not good __ load_klass(src, G3_src_klass); } else { @@ -2980,7 +2980,7 @@ class StubGenerator: public StubCodeGenerator { // Load 32-bits signed value. Use br() instruction with it to check icc. __ lduw(G3_src_klass, lh_offset, G5_lh); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ load_klass(dst, G4_dst_klass); } // Handle objArrays completely differently... @@ -2988,7 +2988,7 @@ class StubGenerator: public StubCodeGenerator { __ set(objArray_lh, O5_temp); __ cmp(G5_lh, O5_temp); __ br(Assembler::equal, false, Assembler::pt, L_objArray); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ delayed()->nop(); } else { __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp index 39663758035..ce19d4d7e7b 100644 --- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp @@ -218,13 +218,13 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) { // ld;ld;ld,jmp,nop const int basic = 5*BytesPerInstWord + // shift;add for load_klass (only shift with zero heap based) - (UseCompressedKlassPointers ? + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); return basic + slop; } else { const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord + // shift;add for load_klass (only shift with zero heap based) - (UseCompressedKlassPointers ? + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); return (basic + slop); } diff --git a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp index ea5d6d39da6..2d1b5f1f3c7 100644 --- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.hpp @@ -148,7 +148,7 @@ static int adjust_reg_range(int range) { // Reduce the number of available regs (to free r12) in case of compressed oops - if (UseCompressedOops || UseCompressedKlassPointers) return range - 1; + if (UseCompressedOops || UseCompressedClassPointers) return range - 1; return range; } diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 334d0cc92db..735d343898f 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -341,7 +341,7 @@ int LIR_Assembler::check_icache() { Register receiver = FrameMap::receiver_opr->as_register(); Register ic_klass = IC_Klass; const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); - const bool do_post_padding = VerifyOops || UseCompressedKlassPointers; + const bool do_post_padding = VerifyOops || UseCompressedClassPointers; if (!do_post_padding) { // insert some nops so that the verified entry point is aligned on CodeEntryAlignment while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { @@ -1263,7 +1263,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch break; case T_ADDRESS: - if (UseCompressedKlassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) { + if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) { __ movl(dest->as_register(), from_addr); } else { __ movptr(dest->as_register(), from_addr); @@ -1371,7 +1371,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch __ verify_oop(dest->as_register()); } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) { #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ decode_klass_not_null(dest->as_register()); } #endif @@ -1716,7 +1716,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } else if (obj == klass_RInfo) { klass_RInfo = dst; } - if (k->is_loaded() && !UseCompressedKlassPointers) { + if (k->is_loaded() && !UseCompressedClassPointers) { select_different_registers(obj, dst, k_RInfo, klass_RInfo); } else { Rtmp1 = op->tmp3()->as_register(); @@ -1754,7 +1754,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L // get object class // not a safepoint as obj null check happens earlier #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ load_klass(Rtmp1, obj); __ cmpptr(k_RInfo, Rtmp1); } else { @@ -3294,7 +3294,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { // We don't know the array types are compatible if (basic_type != T_OBJECT) { // Simple test for basic type arrays - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ movl(tmp, src_klass_addr); __ cmpl(tmp, dst_klass_addr); } else { @@ -3456,21 +3456,21 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { Label known_ok, halt; __ mov_metadata(tmp, default_type->constant_encoding()); #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { __ encode_klass_not_null(tmp); } #endif if (basic_type != T_OBJECT) { - if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr); + if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr); else __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::notEqual, halt); - if (UseCompressedKlassPointers) __ cmpl(tmp, src_klass_addr); + if (UseCompressedClassPointers) __ cmpl(tmp, src_klass_addr); else __ cmpptr(tmp, src_klass_addr); __ jcc(Assembler::equal, known_ok); } else { - if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr); + if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr); else __ cmpptr(tmp, dst_klass_addr); __ jcc(Assembler::equal, known_ok); __ cmpptr(src, dst); diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index e6638581bcf..308befddc77 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -1239,7 +1239,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) { } LIR_Opr reg = rlock_result(x); LIR_Opr tmp3 = LIR_OprFact::illegalOpr; - if (!x->klass()->is_loaded() || UseCompressedKlassPointers) { + if (!x->klass()->is_loaded() || UseCompressedClassPointers) { tmp3 = new_register(objectType); } __ checkcast(reg, obj.result(), x->klass(), @@ -1261,7 +1261,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) { } obj.load_item(); LIR_Opr tmp3 = LIR_OprFact::illegalOpr; - if (!x->klass()->is_loaded() || UseCompressedKlassPointers) { + if (!x->klass()->is_loaded() || UseCompressedClassPointers) { tmp3 = new_register(objectType); } __ instanceof(reg, obj.result(), x->klass(), diff --git a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp index d9ae6ce5de5..805fe5a48ca 100644 --- a/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp @@ -157,7 +157,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype()); } #ifdef _LP64 - if (UseCompressedKlassPointers) { // Take care not to kill klass + if (UseCompressedClassPointers) { // Take care not to kill klass movptr(t1, klass); encode_klass_not_null(t1); movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1); @@ -171,7 +171,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); } #ifdef _LP64 - else if (UseCompressedKlassPointers) { + else if (UseCompressedClassPointers) { xorptr(t1, t1); store_klass_gap(obj, t1); } @@ -334,7 +334,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); int start_offset = offset(); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { load_klass(rscratch1, receiver); cmpptr(rscratch1, iCache); } else { @@ -345,7 +345,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); - assert(UseCompressedKlassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); + assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry"); } diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index b331f694959..fed50ef4286 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -1635,7 +1635,7 @@ void MacroAssembler::call_VM_base(Register oop_result, #ifdef ASSERT // TraceBytecodes does not use r12 but saves it over the call, so don't verify // r12 is the heapbase. - LP64_ONLY(if ((UseCompressedOops || UseCompressedKlassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");) + LP64_ONLY(if ((UseCompressedOops || UseCompressedClassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");) #endif // ASSERT assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); @@ -4802,7 +4802,7 @@ void MacroAssembler::restore_cpu_control_state_after_jni() { void MacroAssembler::load_klass(Register dst, Register src) { #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); decode_klass_not_null(dst); } else @@ -4817,7 +4817,7 @@ void MacroAssembler::load_prototype_header(Register dst, Register src) { void MacroAssembler::store_klass(Register dst, Register src) { #ifdef _LP64 - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { encode_klass_not_null(src); movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); } else @@ -4892,7 +4892,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) { #ifdef _LP64 void MacroAssembler::store_klass_gap(Register dst, Register src) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // Store to klass gap in destination movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); } @@ -5075,7 +5075,7 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) { // when (Universe::heap() != NULL). Hence, if the instructions they // generate change, then this method needs to be updated. int MacroAssembler::instr_size_for_decode_klass_not_null() { - assert (UseCompressedKlassPointers, "only for compressed klass ptrs"); + assert (UseCompressedClassPointers, "only for compressed klass ptrs"); // mov64 + addq + shlq? + mov64 (for reinit_heapbase()). return (Universe::narrow_klass_shift() == 0 ? 20 : 24); } @@ -5085,7 +5085,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() { void MacroAssembler::decode_klass_not_null(Register r) { // Note: it will change flags assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert(r != r12_heapbase, "Decoding a klass in r12"); // Cannot assert, unverified entry point counts instructions (see .ad file) // vtableStubs also counts instructions in pd_code_size_limit. @@ -5103,7 +5103,7 @@ void MacroAssembler::decode_klass_not_null(Register r) { void MacroAssembler::decode_klass_not_null(Register dst, Register src) { // Note: it will change flags assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); if (dst == src) { decode_klass_not_null(dst); } else { @@ -5141,7 +5141,7 @@ void MacroAssembler::set_narrow_oop(Address dst, jobject obj) { } void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5149,7 +5149,7 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { } void MacroAssembler::set_narrow_klass(Address dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5175,7 +5175,7 @@ void MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) { } void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5183,7 +5183,7 @@ void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) { } void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { - assert (UseCompressedKlassPointers, "should only be used for compressed headers"); + assert (UseCompressedClassPointers, "should only be used for compressed headers"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder"); int klass_index = oop_recorder()->find_index(k); RelocationHolder rspec = metadata_Relocation::spec(klass_index); @@ -5191,7 +5191,7 @@ void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { } void MacroAssembler::reinit_heapbase() { - if (UseCompressedOops || UseCompressedKlassPointers) { + if (UseCompressedOops || UseCompressedClassPointers) { if (Universe::heap() != NULL) { if (Universe::narrow_oop_base() == NULL) { MacroAssembler::xorptr(r12_heapbase, r12_heapbase); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 518da23eb60..5f5f94f41a5 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -211,11 +211,11 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) { if (is_vtable_stub) { // Vtable stub size return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0) + - (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); } else { // Itable stub size return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) + - (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); + (UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0); } // In order to tune these parameters, run the JVM with VM options // +PrintMiscellaneous and +WizardMode to see information about diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index f550208e94d..ed13b3da1d1 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -1391,7 +1391,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const #ifndef PRODUCT void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); @@ -1408,7 +1408,7 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { MacroAssembler masm(&cbuf); uint insts_size = cbuf.insts_size(); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { masm.load_klass(rscratch1, j_rarg0); masm.cmpptr(rax, rscratch1); } else { @@ -1557,7 +1557,7 @@ bool Matcher::narrow_oop_use_complex_address() { } bool Matcher::narrow_klass_use_complex_address() { - assert(UseCompressedKlassPointers, "only for compressed klass code"); + assert(UseCompressedClassPointers, "only for compressed klass code"); return (LogKlassAlignmentInBytes <= 3); } diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 04b550c718b..2fc6edd34df 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -230,7 +230,7 @@ ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration( // depends on this property. debug_only( FreeChunk* junk = NULL; - assert(UseCompressedKlassPointers || + assert(UseCompressedClassPointers || junk->prev_addr() == (void*)(oop(junk)->klass_addr()), "Offset of FreeChunk::_prev within FreeChunk must match" " that of OopDesc::_klass within OopDesc"); @@ -1407,7 +1407,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num, assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size"); OrderAccess::storestore(); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { // Copy gap missed by (aligned) header size calculation below obj->set_klass_gap(old->klass_gap()); } diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index cd46888c9c2..1c5cec84d5f 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -423,7 +423,7 @@ class VirtualSpaceList : public CHeapObj { // Can this virtual list allocate >1 spaces? Also, used to determine // whether to allocate unlimited small chunks in this virtual space bool _is_class; - bool can_grow() const { return !is_class() || !UseCompressedKlassPointers; } + bool can_grow() const { return !is_class() || !UseCompressedClassPointers; } // Sum of space in all virtual spaces and number of virtual spaces size_t _virtual_space_total; @@ -2836,7 +2836,7 @@ void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address // to work with compressed klass pointers. bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) { assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS"); - assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs"); + assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs"); address lower_base = MIN2((address)metaspace_base, cds_base); address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()), (address)(metaspace_base + class_metaspace_size())); @@ -2846,7 +2846,7 @@ bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cd // Try to allocate the metaspace at the requested addr. void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) { assert(using_class_space(), "called improperly"); - assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs"); + assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs"); assert(class_metaspace_size() < KlassEncodingMetaspaceMax, "Metaspace size is too big"); @@ -2869,9 +2869,9 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a // If no successful allocation then try to allocate the space anywhere. If // that fails then OOM doom. At this point we cannot try allocating the - // metaspace as if UseCompressedKlassPointers is off because too much - // initialization has happened that depends on UseCompressedKlassPointers. - // So, UseCompressedKlassPointers cannot be turned off at this point. + // metaspace as if UseCompressedClassPointers is off because too much + // initialization has happened that depends on UseCompressedClassPointers. + // So, UseCompressedClassPointers cannot be turned off at this point. if (!metaspace_rs.is_reserved()) { metaspace_rs = ReservedSpace(class_metaspace_size(), os::vm_allocation_granularity(), false); @@ -2904,12 +2904,12 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a } } -// For UseCompressedKlassPointers the class space is reserved above the top of +// For UseCompressedClassPointers the class space is reserved above the top of // the Java heap. The argument passed in is at the base of the compressed space. void Metaspace::initialize_class_space(ReservedSpace rs) { // The reserved space size may be bigger because of alignment, esp with UseLargePages - assert(rs.size() >= ClassMetaspaceSize, - err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize)); + assert(rs.size() >= CompressedClassSpaceSize, + err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); assert(using_class_space(), "Must be using class space"); _class_space_list = new VirtualSpaceList(rs); } @@ -2921,7 +2921,7 @@ void Metaspace::global_initialize() { int max_alignment = os::vm_page_size(); size_t cds_total = 0; - set_class_metaspace_size(align_size_up(ClassMetaspaceSize, + set_class_metaspace_size(align_size_up(CompressedClassSpaceSize, os::vm_allocation_granularity())); MetaspaceShared::set_max_alignment(max_alignment); @@ -2941,8 +2941,8 @@ void Metaspace::global_initialize() { #ifdef _LP64 // Set the compressed klass pointer base so that decoding of these pointers works // properly when creating the shared archive. - assert(UseCompressedOops && UseCompressedKlassPointers, - "UseCompressedOops and UseCompressedKlassPointers must be set"); + assert(UseCompressedOops && UseCompressedClassPointers, + "UseCompressedOops and UseCompressedClassPointers must be set"); Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom()); if (TraceMetavirtualspaceAllocation && Verbose) { gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT, @@ -2979,7 +2979,7 @@ void Metaspace::global_initialize() { } #ifdef _LP64 - // If UseCompressedKlassPointers is set then allocate the metaspace area + // If UseCompressedClassPointers is set then allocate the metaspace area // above the heap and above the CDS area (if it exists). if (using_class_space()) { if (UseSharedSpaces) { @@ -2997,7 +2997,7 @@ void Metaspace::global_initialize() { // on the medium chunk list. The next chunk will be small and progress // from there. This size calculated by -version. _first_class_chunk_word_size = MIN2((size_t)MediumChunk*6, - (ClassMetaspaceSize/BytesPerWord)*2); + (CompressedClassSpaceSize/BytesPerWord)*2); _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size); // Arbitrarily set the initial virtual space to a multiple // of the boot class loader size. @@ -3064,7 +3064,7 @@ size_t Metaspace::align_word_size_up(size_t word_size) { MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { // DumpSharedSpaces doesn't use class metadata area (yet) - // Also, don't use class_vsm() unless UseCompressedKlassPointers is true. + // Also, don't use class_vsm() unless UseCompressedClassPointers is true. if (mdtype == ClassType && using_class_space()) { return class_vsm()->allocate(word_size); } else { @@ -3213,7 +3213,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, MetaspaceAux::dump(gclog_or_tty); } // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support - const char* space_string = (mdtype == ClassType) ? "Class Metadata space" : + const char* space_string = (mdtype == ClassType) ? "Compressed class space" : "Metadata space"; report_java_out_of_memory(space_string); diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 88f089494d3..591acf30075 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -213,9 +213,9 @@ class Metaspace : public CHeapObj { void iterate(AllocRecordClosure *closure); - // Return TRUE only if UseCompressedKlassPointers is True and DumpSharedSpaces is False. + // Return TRUE only if UseCompressedClassPointers is True and DumpSharedSpaces is False. static bool using_class_space() { - return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces); + return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces); } }; diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp index eb7bebd28b6..32eda2b4ed8 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp @@ -109,7 +109,7 @@ size_t CompressedClassSpaceCounters::calculate_capacity() { } void CompressedClassSpaceCounters::update_performance_counters() { - if (UsePerfData && UseCompressedKlassPointers) { + if (UsePerfData && UseCompressedClassPointers) { assert(_perf_counters != NULL, "Should be initialized"); size_t capacity = calculate_capacity(); @@ -125,7 +125,7 @@ void CompressedClassSpaceCounters::initialize_performance_counters() { assert(_perf_counters == NULL, "Should only be initialized once"); const char* ns = "compressedclassspace"; - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { size_t min_capacity = MetaspaceAux::min_chunk_size(); size_t capacity = calculate_capacity(); size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type); diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 143c0c00c45..d0f34b33ae1 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -1028,7 +1028,7 @@ bool universe_post_init() { msg = java_lang_String::create_from_str("Metadata space", CHECK_false); java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg()); - msg = java_lang_String::create_from_str("Class Metadata space", CHECK_false); + msg = java_lang_String::create_from_str("Compressed class space", CHECK_false); java_lang_Throwable::set_message(Universe::_out_of_memory_error_class_metaspace, msg()); msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false); diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index a8b541d03a1..4c698f95174 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -181,7 +181,7 @@ class Universe: AllStatic { // For UseCompressedOops. static struct NarrowPtrStruct _narrow_oop; - // For UseCompressedKlassPointers. + // For UseCompressedClassPointers. static struct NarrowPtrStruct _narrow_klass; static address _narrow_ptrs_base; @@ -229,7 +229,7 @@ class Universe: AllStatic { _narrow_oop._base = base; } static void set_narrow_klass_base(address base) { - assert(UseCompressedKlassPointers, "no compressed klass ptrs?"); + assert(UseCompressedClassPointers, "no compressed klass ptrs?"); _narrow_klass._base = base; } static void set_narrow_oop_use_implicit_null_checks(bool use) { @@ -353,7 +353,7 @@ class Universe: AllStatic { static int narrow_oop_shift() { return _narrow_oop._shift; } static bool narrow_oop_use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; } - // For UseCompressedKlassPointers + // For UseCompressedClassPointers static address narrow_klass_base() { return _narrow_klass._base; } static bool is_narrow_klass_base(void* addr) { return (narrow_klass_base() == (address)addr); } static int narrow_klass_shift() { return _narrow_klass._shift; } diff --git a/hotspot/src/share/vm/oops/arrayOop.hpp b/hotspot/src/share/vm/oops/arrayOop.hpp index 806b7b7289a..0e5ceffe35a 100644 --- a/hotspot/src/share/vm/oops/arrayOop.hpp +++ b/hotspot/src/share/vm/oops/arrayOop.hpp @@ -65,7 +65,7 @@ class arrayOopDesc : public oopDesc { // declared nonstatic fields in arrayOopDesc if not compressed, otherwise // it occupies the second half of the _klass field in oopDesc. static int length_offset_in_bytes() { - return UseCompressedKlassPointers ? klass_gap_offset_in_bytes() : + return UseCompressedClassPointers ? klass_gap_offset_in_bytes() : sizeof(arrayOopDesc); } diff --git a/hotspot/src/share/vm/oops/instanceOop.hpp b/hotspot/src/share/vm/oops/instanceOop.hpp index 9ebb9d4720b..bdac1992e6f 100644 --- a/hotspot/src/share/vm/oops/instanceOop.hpp +++ b/hotspot/src/share/vm/oops/instanceOop.hpp @@ -37,9 +37,9 @@ class instanceOopDesc : public oopDesc { // If compressed, the offset of the fields of the instance may not be aligned. static int base_offset_in_bytes() { - // offset computation code breaks if UseCompressedKlassPointers + // offset computation code breaks if UseCompressedClassPointers // only is true - return (UseCompressedOops && UseCompressedKlassPointers) ? + return (UseCompressedOops && UseCompressedClassPointers) ? klass_gap_offset_in_bytes() : sizeof(instanceOopDesc); } diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index 9a6c1e1787b..f1823f2e2b1 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -69,7 +69,7 @@ inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) { } inline Klass* oopDesc::klass() const { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { return Klass::decode_klass_not_null(_metadata._compressed_klass); } else { return _metadata._klass; @@ -78,7 +78,7 @@ inline Klass* oopDesc::klass() const { inline Klass* oopDesc::klass_or_null() const volatile { // can be NULL in CMS - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { return Klass::decode_klass(_metadata._compressed_klass); } else { return _metadata._klass; @@ -86,19 +86,19 @@ inline Klass* oopDesc::klass_or_null() const volatile { } inline int oopDesc::klass_gap_offset_in_bytes() { - assert(UseCompressedKlassPointers, "only applicable to compressed klass pointers"); + assert(UseCompressedClassPointers, "only applicable to compressed klass pointers"); return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass); } inline Klass** oopDesc::klass_addr() { // Only used internally and with CMS and will not work with // UseCompressedOops - assert(!UseCompressedKlassPointers, "only supported with uncompressed klass pointers"); + assert(!UseCompressedClassPointers, "only supported with uncompressed klass pointers"); return (Klass**) &_metadata._klass; } inline narrowKlass* oopDesc::compressed_klass_addr() { - assert(UseCompressedKlassPointers, "only called by compressed klass pointers"); + assert(UseCompressedClassPointers, "only called by compressed klass pointers"); return &_metadata._compressed_klass; } @@ -106,7 +106,7 @@ inline void oopDesc::set_klass(Klass* k) { // since klasses are promoted no store check is needed assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*"); assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*"); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { *compressed_klass_addr() = Klass::encode_klass_not_null(k); } else { *klass_addr() = k; @@ -118,7 +118,7 @@ inline int oopDesc::klass_gap() const { } inline void oopDesc::set_klass_gap(int v) { - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v; } } @@ -126,7 +126,7 @@ inline void oopDesc::set_klass_gap(int v) { inline void oopDesc::set_klass_to_list_ptr(oop k) { // This is only to be used during GC, for from-space objects, so no // barrier is needed. - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { _metadata._compressed_klass = (narrowKlass)encode_heap_oop(k); // may be null (parnew overflow handling) } else { _metadata._klass = (Klass*)(address)k; @@ -135,7 +135,7 @@ inline void oopDesc::set_klass_to_list_ptr(oop k) { inline oop oopDesc::list_ptr_from_klass() { // This is only to be used during GC, for from-space objects. - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { return decode_heap_oop((narrowOop)_metadata._compressed_klass); } else { // Special case for GC diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 4185ada5d1c..36347fb9202 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -1932,7 +1932,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { #ifdef _LP64 // Push DecodeN/DecodeNKlass down through phi. // The rest of phi graph will transform by split EncodeP node though phis up. - if ((UseCompressedOops || UseCompressedKlassPointers) && can_reshape && progress == NULL) { + if ((UseCompressedOops || UseCompressedClassPointers) && can_reshape && progress == NULL) { bool may_push = true; bool has_decodeN = false; bool is_decodeN = false; diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index b426bcce1a2..69b6ca05c84 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -2631,7 +2631,7 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) { addp->in(AddPNode::Base) == n->in(AddPNode::Base), "Base pointers must match" ); #ifdef _LP64 - if ((UseCompressedOops || UseCompressedKlassPointers) && + if ((UseCompressedOops || UseCompressedClassPointers) && addp->Opcode() == Op_ConP && addp == n->in(AddPNode::Base) && n->in(AddPNode::Offset)->is_Con()) { @@ -3018,7 +3018,7 @@ void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_ // Skip next transformation if compressed oops are not used. if ((UseCompressedOops && !Matcher::gen_narrow_oop_implicit_null_checks()) || - (!UseCompressedOops && !UseCompressedKlassPointers)) + (!UseCompressedOops && !UseCompressedClassPointers)) return; // Go over safepoints nodes to skip DecodeN/DecodeNKlass nodes for debug edges. diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp index eb343a822e5..b59025ad4f3 100644 --- a/hotspot/src/share/vm/opto/connode.cpp +++ b/hotspot/src/share/vm/opto/connode.cpp @@ -630,7 +630,7 @@ const Type *EncodePKlassNode::Value( PhaseTransform *phase ) const { if (t == Type::TOP) return Type::TOP; assert (t != TypePtr::NULL_PTR, "null klass?"); - assert(UseCompressedKlassPointers && t->isa_klassptr(), "only klass ptr here"); + assert(UseCompressedClassPointers && t->isa_klassptr(), "only klass ptr here"); return t->make_narrowklass(); } diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 60525d73ef7..d3f5e18440c 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -4199,7 +4199,7 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b // 12 - 64-bit VM, compressed klass // 16 - 64-bit VM, normal klass if (base_off % BytesPerLong != 0) { - assert(UseCompressedKlassPointers, ""); + assert(UseCompressedClassPointers, ""); if (is_array) { // Exclude length to copy by 8 bytes words. base_off += sizeof(int); diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index 280d22204c2..70bcd8549c9 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -321,7 +321,7 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const { #ifdef _LP64 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP || UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN || - UseCompressedKlassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass || + UseCompressedClassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass || #endif check->as_Mach()->ideal_Opcode() == Op_LoadP || check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) { diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 137c529ed0c..06bf9e608c0 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -2191,7 +2191,7 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) { Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes()); klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) ); #ifdef _LP64 - if (UseCompressedKlassPointers && klass_node->is_DecodeNKlass()) { + if (UseCompressedClassPointers && klass_node->is_DecodeNKlass()) { assert(klass_node->in(1)->Opcode() == Op_LoadNKlass, "sanity"); klass_node->in(1)->init_req(0, ctrl); } else diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index aa03b5ff6c5..01deaf07701 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1971,7 +1971,7 @@ Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* a assert(adr_type != NULL, "expecting TypeKlassPtr"); #ifdef _LP64 if (adr_type->is_ptr_to_narrowklass()) { - assert(UseCompressedKlassPointers, "no compressed klasses"); + assert(UseCompressedClassPointers, "no compressed klasses"); Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass())); return new (C) DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr()); } @@ -2309,7 +2309,7 @@ StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, cons val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop())); return new (C) StoreNNode(ctl, mem, adr, adr_type, val); } else if (adr->bottom_type()->is_ptr_to_narrowklass() || - (UseCompressedKlassPointers && val->bottom_type()->isa_klassptr() && + (UseCompressedClassPointers && val->bottom_type()->isa_klassptr() && adr->bottom_type()->isa_rawptr())) { val = gvn.transform(new (C) EncodePKlassNode(val, val->bottom_type()->make_narrowklass())); return new (C) StoreNKlassNode(ctl, mem, adr, adr_type, val); diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index fabcf1cad16..5fa6bfa8815 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -2381,7 +2381,7 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int #ifdef _LP64 if (_offset != 0) { if (_offset == oopDesc::klass_offset_in_bytes()) { - _is_ptr_to_narrowklass = UseCompressedKlassPointers; + _is_ptr_to_narrowklass = UseCompressedClassPointers; } else if (klass() == NULL) { // Array with unknown body type assert(this->isa_aryptr(), "only arrays without klass"); diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index d8a6f90eeef..fbce8b6b695 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1439,7 +1439,7 @@ void Arguments::set_use_compressed_oops() { if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) { warning("Max heap size too large for Compressed Oops"); FLAG_SET_DEFAULT(UseCompressedOops, false); - FLAG_SET_DEFAULT(UseCompressedKlassPointers, false); + FLAG_SET_DEFAULT(UseCompressedClassPointers, false); } } #endif // _LP64 @@ -1452,22 +1452,22 @@ void Arguments::set_use_compressed_oops() { void Arguments::set_use_compressed_klass_ptrs() { #ifndef ZERO #ifdef _LP64 - // UseCompressedOops must be on for UseCompressedKlassPointers to be on. + // UseCompressedOops must be on for UseCompressedClassPointers to be on. if (!UseCompressedOops) { - if (UseCompressedKlassPointers) { - warning("UseCompressedKlassPointers requires UseCompressedOops"); + if (UseCompressedClassPointers) { + warning("UseCompressedClassPointers requires UseCompressedOops"); } - FLAG_SET_DEFAULT(UseCompressedKlassPointers, false); + FLAG_SET_DEFAULT(UseCompressedClassPointers, false); } else { - // Turn on UseCompressedKlassPointers too - if (FLAG_IS_DEFAULT(UseCompressedKlassPointers)) { - FLAG_SET_ERGO(bool, UseCompressedKlassPointers, true); + // Turn on UseCompressedClassPointers too + if (FLAG_IS_DEFAULT(UseCompressedClassPointers)) { + FLAG_SET_ERGO(bool, UseCompressedClassPointers, true); } - // Check the ClassMetaspaceSize to make sure we use compressed klass ptrs. - if (UseCompressedKlassPointers) { - if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) { - warning("Class metaspace size is too large for UseCompressedKlassPointers"); - FLAG_SET_DEFAULT(UseCompressedKlassPointers, false); + // Check the CompressedClassSpaceSize to make sure we use compressed klass ptrs. + if (UseCompressedClassPointers) { + if (CompressedClassSpaceSize > KlassEncodingMetaspaceMax) { + warning("CompressedClassSpaceSize is too large for UseCompressedClassPointers"); + FLAG_SET_DEFAULT(UseCompressedClassPointers, false); } } } @@ -2148,8 +2148,8 @@ bool Arguments::check_vm_args_consistency() { status = status && verify_object_alignment(); - status = status && verify_interval(ClassMetaspaceSize, 1*M, 3*G, - "ClassMetaspaceSize"); + status = status && verify_interval(CompressedClassSpaceSize, 1*M, 3*G, + "CompressedClassSpaceSize"); status = status && verify_interval(MarkStackSizeMax, 1, (max_jint - 1), "MarkStackSizeMax"); @@ -3274,13 +3274,13 @@ void Arguments::set_shared_spaces_flags() { } UseSharedSpaces = false; #ifdef _LP64 - if (!UseCompressedOops || !UseCompressedKlassPointers) { + if (!UseCompressedOops || !UseCompressedClassPointers) { vm_exit_during_initialization( - "Cannot dump shared archive when UseCompressedOops or UseCompressedKlassPointers is off.", NULL); + "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL); } } else { - // UseCompressedOops and UseCompressedKlassPointers must be on for UseSharedSpaces. - if (!UseCompressedOops || !UseCompressedKlassPointers) { + // UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces. + if (!UseCompressedOops || !UseCompressedClassPointers) { no_shared_spaces(); } #endif @@ -3581,7 +3581,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) { FLAG_SET_DEFAULT(ProfileInterpreter, false); FLAG_SET_DEFAULT(UseBiasedLocking, false); LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false)); - LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedKlassPointers, false)); + LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedClassPointers, false)); #endif // CC_INTERP #ifdef COMPILER2 @@ -3610,6 +3610,10 @@ jint Arguments::parse(const JavaVMInitArgs* args) { DebugNonSafepoints = true; } + if (FLAG_IS_CMDLINE(CompressedClassSpaceSize) && !UseCompressedClassPointers) { + warning("Setting CompressedClassSpaceSize has no effect when compressed class pointers are not used"); + } + #ifndef PRODUCT if (CompileTheWorld) { // Force NmethodSweeper to sweep whole CodeCache each time. diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index c9bcbe1f4d3..2633bf21265 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -443,8 +443,8 @@ class CommandLineFlags { "Use 32-bit object references in 64-bit VM " \ "lp64_product means flag is always constant in 32 bit VM") \ \ - lp64_product(bool, UseCompressedKlassPointers, false, \ - "Use 32-bit klass pointers in 64-bit VM " \ + lp64_product(bool, UseCompressedClassPointers, false, \ + "Use 32-bit class pointers in 64-bit VM " \ "lp64_product means flag is always constant in 32 bit VM") \ \ notproduct(bool, CheckCompressedOops, true, \ @@ -3039,9 +3039,9 @@ class CommandLineFlags { product(uintx, MaxMetaspaceSize, max_uintx, \ "Maximum size of Metaspaces (in bytes)") \ \ - product(uintx, ClassMetaspaceSize, 1*G, \ - "Maximum size of InstanceKlass area in Metaspace used for " \ - "UseCompressedKlassPointers") \ + product(uintx, CompressedClassSpaceSize, 1*G, \ + "Maximum size of class area in Metaspace when compressed " \ + "class pointers are used") \ \ product(uintx, MinHeapFreeRatio, 40, \ "Min percentage of heap free after GC to avoid expansion") \ diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index 777b8b8f382..7a17f0bd138 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -280,7 +280,7 @@ size_t MetaspacePool::calculate_max_size() const { } CompressedKlassSpacePool::CompressedKlassSpacePool() : - MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), ClassMetaspaceSize, true, false) { } + MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), CompressedClassSpaceSize, true, false) { } size_t CompressedKlassSpacePool::used_in_bytes() { return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp index bf0fb9cad24..6508cd2086a 100644 --- a/hotspot/src/share/vm/services/memoryService.cpp +++ b/hotspot/src/share/vm/services/memoryService.cpp @@ -409,7 +409,7 @@ void MemoryService::add_metaspace_memory_pools() { mgr->add_pool(_metaspace_pool); _pools_list->append(_metaspace_pool); - if (UseCompressedKlassPointers) { + if (UseCompressedClassPointers) { _compressed_class_pool = new CompressedKlassSpacePool(); mgr->add_pool(_compressed_class_pool); _pools_list->append(_compressed_class_pool); diff --git a/hotspot/test/gc/arguments/TestCompressedClassFlags.java b/hotspot/test/gc/arguments/TestCompressedClassFlags.java new file mode 100644 index 00000000000..4135debd89c --- /dev/null +++ b/hotspot/test/gc/arguments/TestCompressedClassFlags.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.*; + +/* + * @test + * @bug 8015107 + * @summary Tests that VM prints a warning when -XX:CompressedClassSpaceSize + * is used together with -XX:-UseCompressedClassPointers + * @library /testlibrary + */ +public class TestCompressedClassFlags { + public static void main(String[] args) throws Exception { + if (Platform.is64bit()) { + OutputAnalyzer output = runJava("-XX:CompressedClassSpaceSize=1g", + "-XX:-UseCompressedClassPointers", + "-version"); + output.shouldContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + } + + private static OutputAnalyzer runJava(String ... args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); + return new OutputAnalyzer(pb.start()); + } +} diff --git a/hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java similarity index 83% rename from hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java rename to hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java index b3258466a2d..8152a9eb1ca 100644 --- a/hotspot/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java +++ b/hotspot/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java @@ -22,11 +22,11 @@ */ /* - * @test ClassMetaspaceSizeInJmapHeap + * @test CompressedClassSpaceSizeInJmapHeap * @bug 8004924 - * @summary Checks that jmap -heap contains the flag ClassMetaspaceSize + * @summary Checks that jmap -heap contains the flag CompressedClassSpaceSize * @library /testlibrary - * @run main/othervm -XX:ClassMetaspaceSize=50m ClassMetaspaceSizeInJmapHeap + * @run main/othervm -XX:CompressedClassSpaceSize=50m CompressedClassSpaceSizeInJmapHeap */ import com.oracle.java.testlibrary.*; @@ -35,7 +35,7 @@ import java.io.File; import java.nio.charset.Charset; import java.util.List; -public class ClassMetaspaceSizeInJmapHeap { +public class CompressedClassSpaceSizeInJmapHeap { public static void main(String[] args) throws Exception { String pid = Integer.toString(ProcessTools.getProcessId()); @@ -44,16 +44,16 @@ public class ClassMetaspaceSizeInJmapHeap { .addToolArg(pid); ProcessBuilder pb = new ProcessBuilder(jmap.getCommand()); - File out = new File("ClassMetaspaceSizeInJmapHeap.stdout.txt"); + File out = new File("CompressedClassSpaceSizeInJmapHeap.stdout.txt"); pb.redirectOutput(out); - File err = new File("ClassMetaspaceSizeInJmapHeap.stderr.txt"); + File err = new File("CompressedClassSpaceSizeInJmapHeap.stderr.txt"); pb.redirectError(err); run(pb); OutputAnalyzer output = new OutputAnalyzer(read(out)); - output.shouldContain("ClassMetaspaceSize = 52428800 (50.0MB)"); + output.shouldContain("CompressedClassSpaceSize = 52428800 (50.0MB)"); out.delete(); } diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java index 440f91cbd85..105ba240ddf 100644 --- a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java +++ b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java @@ -36,8 +36,8 @@ import java.lang.management.ManagementFactory; * MemoryManagerMXBean is created. * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops TestMetaspaceMemoryPool * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPool - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers TestMetaspaceMemoryPool - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:ClassMetaspaceSize=60m TestMetaspaceMemoryPool + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers TestMetaspaceMemoryPool + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:CompressedClassSpaceSize=60m TestMetaspaceMemoryPool */ public class TestMetaspaceMemoryPool { public static void main(String[] args) { diff --git a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java index 26934249a7c..9672d90a5d0 100644 --- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java +++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java @@ -33,13 +33,13 @@ import static com.oracle.java.testlibrary.Asserts.*; * @summary Tests that performance counters for metaspace and compressed class * space exists and works. * - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters * - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters */ public class TestMetaspacePerfCounters { public static Class fooClass = null; @@ -99,6 +99,6 @@ public class TestMetaspacePerfCounters { } private static boolean isUsingCompressedClassPointers() { - return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedKlassPointers"); + return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers"); } } diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java index 4ce2e82c771..c32c05ebd27 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrs.java @@ -24,7 +24,7 @@ /* * @test * @bug 8003424 - * @summary Testing UseCompressedKlassPointers with CDS + * @summary Testing UseCompressedClassPointers with CDS * @library /testlibrary * @run main CDSCompressedKPtrs */ @@ -36,7 +36,7 @@ public class CDSCompressedKPtrs { ProcessBuilder pb; if (Platform.is64bit()) { pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops", + "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { @@ -44,7 +44,7 @@ public class CDSCompressedKPtrs { output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", "-XX:+UseCompressedOops", + "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("sharing"); diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java index b2cb84ac988..05b4ac9af28 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/CDSCompressedKPtrsError.java @@ -24,7 +24,7 @@ /* * @test * @bug 8003424 - * @summary Test that cannot use CDS if UseCompressedKlassPointers is turned off. + * @summary Test that cannot use CDS if UseCompressedClassPointers is turned off. * @library /testlibrary * @run main CDSCompressedKPtrsError */ @@ -36,7 +36,7 @@ public class CDSCompressedKPtrsError { ProcessBuilder pb; if (Platform.is64bit()) { pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); try { @@ -44,21 +44,21 @@ public class CDSCompressedKPtrsError { output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedKlassPointers", "-XX:-UseCompressedOops", + "-XX:-UseCompressedClassPointers", "-XX:-UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Unable to use shared archive"); output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedKlassPointers", "-XX:+UseCompressedOops", + "-XX:-UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Unable to use shared archive"); output.shouldHaveExitValue(0); pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", "-XX:-UseCompressedOops", + "-XX:+UseCompressedClassPointers", "-XX:-UseCompressedOops", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Unable to use shared archive"); @@ -71,19 +71,19 @@ public class CDSCompressedKPtrsError { // Test bad options with -Xshare:dump. pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedOops", "-XX:+UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:-UseCompressedOops", "-XX:+UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Cannot dump shared archive"); pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Cannot dump shared archive"); pb = ProcessTools.createJavaProcessBuilder( - "-XX:-UseCompressedOops", "-XX:-UseCompressedKlassPointers", "-XX:+UnlockDiagnosticVMOptions", + "-XX:-UseCompressedOops", "-XX:-UseCompressedClassPointers", "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); output = new OutputAnalyzer(pb.start()); output.shouldContain("Cannot dump shared archive"); diff --git a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java index dd0c26d9f10..228d8cb6a7a 100644 --- a/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java +++ b/hotspot/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java @@ -25,7 +25,7 @@ * @test * @bug 8000968 * @key regression - * @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32 + * @summary NPG: UseCompressedClassPointers asserts with ObjectAlignmentInBytes=32 * @library /testlibrary */ @@ -52,7 +52,7 @@ public class CompressedKlassPointerAndOops { OutputAnalyzer output; pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UseCompressedKlassPointers", + "-XX:+UseCompressedClassPointers", "-XX:+UseCompressedOops", "-XX:ObjectAlignmentInBytes=" + alignment, "-version"); From 4d086fe704c9c08b2fb68c7c7d97a17e6f9548cd Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Thu, 26 Sep 2013 18:20:25 -0700 Subject: [PATCH 002/293] 8019192: StringIndexOutOfBoundsException: in Class.getSimpleName() Reviewed-by: jrose --- .../classes/java/lang/invoke/MemberName.java | 113 +++++++++++------- 1 file changed, 73 insertions(+), 40 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java index 910574befe7..05d291c25a1 100644 --- a/jdk/src/share/classes/java/lang/invoke/MemberName.java +++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java @@ -70,13 +70,13 @@ import java.util.Objects; * @author jrose */ /*non-public*/ final class MemberName implements Member, Cloneable { - private Class clazz; // class in which the method is defined - private String name; // may be null if not yet materialized - private Object type; // may be null if not yet materialized - private int flags; // modifier bits; see reflect.Modifier + private Class clazz; // class in which the method is defined + private String name; // may be null if not yet materialized + private Object type; // may be null if not yet materialized + private int flags; // modifier bits; see reflect.Modifier //@Injected JVM_Method* vmtarget; //@Injected int vmindex; - private Object resolution; // if null, this guy is resolved + private Object resolution; // if null, this guy is resolved /** Return the declaring class of this member. * In the case of a bare name and type, the declaring class will be null. @@ -98,7 +98,9 @@ import java.util.Objects; public String getName() { if (name == null) { expandFromVM(); - if (name == null) return null; + if (name == null) { + return null; + } } return name; } @@ -119,28 +121,39 @@ import java.util.Objects; public MethodType getMethodType() { if (type == null) { expandFromVM(); - if (type == null) return null; + if (type == null) { + return null; + } } - if (!isInvocable()) + if (!isInvocable()) { throw newIllegalArgumentException("not invocable, no method type"); - if (type instanceof MethodType) { - return (MethodType) type; } - if (type instanceof String) { - String sig = (String) type; - MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); - this.type = res; - return res; + + { + // Get a snapshot of type which doesn't get changed by racing threads. + final Object type = this.type; + if (type instanceof MethodType) { + return (MethodType) type; + } } - if (type instanceof Object[]) { - Object[] typeInfo = (Object[]) type; - Class[] ptypes = (Class[]) typeInfo[1]; - Class rtype = (Class) typeInfo[0]; - MethodType res = MethodType.methodType(rtype, ptypes); - this.type = res; - return res; + + // type is not a MethodType yet. Convert it thread-safely. + synchronized (this) { + if (type instanceof String) { + String sig = (String) type; + MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); + type = res; + } else if (type instanceof Object[]) { + Object[] typeInfo = (Object[]) type; + Class[] ptypes = (Class[]) typeInfo[1]; + Class rtype = (Class) typeInfo[0]; + MethodType res = MethodType.methodType(rtype, ptypes); + type = res; + } + // Make sure type is a MethodType for racing threads. + assert type instanceof MethodType : "bad method type " + type; } - throw new InternalError("bad method type "+type); + return (MethodType) type; } /** Return the actual type under which this method or constructor must be invoked. @@ -173,21 +186,34 @@ import java.util.Objects; public Class getFieldType() { if (type == null) { expandFromVM(); - if (type == null) return null; + if (type == null) { + return null; + } } - if (isInvocable()) + if (isInvocable()) { throw newIllegalArgumentException("not a field or nested class, no simple type"); - if (type instanceof Class) { - return (Class) type; } - if (type instanceof String) { - String sig = (String) type; - MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader()); - Class res = mtype.returnType(); - this.type = res; - return res; + + { + // Get a snapshot of type which doesn't get changed by racing threads. + final Object type = this.type; + if (type instanceof Class) { + return (Class) type; + } } - throw new InternalError("bad field type "+type); + + // type is not a Class yet. Convert it thread-safely. + synchronized (this) { + if (type instanceof String) { + String sig = (String) type; + MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader()); + Class res = mtype.returnType(); + type = res; + } + // Make sure type is a Class for racing threads. + assert type instanceof Class : "bad field type " + type; + } + return (Class) type; } /** Utility method to produce either the method type or field type of this member. */ @@ -201,10 +227,10 @@ import java.util.Objects; public String getSignature() { if (type == null) { expandFromVM(); - if (type == null) return null; + if (type == null) { + return null; + } } - if (type instanceof String) - return (String) type; if (isInvocable()) return BytecodeDescriptor.unparse(getMethodType()); else @@ -463,10 +489,17 @@ import java.util.Objects; //assert(referenceKindIsConsistent()); // do this after resolution } + /** + * Calls down to the VM to fill in the fields. This method is + * synchronized to avoid racing calls. + */ private void expandFromVM() { - if (!isResolved()) return; - if (type instanceof Object[]) - type = null; // don't saddle JVM w/ typeInfo + if (type != null) { + return; + } + if (!isResolved()) { + return; + } MethodHandleNatives.expand(this); } From b16be80c6b1ad278c716bbe366e53440b8b1a77e Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 27 Sep 2013 15:25:18 +0800 Subject: [PATCH 003/293] 8024861: Incomplete token triggers GSS-API NullPointerException Reviewed-by: mullan --- .../security/jgss/spnego/SpNegoContext.java | 4 ++ .../jgss/spnego/MechTokenMissing.java | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 jdk/test/sun/security/jgss/spnego/MechTokenMissing.java diff --git a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java index d6bc6d92e6e..808acb2efde 100644 --- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java +++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java @@ -525,6 +525,10 @@ public class SpNegoContext implements GSSContextSpi { // get the mechanism token byte[] mechToken = initToken.getMechToken(); + if (mechToken == null) { + throw new GSSException(GSSException.FAILURE, -1, + "mechToken is missing"); + } /* * Select the best match between the list of mechs diff --git a/jdk/test/sun/security/jgss/spnego/MechTokenMissing.java b/jdk/test/sun/security/jgss/spnego/MechTokenMissing.java new file mode 100644 index 00000000000..98ded50fed3 --- /dev/null +++ b/jdk/test/sun/security/jgss/spnego/MechTokenMissing.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024861 + * @summary Incomplete token triggers GSS-API NullPointerException + */ + +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; + +public class MechTokenMissing { + public static void main(String[] args) throws Exception { + GSSCredential cred = null; + GSSContext ctx = GSSManager.getInstance().createContext(cred); + + String var = + /*0000*/ "60 1C 06 06 2B 06 01 05 05 02 A0 12 30 10 A0 0E " + + /*0010*/ "30 0C 06 0A 2B 06 01 04 01 82 37 02 02 0A "; + byte[] token = new byte[var.length()/3]; + for (int i=0; i Date: Thu, 26 Sep 2013 16:23:45 +0200 Subject: [PATCH 004/293] 8025502: Exclude tests due to JDK-8025427 Reviewed-by: ksrini --- jdk/test/ProblemList.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 90ac26d0f69..984d431ef35 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -322,6 +322,18 @@ tools/pack200/Pack200Test.java solaris-all, mac # 8007410 tools/launcher/FXLauncherTest.java linux-all +# 8025427 +sun/tools/jstat/jstatLineCounts1.sh generic-all +sun/tools/jstat/jstatLineCounts2.sh generic-all +sun/tools/jstat/jstatLineCounts3.sh generic-all +sun/tools/jstat/jstatTimeStamp1.sh generic-all +sun/tools/jstat/jstatGcCauseOutput1.sh generic-all +sun/tools/jstat/jstatLineCounts4.sh generic-all +sun/tools/jstatd/jstatdDefaults.sh generic-all +sun/tools/jstatd/jstatdExternalRegistry.sh generic-all +sun/tools/jstatd/jstatdPort.sh generic-all +sun/tools/jstatd/jstatdServerName.sh generic-all + ############################################################################ # jdk_jdi From e68f7e9564b39f911cdece317fed65a8021a2f1f Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Fri, 27 Sep 2013 10:21:04 -0700 Subject: [PATCH 005/293] 8025595: Remove alt-rt.jar, used by +AggressiveOps (jdk repo portion of JDK-8024826) Reviewed-by: alanb, chegar, dholmes, ksrini --- jdk/makefiles/CompileJavaClasses.gmk | 19 ++----------- jdk/makefiles/CreateJars.gmk | 9 ------ jdk/makefiles/Profiles.gmk | 40 ++++++++++++--------------- jdk/makefiles/profile-includes.txt | 12 ++++---- jdk/test/java/util/TreeMap/Clone.java | 1 - 5 files changed, 26 insertions(+), 55 deletions(-) diff --git a/jdk/makefiles/CompileJavaClasses.gmk b/jdk/makefiles/CompileJavaClasses.gmk index 0b3e70dd914..36aaa0861a1 100644 --- a/jdk/makefiles/CompileJavaClasses.gmk +++ b/jdk/makefiles/CompileJavaClasses.gmk @@ -236,10 +236,10 @@ endif # These files do not appear in the build result of the old build. This # is because they are generated sources, but the AUTO_JAVA_FILES won't -# pick them up since they aren't generated when the source dirs are +# pick them up since they aren't generated when the source dirs are # searched and they aren't referenced by any other classes so they won't # be picked up by implicit compilation. On a rebuild, they are picked up -# and compiled. Exclude them here to produce the same rt.jar as the old +# and compiled. Exclude them here to produce the same rt.jar as the old # build does when building just once. EXFILES+=javax/swing/plaf/nimbus/InternalFrameTitlePanePainter.java \ javax/swing/plaf/nimbus/OptionPaneMessageAreaPainter.java \ @@ -307,19 +307,6 @@ $(eval $(call SetupJavaCompilation,BUILD_JDK,\ ########################################################################################## -ifndef OPENJDK - - $(eval $(call SetupJavaCompilation,BUILD_ALTCLASSES,\ - SETUP:=GENERATE_JDKBYTECODE,\ - SRC:=$(JDK_TOPDIR)/src/closed/share/altclasses, \ - BIN:=$(JDK_OUTPUTDIR)/altclasses_classes)) - - $(BUILD_ALTCLASSES): $(BUILD_JDK) - -endif - -########################################################################################## - $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin: $(MKDIR) -p $(@D) $(TOUCH) $@ @@ -402,7 +389,7 @@ endif ########################################################################################## -all: $(BUILD_JDK) $(BUILD_ALTCLASSES) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \ +all: $(BUILD_JDK) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \ $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin \ $(BUILD_ACCESSBRIDGE_32) $(BUILD_ACCESSBRIDGE_64) \ $(BUILD_ACCESSBRIDGE_LEGACY) diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index e1d0a5d311b..7ef97646f9e 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -1004,15 +1004,6 @@ endif ########################################################################################## -ifndef OPENJDK - $(eval $(call SetupArchive,BUILD_ALT_RT_JAR,,\ - SRCS:=$(JDK_OUTPUTDIR)/altclasses_classes,\ - JAR:=$(IMAGES_OUTPUTDIR)/lib/alt-rt.jar)) - -endif - -########################################################################################## - # This file is imported from hotspot in Import.gmk. Copying it into images/lib so that # all jars can be found in one place when creating images in Images.gmk. It needs to be # done here so that clean targets can be simple and accurate. diff --git a/jdk/makefiles/Profiles.gmk b/jdk/makefiles/Profiles.gmk index 9e79b2b27ac..41a9b1f0197 100644 --- a/jdk/makefiles/Profiles.gmk +++ b/jdk/makefiles/Profiles.gmk @@ -40,8 +40,8 @@ include profile-includes.txt # imported (signed jars) rather than built. # # The incoming lists, eg PROFILE_1_JRE_JARS_FILES, are the jars to be -# included in this profile. They have the jar name relative to the lib -# directory. We have to turn these into targets by adding the +# included in this profile. They have the jar name relative to the lib +# directory. We have to turn these into targets by adding the # $(IMAGES_OUTPUTDIR)/lib prefix # # Note that some jars may be optional depending on the type of build (jdk vs. @@ -69,10 +69,6 @@ PROFILE_3_JARS := \ $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \ $(PROFILE_2_JARS) -ifdef OPENJDK - FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES)) -endif - ifneq ($(ENABLE_JFR), true) FULL_JRE_JAR_FILES := $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES)) endif @@ -107,7 +103,7 @@ endif ifeq ($(OPENJDK_TARGET_OS),windows) ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar -endif +endif ifeq ($(OPENJDK_TARGET_OS),macosx) ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar @@ -142,7 +138,7 @@ ALL_JRE_BIN_FILES := \ $(PROFILE_1_JRE_BIN_FILES) \ $(PROFILE_2_JRE_BIN_FILES) \ $(PROFILE_3_JRE_BIN_FILES) \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) NOT_JRE_BIN_FILES := $(filter-out $(ALL_JRE_BIN_FILES), $(NEW_ALL_BIN_LIST)) @@ -151,18 +147,18 @@ ifeq ($(PROFILE), profile_1) NOT_JRE_BIN_FILES += \ $(PROFILE_2_JRE_BIN_FILES) \ $(PROFILE_3_JRE_BIN_FILES) \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif ifeq ($(PROFILE), profile_2) NOT_JRE_BIN_FILES += \ $(PROFILE_3_JRE_BIN_FILES) \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif ifeq ($(PROFILE), profile_3) NOT_JRE_BIN_FILES += \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif NOT_JRE_BIN_FILES := $(addprefix $(JDK_OUTPUTDIR)/bin/, $(NOT_JRE_BIN_FILES)) @@ -175,7 +171,7 @@ ALL_JRE_LIB_FILES := \ $(PROFILE_1_JRE_LIB_FILES) \ $(PROFILE_2_JRE_LIB_FILES) \ $(PROFILE_3_JRE_LIB_FILES) \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) NOT_JRE_LIB_FILES := $(filter-out $(ALL_JRE_LIB_FILES), $(NEW_ALL_LIB_LIST)) @@ -191,18 +187,18 @@ ifeq ($(PROFILE), profile_1) NOT_JRE_LIB_FILES += \ $(PROFILE_2_JRE_LIB_FILES) \ $(PROFILE_3_JRE_LIB_FILES) \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif ifeq ($(PROFILE), profile_2) NOT_JRE_LIB_FILES += \ $(PROFILE_3_JRE_LIB_FILES) \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif ifeq ($(PROFILE), profile_3) NOT_JRE_LIB_FILES += \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif # Exclude the custom jar files as these will be added back via a special rule @@ -210,7 +206,7 @@ NOT_JRE_LIB_FILES += $(CUSTOM_JARS) ############################################################################### # Customization of rt.jar file contents -# These are expressed as exclusions from everything found in the +# These are expressed as exclusions from everything found in the # JDK_OUTPUTDIR/classes directory ############################################################################### @@ -231,8 +227,8 @@ NOT_JRE_LIB_FILES += $(CUSTOM_JARS) # # These are specific types that must be included within a package. # There are two cases: -# - individual types in a package that is otherwise excluded at this -# profile level. The only arises if there are split packages. +# - individual types in a package that is otherwise excluded at this +# profile level. The only arises if there are split packages. # # - A higher-level package is included in a high profile where a subpackage # is included in a lower profile. Including the package in the high profile @@ -247,7 +243,7 @@ NOT_JRE_LIB_FILES += $(CUSTOM_JARS) # containing package is include. Again this occurs with split packges. # # So the exclude list for each profile consists of the include lists -# for all profiles above it, together with any explicitly excluded types. +# for all profiles above it, together with any explicitly excluded types. # This is then combined with the overall RT_JAR_EXCLUDES list (which covers # things that go into other jar files). # @@ -257,7 +253,7 @@ NOT_JRE_LIB_FILES += $(CUSTOM_JARS) # profile 3 includes the entire package, but it is harmless to add them # explicitly, and complex to determine if we still need to include them. # -# Need a way to express: +# Need a way to express: # for (int i = profile+1; i < 4; i++) # RT_JAR_EXCLUDES += PROFILE_$i_RTJAR_INCLUDE_PACKAGES # @@ -267,7 +263,7 @@ NOT_JRE_LIB_FILES += $(CUSTOM_JARS) # # These are META-INF/services/ entries found in resources.jar. Together # resources.jar and rt.jar hold the contents of the classes directory, (the -# classes in rt.jar and everything else in resources.jar).Hence the +# classes in rt.jar and everything else in resources.jar).Hence the # include/exclude information for resources.jar is tied to that of rt.jar include profile-rtjar-includes.txt @@ -324,7 +320,7 @@ endif # Filter out non-OpenJDK services ifdef OPENJDK - EXCLUDED_SERVICES := META-INF/services/javax.script.ScriptEngineFactory + EXCLUDED_SERVICES := META-INF/services/javax.script.ScriptEngineFactory PROFILE_INCLUDE_METAINF_SERVICES := $(filter-out $(EXCLUDED_SERVICES),$(PROFILE_INCLUDE_METAINF_SERVICES)) endif diff --git a/jdk/makefiles/profile-includes.txt b/jdk/makefiles/profile-includes.txt index fe2f13e2be8..ab2292bad0e 100644 --- a/jdk/makefiles/profile-includes.txt +++ b/jdk/makefiles/profile-includes.txt @@ -107,14 +107,14 @@ PROFILE_2_JRE_BIN_FILES := \ rmid$(EXE_SUFFIX) \ rmiregistry$(EXE_SUFFIX) -PROFILE_2_JRE_LIB_FILES := +PROFILE_2_JRE_LIB_FILES := -PROFILE_2_JRE_OTHER_FILES := +PROFILE_2_JRE_OTHER_FILES := -PROFILE_2_JRE_JAR_FILES := +PROFILE_2_JRE_JAR_FILES := -PROFILE_3_JRE_BIN_FILES := +PROFILE_3_JRE_BIN_FILES := PROFILE_3_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)hprof$(SHARED_LIBRARY_SUFFIX) \ @@ -138,7 +138,7 @@ PROFILE_3_JRE_LIB_FILES := \ management/management.properties \ management/snmp.acl.template -PROFILE_3_JRE_OTHER_FILES := +PROFILE_3_JRE_OTHER_FILES := PROFILE_3_JRE_JAR_FILES := \ management-agent.jar @@ -171,7 +171,6 @@ FULL_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)splashscreen$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \ - alt-rt.jar \ charsets.jar \ cmm/CIEXYZ.pf \ cmm/GRAY.pf \ @@ -248,7 +247,6 @@ FULL_JRE_OTHER_FILES := \ man/man1/unpack200.1 FULL_JRE_JAR_FILES := \ - alt-rt.jar \ charsets.jar \ ext/cldrdata.jar \ ext/dnsns.jar \ diff --git a/jdk/test/java/util/TreeMap/Clone.java b/jdk/test/java/util/TreeMap/Clone.java index efffa6a9633..aed33ded2eb 100644 --- a/jdk/test/java/util/TreeMap/Clone.java +++ b/jdk/test/java/util/TreeMap/Clone.java @@ -27,7 +27,6 @@ * @summary Verify that cloned TreeMap gets new keyset * @author david.buck@oracle.com * @run main/othervm Clone - * @run main/othervm -XX:+AggressiveOpts Clone */ import java.util.TreeMap; From ea739968d2403d70ddef51f8943ecfac0f98da1c Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Fri, 27 Sep 2013 13:30:31 -0700 Subject: [PATCH 006/293] 8023339: Refined Collection.removeIf UOE conditions Reviewed-by: mduigou --- jdk/src/share/classes/java/util/Collection.java | 11 ++++++----- jdk/test/java/util/Collection/MOAT.java | 12 ++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/jdk/src/share/classes/java/util/Collection.java b/jdk/src/share/classes/java/util/Collection.java index dba273e6885..8e8fd5a76dc 100644 --- a/jdk/src/share/classes/java/util/Collection.java +++ b/jdk/src/share/classes/java/util/Collection.java @@ -379,8 +379,8 @@ public interface Collection extends Iterable { /** * Removes all of the elements of this collection that satisfy the given - * predicate. Errors or runtime exceptions thrown by the predicate are - * relayed to the caller. + * predicate. Errors or runtime exceptions thrown during iteration or by + * the predicate are relayed to the caller. * * @implSpec * The default implementation traverses all elements of the collection using @@ -393,9 +393,10 @@ public interface Collection extends Iterable { * removed * @return {@code true} if any elements were removed * @throws NullPointerException if the specified filter is null - * @throws UnsupportedOperationException if the {@code remove} - * method is not supported by this collection's - * {@link #iterator} + * @throws UnsupportedOperationException if elements cannot be removed + * from this collection. Implementations may throw this exception if a + * matching element cannot be removed or if, in general, removal is not + * supported. * @since 1.8 */ default boolean removeIf(Predicate filter) { diff --git a/jdk/test/java/util/Collection/MOAT.java b/jdk/test/java/util/Collection/MOAT.java index a039461e2b7..945335a7fe3 100644 --- a/jdk/test/java/util/Collection/MOAT.java +++ b/jdk/test/java/util/Collection/MOAT.java @@ -207,8 +207,8 @@ public class MOAT { new Fun(){void f(){ it.next(); }}); try { it.remove(); } - catch (IllegalStateException _) { pass(); } - catch (UnsupportedOperationException _) { pass(); } + catch (IllegalStateException ignored) { pass(); } + catch (UnsupportedOperationException ignored) { pass(); } catch (Throwable t) { unexpected(t); } if (rnd.nextBoolean()) @@ -280,9 +280,9 @@ public class MOAT { testEmptyCollection(m.values()); try { check(! m.containsValue(null)); } - catch (NullPointerException _) { /* OK */ } + catch (NullPointerException ignored) { /* OK */ } try { check(! m.containsKey(null)); } - catch (NullPointerException _) { /* OK */ } + catch (NullPointerException ignored) { /* OK */ } check(! m.containsValue(1)); check(! m.containsKey(1)); } @@ -710,8 +710,8 @@ public class MOAT { l.addAll(-1, Collections.emptyList()); fail("Expected IndexOutOfBoundsException not thrown"); } - catch (UnsupportedOperationException _) {/* OK */} - catch (IndexOutOfBoundsException _) {/* OK */} + catch (UnsupportedOperationException ignored) {/* OK */} + catch (IndexOutOfBoundsException ignored) {/* OK */} catch (Throwable t) { unexpected(t); } // equal(l instanceof Serializable, From 114ccbddf83689d9a792402f53fdacd7f3f28613 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Fri, 27 Sep 2013 13:30:35 -0700 Subject: [PATCH 007/293] 8023340: Clarify that unmodifiable List.replaceAll() may not throw UOE if there are no items to be replaced Reviewed-by: psandoz, jjg --- jdk/src/share/classes/java/util/List.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/util/List.java b/jdk/src/share/classes/java/util/List.java index 65ad1404c38..42a1acf22c5 100644 --- a/jdk/src/share/classes/java/util/List.java +++ b/jdk/src/share/classes/java/util/List.java @@ -396,11 +396,13 @@ public interface List extends Collection { * replacing the first element. * * @param operator the operator to apply to each element - * @throws UnsupportedOperationException if the {@code set} - * operation is not supported by this list + * @throws UnsupportedOperationException if this list is unmodifiable. + * Implementations may throw this exception if an element + * cannot be replaced or if, in general, modification is not + * supported * @throws NullPointerException if the specified operator is null or - * if the element is replaced with a null value and this list - * does not permit null elements + * if the operator result is a null value and this list does + * not permit null elements * (optional) * @since 1.8 */ @@ -685,4 +687,3 @@ public interface List extends Collection { return Spliterators.spliterator(this, Spliterator.ORDERED); } } - From 512fbc2a590f8504c6cd249f04bc98eb13b8e2e8 Mon Sep 17 00:00:00 2001 From: Dan Xu Date: Fri, 27 Sep 2013 17:09:25 -0700 Subject: [PATCH 008/293] 8025128: File.createTempFile fails if prefix is absolute path Use only the file name from the supplied prefix for backward compatibility Reviewed-by: alanb, chegar --- jdk/src/share/classes/java/io/File.java | 12 +++- .../File/createTempFile/SpecialTempFile.java | 65 ++++++++++++------- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/jdk/src/share/classes/java/io/File.java b/jdk/src/share/classes/java/io/File.java index f11530d2f67..bafcea5a839 100644 --- a/jdk/src/share/classes/java/io/File.java +++ b/jdk/src/share/classes/java/io/File.java @@ -1908,10 +1908,18 @@ public class File } else { n = Math.abs(n); } + + // Use only the file name from the supplied prefix + prefix = (new File(prefix)).getName(); + String name = prefix + Long.toString(n) + suffix; File f = new File(dir, name); - if (!name.equals(f.getName()) || f.isInvalid()) - throw new IOException("Unable to create temporary file"); + if (!name.equals(f.getName()) || f.isInvalid()) { + if (System.getSecurityManager() != null) + throw new IOException("Unable to create temporary file"); + else + throw new IOException("Unable to create temporary file, " + f); + } return f; } } diff --git a/jdk/test/java/io/File/createTempFile/SpecialTempFile.java b/jdk/test/java/io/File/createTempFile/SpecialTempFile.java index 9a4cc01c5ff..8bb8d934d36 100644 --- a/jdk/test/java/io/File/createTempFile/SpecialTempFile.java +++ b/jdk/test/java/io/File/createTempFile/SpecialTempFile.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8013827 8011950 8017212 + * @bug 8013827 8011950 8017212 8025128 * @summary Check whether File.createTempFile can handle special parameters * @author Dan Xu */ @@ -33,7 +33,9 @@ import java.io.IOException; public class SpecialTempFile { - private static void test(String name, String[] prefix, String[] suffix) { + private static void test(String name, String[] prefix, String[] suffix, + boolean exceptionExpected) throws IOException + { if (prefix == null || suffix == null || prefix.length != suffix.length) { @@ -41,24 +43,38 @@ public class SpecialTempFile { } final String exceptionMsg = "Unable to create temporary file"; - final String errMsg = "IOException is expected"; + String[] dirs = { null, "." }; for (int i = 0; i < prefix.length; i++) { boolean exceptionThrown = false; File f = null; - System.out.println("In test " + name - + ", creating temp file with prefix, " - + prefix[i] + ", suffix, " + suffix[i]); - try { - f = File.createTempFile(prefix[i], suffix[i]); - } catch (IOException e) { - if (exceptionMsg.equals(e.getMessage())) - exceptionThrown = true; - else - System.out.println("Wrong error message:" + e.getMessage()); + + for (String dir: dirs) { + System.out.println("In test " + name + + ", creating temp file with prefix, " + + prefix[i] + ", suffix, " + suffix[i] + + ", in dir, " + dir); + + try { + if (dir == null || dir.isEmpty()) + f = File.createTempFile(prefix[i], suffix[i]); + else + f = File.createTempFile(prefix[i], suffix[i], new File(dir)); + } catch (IOException e) { + if (exceptionExpected) { + if (e.getMessage().startsWith(exceptionMsg)) + exceptionThrown = true; + else + System.out.println("Wrong error message:" + + e.getMessage()); + } else { + throw e; + } + } + + if (exceptionExpected && (!exceptionThrown || f != null)) + throw new RuntimeException("IOException is expected"); } - if (!exceptionThrown || f != null) - throw new RuntimeException(errMsg); } } @@ -71,7 +87,17 @@ public class SpecialTempFile { } String[] nulPre = { name + "\u0000" }; String[] nulSuf = { ".test" }; - test("NulName", nulPre, nulSuf); + test("NulName", nulPre, nulSuf, true); + + // Test JDK-8025128 + String[] goodPre = { "///..///", "/foo" }; + String[] goodSuf = { ".temp", ".tmp" }; + test("goodName", goodPre, goodSuf, false); + + // Test JDK-8011950 + String[] slashPre = { "temp", "///..///", "/foo" }; + String[] slashSuf = { "///..///..", "///..///..", "///..///.." }; + test("SlashedName", slashPre, slashSuf, true); // Windows tests if (!System.getProperty("os.name").startsWith("Windows")) @@ -80,11 +106,6 @@ public class SpecialTempFile { // Test JDK-8013827 String[] resvPre = { "LPT1.package.zip", "com7.4.package.zip" }; String[] resvSuf = { ".temp", ".temp" }; - test("ReservedName", resvPre, resvSuf); - - // Test JDK-8011950 - String[] slashPre = { "///..///", "temp", "///..///" }; - String[] slashSuf = { ".temp", "///..///..", "///..///.." }; - test("SlashedName", slashPre, slashSuf); + test("ReservedName", resvPre, resvSuf, true); } } From 230478592dea53568059566bbd86084f792a2e2e Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Fri, 27 Sep 2013 17:27:15 -0700 Subject: [PATCH 009/293] 8025610: Add explicit @throws NPE documentation to Optional constructor and Optional.of Reviewed-by: briangoetz, chegar, alanb --- jdk/src/share/classes/java/util/Optional.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jdk/src/share/classes/java/util/Optional.java b/jdk/src/share/classes/java/util/Optional.java index ce2a33d1de6..10b79234b18 100644 --- a/jdk/src/share/classes/java/util/Optional.java +++ b/jdk/src/share/classes/java/util/Optional.java @@ -85,6 +85,7 @@ public final class Optional { * Constructs an instance with the value present. * * @param value the non-null value to be present + * @throws NullPointerException if value is null */ private Optional(T value) { this.value = Objects.requireNonNull(value); @@ -96,6 +97,7 @@ public final class Optional { * @param the class of the value * @param value the value to be present, which must be non-null * @return an {@code Optional} with the value present + * @throws NullPointerException if value is null */ public static Optional of(T value) { return new Optional<>(value); From 279576cf17b309da245f2f32a1b59944bc774695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Mon, 30 Sep 2013 11:18:18 +0200 Subject: [PATCH 010/293] 8007072: Update Core Reflection for Type Annotations to match latest spec 8022324: j.l.Class.getAnnotatedInterfaces() for array type returns wrong value 8024915: j.l.r.Executable.getAnnotatedReceiverType() should return null for static methods Update javadoc and implementation of reflection for type annotations to match latest spec Reviewed-by: darcy --- jdk/src/share/classes/java/lang/Class.java | 61 ++++++++------ .../java/lang/reflect/AnnotatedArrayType.java | 9 +- .../reflect/AnnotatedParameterizedType.java | 9 +- .../java/lang/reflect/AnnotatedType.java | 8 +- .../lang/reflect/AnnotatedTypeVariable.java | 10 +-- .../lang/reflect/AnnotatedWildcardType.java | 13 +-- .../classes/java/lang/reflect/Executable.java | 57 +++++++------ .../annotation/AnnotatedTypeFactory.java | 1 + .../annotation/TypeAnnotationParser.java | 5 ++ .../GetAnnotatedInterfaces.java | 80 ++++++++++++++++++ .../GetAnnotatedReceiverType.java | 83 +++++++++++++++++++ .../GetAnnotatedSuperclass.java | 56 +++++++++++-- 12 files changed, 311 insertions(+), 81 deletions(-) create mode 100644 jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedInterfaces.java create mode 100644 jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index a09aa2c86a4..6d1aa009755 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -3414,16 +3414,20 @@ public final class Class implements java.io.Serializable, transient ClassValue.ClassValueMap classValueMap; /** - * Returns an AnnotatedType object that represents the use of a type to specify - * the superclass of the entity represented by this Class. (The use of type - * Foo to specify the superclass in '... extends Foo' is distinct from the - * declaration of type Foo.) + * Returns an {@code AnnotatedType} object that represents the use of a + * type to specify the superclass of the entity represented by this {@code + * Class} object. (The use of type Foo to specify the superclass + * in '... extends Foo' is distinct from the declaration of type + * Foo.) * - * If this Class represents a class type whose declaration does not explicitly - * indicate an annotated superclass, the return value is null. + *

If this {@code Class} object represents a type whose declaration + * does not explicitly indicate an annotated superclass, then the return + * value is an {@code AnnotatedType} object representing an element with no + * annotations. * - * If this Class represents either the Object class, an interface type, an - * array type, a primitive type, or void, the return value is null. + *

If this {@code Class} represents either the {@code Object} class, an + * interface type, an array type, a primitive type, or void, the return + * value is {@code null}. * * @return an object representing the superclass * @since 1.8 @@ -3441,30 +3445,33 @@ public final class Class implements java.io.Serializable, } /** - * Returns an array of AnnotatedType objects that represent the use of types to - * specify superinterfaces of the entity represented by this Class. (The use - * of type Foo to specify a superinterface in '... implements Foo' is - * distinct from the declaration of type Foo.) + * Returns an array of {@code AnnotatedType} objects that represent the use + * of types to specify superinterfaces of the entity represented by this + * {@code Class} object. (The use of type Foo to specify a + * superinterface in '... implements Foo' is distinct from the + * declaration of type Foo.) * - * If this Class represents a class, the return value is an array - * containing objects representing the uses of interface types to specify - * interfaces implemented by the class. The order of the objects in the - * array corresponds to the order of the interface types used in the - * 'implements' clause of the declaration of this Class. - * - * If this Class represents an interface, the return value is an array - * containing objects representing the uses of interface types to specify - * interfaces directly extended by the interface. The order of the objects in + *

If this {@code Class} object represents a class, the return value is + * an array containing objects representing the uses of interface types to + * specify interfaces implemented by the class. The order of the objects in * the array corresponds to the order of the interface types used in the - * 'extends' clause of the declaration of this Class. + * 'implements' clause of the declaration of this {@code Class} object. * - * If this Class represents a class or interface whose declaration does not - * explicitly indicate any annotated superinterfaces, the return value is an + *

If this {@code Class} object represents an interface, the return + * value is an array containing objects representing the uses of interface + * types to specify interfaces directly extended by the interface. The + * order of the objects in the array corresponds to the order of the + * interface types used in the 'extends' clause of the declaration of this + * {@code Class} object. + * + *

If this {@code Class} object represents a class or interface whose + * declaration does not explicitly indicate any annotated superinterfaces, + * the return value is an array of length 0. + * + *

If this {@code Class} object represents either the {@code Object} + * class, an array type, a primitive type, or void, the return value is an * array of length 0. * - * If this Class represents either the Object class, an array type, a - * primitive type, or void, the return value is an array of length 0. - * * @return an array representing the superinterfaces * @since 1.8 */ diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java index e84a3360fdd..f92b51d6ff6 100644 --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedArrayType.java @@ -27,17 +27,18 @@ package java.lang.reflect; /** - * AnnotatedArrayType represents the use of an array type, whose component - * type may itself represent the annotated use of a type. + * {@code AnnotatedArrayType} represents the potentially annotated use of an + * array type, whose component type may itself represent the annotated use of a + * type. * * @since 1.8 */ public interface AnnotatedArrayType extends AnnotatedType { /** - * Returns the annotated generic component type of this array type. + * Returns the potentially annotated generic component type of this array type. * - * @return the annotated generic component type of this array type + * @return the potentially annotated generic component type of this array type */ AnnotatedType getAnnotatedGenericComponentType(); } diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java index 4fa089e318c..f1d43c9528e 100644 --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java @@ -26,17 +26,18 @@ package java.lang.reflect; /** - * AnnotatedParameterizedType represents the use of a parameterized type, - * whose type arguments may themselves represent annotated uses of types. + * {@code AnnotatedParameterizedType} represents the potentially annotated use + * of a parameterized type, whose type arguments may themselves represent + * annotated uses of types. * * @since 1.8 */ public interface AnnotatedParameterizedType extends AnnotatedType { /** - * Returns the annotated actual type arguments of this parameterized type. + * Returns the potentially annotated actual type arguments of this parameterized type. * - * @return the annotated actual type arguments of this parameterized type + * @return the potentially annotated actual type arguments of this parameterized type */ AnnotatedType[] getAnnotatedActualTypeArguments(); } diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedType.java index d1ee79f14f4..12d0bfc17bb 100644 --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedType.java +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedType.java @@ -26,10 +26,10 @@ package java.lang.reflect; /** - * AnnotatedType represents the annotated use of a type in the program - * currently running in this VM. The use may be of any type in the Java - * programming language, including an array type, a parameterized type, a type - * variable, or a wildcard type. + * {@code AnnotatedType} represents the potentially annotated use of a type in + * the program currently running in this VM. The use may be of any type in the + * Java programming language, including an array type, a parameterized type, a + * type variable, or a wildcard type. * * @since 1.8 */ diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java index 3580a14442f..7a39bae492d 100644 --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java @@ -26,18 +26,18 @@ package java.lang.reflect; /** - * AnnotatedTypeVariable represents the use of a type variable, whose - * declaration may have bounds which themselves represent annotated uses of - * types. + * {@code AnnotatedTypeVariable} represents the potentially annotated use of a + * type variable, whose declaration may have bounds which themselves represent + * annotated uses of types. * * @since 1.8 */ public interface AnnotatedTypeVariable extends AnnotatedType { /** - * Returns the annotated bounds of this type variable. + * Returns the potentially annotated bounds of this type variable. * - * @return the annotated bounds of this type variable + * @return the potentially annotated bounds of this type variable */ AnnotatedType[] getAnnotatedBounds(); } diff --git a/jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java b/jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java index c357eb9d0bc..2d15f6c9770 100644 --- a/jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java +++ b/jdk/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java @@ -26,24 +26,25 @@ package java.lang.reflect; /** - * AnnotatedWildcardType represents the use of a wildcard type argument, whose - * upper or lower bounds may themselves represent annotated uses of types. + * {@code AnnotatedWildcardType} represents the potentially annotated use of a + * wildcard type argument, whose upper or lower bounds may themselves represent + * annotated uses of types. * * @since 1.8 */ public interface AnnotatedWildcardType extends AnnotatedType { /** - * Returns the annotated lower bounds of this wildcard type. + * Returns the potentially annotated lower bounds of this wildcard type. * - * @return the annotated lower bounds of this wildcard type + * @return the potentially annotated lower bounds of this wildcard type */ AnnotatedType[] getAnnotatedLowerBounds(); /** - * Returns the annotated upper bounds of this wildcard type. + * Returns the potentially annotated upper bounds of this wildcard type. * - * @return the annotated upper bounds of this wildcard type + * @return the potentially annotated upper bounds of this wildcard type */ AnnotatedType[] getAnnotatedUpperBounds(); } diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java index 9d41a0217db..af876c6f4f2 100644 --- a/jdk/src/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java @@ -514,18 +514,20 @@ public abstract class Executable extends AccessibleObject } /** - * Returns an AnnotatedType object that represents the use of a type to + * Returns an {@code AnnotatedType} object that represents the use of a type to * specify the return type of the method/constructor represented by this * Executable. * - * If this Executable represents a constructor, the AnnotatedType object - * represents the type of the constructed object. + * If this {@code Executable} object represents a constructor, the {@code + * AnnotatedType} object represents the type of the constructed object. * - * If this Executable represents a method, the AnnotatedType object - * represents the use of a type to specify the return type of the method. + * If this {@code Executable} object represents a method, the {@code + * AnnotatedType} object represents the use of a type to specify the return + * type of the method. + * + * @return an object representing the return type of the method + * or constructor represented by this {@code Executable} * - * @return an object representing the return type of this method - * or constructor * @since 1.8 */ public abstract AnnotatedType getAnnotatedReturnType(); @@ -549,24 +551,29 @@ public abstract class Executable extends AccessibleObject } /** - * Returns an AnnotatedType object that represents the use of a type to - * specify the receiver type of the method/constructor represented by this - * Executable. The receiver type of a method/constructor is available only - * if the method/constructor declares a formal parameter called 'this'. + * Returns an {@code AnnotatedType} object that represents the use of a + * type to specify the receiver type of the method/constructor represented + * by this Executable object. The receiver type of a method/constructor is + * available only if the method/constructor has a receiver + * parameter (JLS 8.4.1). * - * Returns null if this Executable represents a constructor or instance - * method that either declares no formal parameter called 'this', or - * declares a formal parameter called 'this' with no annotations on its - * type. + * If this {@code Executable} object represents a constructor or instance + * method that does not have a receiver parameter, or has a receiver + * parameter with no annotations on its type, then the return value is an + * {@code AnnotatedType} object representing an element with no + * annotations. * - * Returns null if this Executable represents a static method. + * If this {@code Executable} object represents a static method, then the + * return value is null. * - * @return an object representing the receiver type of the - * method or constructor represented by this Executable + * @return an object representing the receiver type of the method or + * constructor represented by this {@code Executable} * * @since 1.8 */ public AnnotatedType getAnnotatedReceiverType() { + if (Modifier.isStatic(this.getModifiers())) + return null; return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), @@ -577,8 +584,8 @@ public abstract class Executable extends AccessibleObject } /** - * Returns an array of AnnotatedType objects that represent the use of - * types to specify formal parameter types of the method/constructor + * Returns an array of {@code AnnotatedType} objects that represent the use + * of types to specify formal parameter types of the method/constructor * represented by this Executable. The order of the objects in the array * corresponds to the order of the formal parameter types in the * declaration of the method/constructor. @@ -587,7 +594,8 @@ public abstract class Executable extends AccessibleObject * parameters. * * @return an array of objects representing the types of the - * formal parameters of this method or constructor + * formal parameters of the method or constructor represented by this + * {@code Executable} * * @since 1.8 */ @@ -602,8 +610,8 @@ public abstract class Executable extends AccessibleObject } /** - * Returns an array of AnnotatedType objects that represent the use of - * types to specify the declared exceptions of the method/constructor + * Returns an array of {@code AnnotatedType} objects that represent the use + * of types to specify the declared exceptions of the method/constructor * represented by this Executable. The order of the objects in the array * corresponds to the order of the exception types in the declaration of * the method/constructor. @@ -612,7 +620,8 @@ public abstract class Executable extends AccessibleObject * exceptions. * * @return an array of objects representing the declared - * exceptions of this method or constructor + * exceptions of the method or constructor represented by this {@code + * Executable} * * @since 1.8 */ diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java index e9f3f957c09..9e01fc59ba6 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java +++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java @@ -118,6 +118,7 @@ public class AnnotatedTypeFactory { static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION, new TypeAnnotation[0], new TypeAnnotation[0], null); + static final AnnotatedType[] EMPTY_ANNOTATED_TYPE_ARRAY = new AnnotatedType[0]; private static class AnnotatedTypeBaseImpl implements AnnotatedType { private final Type type; diff --git a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java index 6b9712a6d4a..12fa1fa687b 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java +++ b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java @@ -174,6 +174,11 @@ public class TypeAnnotationParser { public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations, ConstantPool cp, Class decl) { + if (decl == Object.class || + decl.isArray() || + decl.isPrimitive() || + decl == Void.TYPE) + return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE_ARRAY; return buildAnnotatedTypes(rawAnnotations, cp, decl, diff --git a/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedInterfaces.java b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedInterfaces.java new file mode 100644 index 00000000000..6a6d256e551 --- /dev/null +++ b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedInterfaces.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8022324 + * @summary Test Class.getAnnotatedInterfaces() returns 0-length array as + * specified. + */ + +import java.lang.reflect.AnnotatedType; +import java.util.Arrays; + +public class GetAnnotatedInterfaces { + private static final Class[] testData = { + GetAnnotatedInterfaces.class, + (new Clz() {}).getClass(), + (new Object() {}).getClass(), + Object[].class, + Object[][].class, + Object[][][].class, + Object.class, + void.class, + int.class, + }; + + private static int failed = 0; + private static int tests = 0; + + public static void main(String[] args) throws Exception { + testReturnsZeroLengthArray(); + + if (failed != 0) + throw new RuntimeException("Test failed, check log for details"); + if (tests != 9) + throw new RuntimeException("Not all cases ran, failing"); + } + + private static void testReturnsZeroLengthArray() { + for (Class toTest : testData) { + tests++; + + AnnotatedType[] res = toTest.getAnnotatedInterfaces(); + + if (res == null) { + failed++; + System.out.println(toTest + ".class.getAnnotatedInterface() returns" + + "'null' should zero length array"); + } else if (res.length != 0) { + failed++; + System.out.println(toTest + ".class.getAnnotatedInterfaces() returns: " + + Arrays.asList(res) + ", should be a zero length array of AnnotatedType"); + } + } + } + + interface If {} + + static abstract class Clz {} +} diff --git a/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java new file mode 100644 index 00000000000..e3dd64612c8 --- /dev/null +++ b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024915 + */ + +import java.lang.reflect.AnnotatedType; +import java.util.Arrays; + +public class GetAnnotatedReceiverType { + public void method() {} + public void method0(GetAnnotatedReceiverType this) {} + public static void method4() {} + + class Inner0 { + public Inner0() {} + } + + class Inner1 { + public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {} + } + + private static int failures = 0; + private static int tests = 0; + + public static void main(String[] args) throws NoSuchMethodException { + checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method").getAnnotatedReceiverType(), + "getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType"); + checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(), + "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType"); + + checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0").getAnnotatedReceiverType(), + "getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType"); + checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(), + "getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType"); + + checkNull(GetAnnotatedReceiverType.class.getMethod("method4").getAnnotatedReceiverType(), + "getAnnotatedReceiverType() on a static method should return null"); + + if (failures != 0) + throw new RuntimeException("Test failed, see log for details"); + else if (tests != 5) + throw new RuntimeException("Not all cases ran, failing"); + } + + private static void checkNull(Object o, String msg) { + if (o != null) { + failures++; + System.err.println(msg); + } + tests++; + } + + private static void checkEmptyAT(AnnotatedType a, String msg) { + if (a.getAnnotations().length != 0) { + failures++; + System.err.print(msg); + } + tests++; + } +} diff --git a/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java index d112203a90f..34b95a0a518 100644 --- a/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java +++ b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java @@ -23,12 +23,16 @@ /* * @test - * @bug 8022343 - * @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so + * @bug 8022343 8007072 + * @summary Test Class.getAnnotatedSuperclass() returns null/non-null + * AnnotatedType as specified */ +import java.lang.reflect.AnnotatedType; +import java.util.Arrays; + public class GetAnnotatedSuperclass { - private static final Class[] testData = { + private static final Class[] nullTestData = { Object.class, If.class, Object[].class, @@ -36,9 +40,31 @@ public class GetAnnotatedSuperclass { int.class, }; + private static final Class[] nonNullTestData = { + Class.class, + GetAnnotatedSuperclass.class, + (new If() {}).getClass(), + (new Clz() {}).getClass(), + (new Object() {}).getClass(), + }; + + private static int failed = 0; + private static int tests = 0; + public static void main(String[] args) throws Exception { - int failed = 0; - for (Class toTest : testData) { + testReturnsNull(); + testReturnsEmptyAT(); + + if (failed != 0) + throw new RuntimeException("Test failed, check log for details"); + if (tests != 10) + throw new RuntimeException("Not all cases ran, failing"); + } + + private static void testReturnsNull() { + for (Class toTest : nullTestData) { + tests++; + Object res = toTest.getAnnotatedSuperclass(); if (res != null) { @@ -47,10 +73,26 @@ public class GetAnnotatedSuperclass { + res + ", should be null"); } } + } - if (failed != 0) - throw new RuntimeException("Test failed, check log for details"); + private static void testReturnsEmptyAT() { + for (Class toTest : nonNullTestData) { + tests++; + + AnnotatedType res = toTest.getAnnotatedSuperclass(); + + if (res == null) { + failed++; + System.out.println(toTest + ".getAnnotatedSuperclass() returns 'null' should be non-null"); + } else if (res.getAnnotations().length != 0) { + failed++; + System.out.println(toTest + ".getAnnotatedSuperclass() returns: " + + Arrays.asList(res.getAnnotations()) + ", should be an empty AnnotatedType"); + } + } } interface If {} + + static abstract class Clz {} } From 738a5097a705c237035378ce1f20c41598c76ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?= Date: Mon, 30 Sep 2013 12:19:48 +0200 Subject: [PATCH 011/293] 8009719: core reflection should get type annotation data from the VM lazily Remove typeAnnotations field from Method, Constructor, and Field, update Executable and Field to fetch data on demand. Reviewed-by: darcy, erikj --- jdk/make/java/java/FILES_c.gmk | 1 + jdk/make/java/java/mapfile-vers | 2 ++ jdk/makefiles/mapfiles/libjava/mapfile-vers | 2 ++ .../java/lang/reflect/Constructor.java | 8 ----- .../classes/java/lang/reflect/Executable.java | 15 +++++--- .../classes/java/lang/reflect/Field.java | 7 ++-- .../classes/java/lang/reflect/Method.java | 8 ----- jdk/src/share/javavm/export/jvm.h | 5 +++ .../native/java/lang/reflect/Executable.c | 10 +++--- .../share/native/java/lang/reflect/Field.c | 34 +++++++++++++++++++ 10 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 jdk/src/share/native/java/lang/reflect/Field.c diff --git a/jdk/make/java/java/FILES_c.gmk b/jdk/make/java/java/FILES_c.gmk index d01b0c29563..29bb7e3b94a 100644 --- a/jdk/make/java/java/FILES_c.gmk +++ b/jdk/make/java/java/FILES_c.gmk @@ -33,6 +33,7 @@ FILES_c = \ Console_md.c \ Double.c \ Executable.c \ + Field.c \ FileDescriptor_md.c \ FileInputStream.c \ FileInputStream_md.c \ diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers index bb06a3d6036..29ce7eb26df 100644 --- a/jdk/make/java/java/mapfile-vers +++ b/jdk/make/java/java/mapfile-vers @@ -190,6 +190,8 @@ SUNWprivate_1.1 { Java_java_lang_reflect_Array_setLong; Java_java_lang_reflect_Array_setShort; Java_java_lang_reflect_Executable_getParameters0; + Java_java_lang_reflect_Executable_getTypeAnnotationBytes0; + Java_java_lang_reflect_Field_getTypeAnnotationBytes0; Java_java_lang_Runtime_freeMemory; Java_java_lang_Runtime_maxMemory; Java_java_lang_Runtime_gc; diff --git a/jdk/makefiles/mapfiles/libjava/mapfile-vers b/jdk/makefiles/mapfiles/libjava/mapfile-vers index bb06a3d6036..29ce7eb26df 100644 --- a/jdk/makefiles/mapfiles/libjava/mapfile-vers +++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers @@ -190,6 +190,8 @@ SUNWprivate_1.1 { Java_java_lang_reflect_Array_setLong; Java_java_lang_reflect_Array_setShort; Java_java_lang_reflect_Executable_getParameters0; + Java_java_lang_reflect_Executable_getTypeAnnotationBytes0; + Java_java_lang_reflect_Field_getTypeAnnotationBytes0; Java_java_lang_Runtime_freeMemory; Java_java_lang_Runtime_maxMemory; Java_java_lang_Runtime_gc; diff --git a/jdk/src/share/classes/java/lang/reflect/Constructor.java b/jdk/src/share/classes/java/lang/reflect/Constructor.java index 0ed60dc375b..202a7368fb1 100644 --- a/jdk/src/share/classes/java/lang/reflect/Constructor.java +++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java @@ -67,8 +67,6 @@ public final class Constructor extends Executable { private transient ConstructorRepository genericInfo; private byte[] annotations; private byte[] parameterAnnotations; - // This is set by the vm at Constructor creation - private byte[] typeAnnotations; // Generics infrastructure // Accessor for factory @@ -141,8 +139,6 @@ public final class Constructor extends Executable { res.root = this; // Might as well eagerly propagate this if already present res.constructorAccessor = constructorAccessor; - - res.typeAnnotations = typeAnnotations; return res; } @@ -155,10 +151,6 @@ public final class Constructor extends Executable { byte[] getAnnotationBytes() { return annotations; } - @Override - byte[] getTypeAnnotationBytes() { - return typeAnnotations; - } /** * {@inheritDoc} diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java index af876c6f4f2..43b9cc64f06 100644 --- a/jdk/src/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java @@ -51,7 +51,6 @@ public abstract class Executable extends AccessibleObject * Accessor method to allow code sharing */ abstract byte[] getAnnotationBytes(); - abstract byte[] getTypeAnnotationBytes(); /** * Does the Executable have generic information. @@ -352,6 +351,12 @@ public abstract class Executable extends AccessibleObject private transient volatile Parameter[] parameters; private native Parameter[] getParameters0(); + private native byte[] getTypeAnnotationBytes0(); + + // Needed by reflectaccess + byte[] getTypeAnnotationBytes() { + return getTypeAnnotationBytes0(); + } /** * Returns an array of {@code Class} objects that represent the @@ -541,7 +546,7 @@ public abstract class Executable extends AccessibleObject * @since 1.8 */ AnnotatedType getAnnotatedReturnType0(Type returnType) { - return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(), + return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), this, @@ -574,7 +579,7 @@ public abstract class Executable extends AccessibleObject public AnnotatedType getAnnotatedReceiverType() { if (Modifier.isStatic(this.getModifiers())) return null; - return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(), + return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), this, @@ -600,7 +605,7 @@ public abstract class Executable extends AccessibleObject * @since 1.8 */ public AnnotatedType[] getAnnotatedParameterTypes() { - return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(), + return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), this, @@ -626,7 +631,7 @@ public abstract class Executable extends AccessibleObject * @since 1.8 */ public AnnotatedType[] getAnnotatedExceptionTypes() { - return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(), + return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), this, diff --git a/jdk/src/share/classes/java/lang/reflect/Field.java b/jdk/src/share/classes/java/lang/reflect/Field.java index 4052e06e804..e84b6b242d3 100644 --- a/jdk/src/share/classes/java/lang/reflect/Field.java +++ b/jdk/src/share/classes/java/lang/reflect/Field.java @@ -82,8 +82,6 @@ class Field extends AccessibleObject implements Member { // currently only two levels deep (i.e., one root Field and // potentially many Field objects pointing to it.) private Field root; - // This is set by the vm at Field creation - private byte[] typeAnnotations; // Generics infrastructure @@ -149,7 +147,6 @@ class Field extends AccessibleObject implements Member { res.fieldAccessor = fieldAccessor; res.overrideFieldAccessor = overrideFieldAccessor; - res.typeAnnotations = typeAnnotations; return res; } @@ -1148,6 +1145,8 @@ class Field extends AccessibleObject implements Member { return declaredAnnotations; } + private native byte[] getTypeAnnotationBytes0(); + /** * Returns an AnnotatedType object that represents the use of a type to specify * the declared type of the field represented by this Field. @@ -1157,7 +1156,7 @@ class Field extends AccessibleObject implements Member { * @since 1.8 */ public AnnotatedType getAnnotatedType() { - return TypeAnnotationParser.buildAnnotatedType(typeAnnotations, + return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), this, diff --git a/jdk/src/share/classes/java/lang/reflect/Method.java b/jdk/src/share/classes/java/lang/reflect/Method.java index 7c7abe43dff..b046a7a1d3d 100644 --- a/jdk/src/share/classes/java/lang/reflect/Method.java +++ b/jdk/src/share/classes/java/lang/reflect/Method.java @@ -80,8 +80,6 @@ public final class Method extends Executable { // currently only two levels deep (i.e., one root Method and // potentially many Method objects pointing to it.) private Method root; - // This is set by the vm at Method creation - private byte[] typeAnnotations; // Generics infrastructure private String getGenericSignature() {return signature;} @@ -152,8 +150,6 @@ public final class Method extends Executable { res.root = this; // Might as well eagerly propagate this if already present res.methodAccessor = methodAccessor; - - res.typeAnnotations = typeAnnotations; return res; } @@ -166,10 +162,6 @@ public final class Method extends Executable { byte[] getAnnotationBytes() { return annotations; } - @Override - byte[] getTypeAnnotationBytes() { - return typeAnnotations; - } /** * {@inheritDoc} diff --git a/jdk/src/share/javavm/export/jvm.h b/jdk/src/share/javavm/export/jvm.h index 48181c06bce..caec0b9306f 100644 --- a/jdk/src/share/javavm/export/jvm.h +++ b/jdk/src/share/javavm/export/jvm.h @@ -472,6 +472,11 @@ JVM_GetClassAnnotations(JNIEnv *env, jclass cls); JNIEXPORT jbyteArray JNICALL JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); +JNIEXPORT jbyteArray JNICALL +JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field); + +JNIEXPORT jbyteArray JNICALL +JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method); /* * New (JDK 1.4) reflection implementation diff --git a/jdk/src/share/native/java/lang/reflect/Executable.c b/jdk/src/share/native/java/lang/reflect/Executable.c index f6133e8d812..1e32d5e1745 100644 --- a/jdk/src/share/native/java/lang/reflect/Executable.c +++ b/jdk/src/share/native/java/lang/reflect/Executable.c @@ -23,11 +23,7 @@ * questions. */ -#include -#include - #include "jni.h" -#include "jni_util.h" #include "jvm.h" #include "java_lang_reflect_Executable.h" @@ -36,3 +32,9 @@ Java_java_lang_reflect_Executable_getParameters0(JNIEnv *env, jobject method) { return JVM_GetMethodParameters(env, method); } + +JNIEXPORT jbyteArray JNICALL +Java_java_lang_reflect_Executable_getTypeAnnotationBytes0(JNIEnv *env, + jobject method) { + return JVM_GetMethodTypeAnnotations(env, method); +} diff --git a/jdk/src/share/native/java/lang/reflect/Field.c b/jdk/src/share/native/java/lang/reflect/Field.c new file mode 100644 index 00000000000..7800abf1ade --- /dev/null +++ b/jdk/src/share/native/java/lang/reflect/Field.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "jni.h" +#include "jvm.h" +#include "java_lang_reflect_Field.h" + +JNIEXPORT jbyteArray JNICALL +Java_java_lang_reflect_Field_getTypeAnnotationBytes0(JNIEnv *env, + jobject field) { + return JVM_GetFieldTypeAnnotations(env, field); +} From 938247e8f4b7f989a69b02669c684117c8ca136d Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Mon, 30 Sep 2013 12:58:18 +0200 Subject: [PATCH 012/293] 8023492: jfr.jar gets loaded even though it's not used Reviewed-by: erikj, mgronlun --- .../tools/buildmetaindex/BuildMetaIndex.java | 86 ++++++++++++------- 1 file changed, 55 insertions(+), 31 deletions(-) diff --git a/jdk/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java b/jdk/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java index 73feec3d2bb..f573c57e99f 100644 --- a/jdk/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java +++ b/jdk/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java @@ -173,6 +173,44 @@ class JarMetaIndex { */ private HashMap> knownPrefixMap = new HashMap<>(); + /* + * A class for mapping package prefixes to the number of + * levels of package elements to include. + */ + static class ExtraLevel { + public ExtraLevel(String prefix, int levels) { + this.prefix = prefix; + this.levels = levels; + } + String prefix; + int levels; + } + + /* + * A list of the special-cased package names. + */ + private static ArrayList extraLevels = new ArrayList<>(); + + static { + // The order of these statements is significant, + // since we stop looking after the first match. + + // Need more precise information to disambiguate + // (illegal) references from applications to + // obsolete backported collections classes in + // com/sun/java/util + extraLevels.add(new ExtraLevel("com/sun/java/util/", Integer.MAX_VALUE)); + extraLevels.add(new ExtraLevel("com/sun/java/", 4)); + // Need more information than just first two package + // name elements to determine that classes in + // deploy.jar are not in rt.jar + extraLevels.add(new ExtraLevel("com/sun/", 3)); + // Need to make sure things in jfr.jar aren't + // confused with other com/oracle/** packages + extraLevels.add(new ExtraLevel("com/oracle/jrockit", 3)); + } + + /* * We add maximum 5 second level entries to "sun", "java" and * "javax" entries. Tune this parameter to get a balance on the @@ -237,39 +275,25 @@ class JarMetaIndex { String[] pkgElements = name.split("/"); // Last one is the class name; definitely ignoring that if (pkgElements.length > 2) { - String meta = null; - // Need more information than just first two package - // name elements to determine that classes in - // deploy.jar are not in rt.jar - if (pkgElements.length > 3 && - pkgElements[0].equals("com") && - pkgElements[1].equals("sun")) { - // Need more precise information to disambiguate - // (illegal) references from applications to - // obsolete backported collections classes in - // com/sun/java/util - if (pkgElements.length > 4 && - pkgElements[2].equals("java")) { - int bound = 0; - if (pkgElements[3].equals("util")) { - // Take all of the packages - bound = pkgElements.length - 1; - } else { - // Trim it somewhat more - bound = 4; - } - meta = ""; - for (int j = 0; j < bound; j++) { - meta += pkgElements[j] + "/"; - } - } else { - meta = pkgElements[0] + "/" + pkgElements[1] - + "/" + pkgElements[2] + "/"; + String meta = ""; + + // Default is 2 levels of package elements + int levels = 2; + + // But for some packages we add more elements + for(ExtraLevel el : extraLevels) { + if (name.startsWith(el.prefix)) { + levels = el.levels; + break; } - } else { - meta = pkgElements[0] + "/" + pkgElements[1] + "/"; } - indexSet.add(meta); + for (int i = 0; i < levels && i < pkgElements.length - 1; i++) { + meta += pkgElements[i] + "/"; + } + + if (!meta.equals("")) { + indexSet.add(meta); + } } } // end of "while" loop; From 2f5f83e38c305cd5c3083631abffeda8c8355dbd Mon Sep 17 00:00:00 2001 From: Peter Allwin Date: Mon, 30 Sep 2013 14:28:53 +0200 Subject: [PATCH 013/293] 8012923: [parfait] File Descriptor Leak in jdk/src/windows/demo/jvmti/hprof/hprof_md.c Reviewed-by: chegar, sla, sspitsyn, mgronlun --- jdk/src/windows/demo/jvmti/hprof/hprof_md.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/jdk/src/windows/demo/jvmti/hprof/hprof_md.c b/jdk/src/windows/demo/jvmti/hprof/hprof_md.c index 90e15ed5b84..67cf2f63c4c 100644 --- a/jdk/src/windows/demo/jvmti/hprof/hprof_md.c +++ b/jdk/src/windows/demo/jvmti/hprof/hprof_md.c @@ -82,9 +82,6 @@ md_connect(char *hostname, unsigned short port) struct sockaddr_in s; int fd; - /* create a socket */ - fd = (int)socket(AF_INET, SOCK_STREAM, 0); - /* find remote host's addr from name */ if ((hentry = gethostbyname(hostname)) == NULL) { return -1; @@ -97,8 +94,15 @@ md_connect(char *hostname, unsigned short port) s.sin_port = htons(port); s.sin_family = AF_INET; + /* create a socket */ + fd = (int)socket(AF_INET, SOCK_STREAM, 0); + if (INVALID_SOCKET == fd) { + return 0; + } + /* now try connecting */ - if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) { + if (SOCKET_ERROR == connect(fd, (struct sockaddr*)&s, sizeof(s))) { + closesocket(fd); return 0; } return fd; From bae75822436b3f84a52d588efaaee64d8c935582 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Thu, 19 Sep 2013 11:59:14 -0700 Subject: [PATCH 014/293] 7122707: Security Providers need to have their version numbers updated for JDK8 Reviewed-by: xuelei --- .../classes/apple/security/AppleProvider.java | 4 +- .../com/sun/crypto/provider/SunJCE.java | 2 +- .../com/sun/security/sasl/Provider.java | 4 +- .../jcp/xml/dsig/internal/dom/XMLDSigRI.java | 4 +- .../share/classes/sun/security/ec/SunEC.java | 4 +- .../sun/security/jgss/SunProvider.java | 4 +- .../jgss/wrapper/SunNativeProvider.java | 4 +- .../sun/security/pkcs11/SunPKCS11.java | 4 +- .../classes/sun/security/provider/MD4.java | 4 +- .../classes/sun/security/provider/Sun.java | 2 +- .../provider/VerificationProvider.java | 4 +- .../classes/sun/security/rsa/SunRsaSign.java | 4 +- .../sun/security/smartcardio/SunPCSC.java | 4 +- .../classes/sun/security/ssl/JsseJce.java | 2 +- .../classes/sun/security/ssl/SunJSSE.java | 4 +- .../sun/security/mscapi/SunMSCAPI.java | 4 +- .../Provider/ProviderVersionCheck.java | 60 +++++++++++++++++++ 17 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 jdk/test/java/security/Provider/ProviderVersionCheck.java diff --git a/jdk/src/macosx/classes/apple/security/AppleProvider.java b/jdk/src/macosx/classes/apple/security/AppleProvider.java index e1e3e2fb682..654af3c5345 100644 --- a/jdk/src/macosx/classes/apple/security/AppleProvider.java +++ b/jdk/src/macosx/classes/apple/security/AppleProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ public final class AppleProvider extends Provider { public AppleProvider() { /* We are the Apple provider */ - super("Apple", 1.1, info); + super("Apple", 1.8d, info); AccessController.doPrivileged(new java.security.PrivilegedAction() { public Object run() { diff --git a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java index af828e2a651..08e1e2ae737 100644 --- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java @@ -104,7 +104,7 @@ public final class SunJCE extends Provider { public SunJCE() { /* We are the "SunJCE" provider */ - super("SunJCE", 1.7d, info); + super("SunJCE", 1.8d, info); final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" + "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" + diff --git a/jdk/src/share/classes/com/sun/security/sasl/Provider.java b/jdk/src/share/classes/com/sun/security/sasl/Provider.java index 8b9c00c8800..986a18758a1 100644 --- a/jdk/src/share/classes/com/sun/security/sasl/Provider.java +++ b/jdk/src/share/classes/com/sun/security/sasl/Provider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ public final class Provider extends java.security.Provider { " server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)"; public Provider() { - super("SunSASL", 1.7d, info); + super("SunSASL", 1.8d, info); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { diff --git a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java index 2cc871485b3..d4dd77b7948 100644 --- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java +++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java @@ -28,7 +28,7 @@ * =========================================================================== */ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved. */ /* * $Id: XMLDSigRI.java 1400021 2012-10-19 10:16:04Z coheigea $ @@ -61,7 +61,7 @@ public final class XMLDSigRI extends Provider { public XMLDSigRI() { /* We are the XMLDSig provider */ - super("XMLDSig", 1.8, INFO); + super("XMLDSig", 1.8d, INFO); final Map map = new HashMap(); map.put("XMLSignatureFactory.DOM", diff --git a/jdk/src/share/classes/sun/security/ec/SunEC.java b/jdk/src/share/classes/sun/security/ec/SunEC.java index 539cea41162..31891696b4f 100644 --- a/jdk/src/share/classes/sun/security/ec/SunEC.java +++ b/jdk/src/share/classes/sun/security/ec/SunEC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public final class SunEC extends Provider { } public SunEC() { - super("SunEC", 1.7d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)"); + super("SunEC", 1.8d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)"); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/src/share/classes/sun/security/jgss/SunProvider.java b/jdk/src/share/classes/sun/security/jgss/SunProvider.java index a49cb8a0fee..42396754b23 100644 --- a/jdk/src/share/classes/sun/security/jgss/SunProvider.java +++ b/jdk/src/share/classes/sun/security/jgss/SunProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ public final class SunProvider extends Provider { public SunProvider() { /* We are the Sun JGSS provider */ - super("SunJGSS", 1.7d, INFO); + super("SunJGSS", 1.8d, INFO); AccessController.doPrivileged( new java.security.PrivilegedAction() { diff --git a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java index b0e81aa2a40..b0bb15d0036 100644 --- a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java +++ b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,7 +120,7 @@ public final class SunNativeProvider extends Provider { public SunNativeProvider() { /* We are the Sun NativeGSS provider */ - super(NAME, 1.0, INFO); + super(NAME, 1.8d, INFO); if (MECH_MAP != null) { AccessController.doPrivileged(new PutAllAction(this, MECH_MAP)); diff --git a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java index ee9169b59d8..b6dd35a80e8 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -94,7 +94,7 @@ public final class SunPKCS11 extends AuthProvider { } public SunPKCS11() { - super("SunPKCS11-Dummy", 1.7d, "SunPKCS11-Dummy"); + super("SunPKCS11-Dummy", 1.8d, "SunPKCS11-Dummy"); throw new ProviderException ("SunPKCS11 requires configuration file argument"); } @@ -127,7 +127,7 @@ public final class SunPKCS11 extends AuthProvider { public SunPKCS11(String configName, InputStream configStream) { super("SunPKCS11-" + Config.getConfig(configName, configStream).getName(), - 1.7d, Config.getConfig(configName, configStream).getDescription()); + 1.8d, Config.getConfig(configName, configStream).getDescription()); this.configName = configName; this.config = Config.removeConfig(configName); diff --git a/jdk/src/share/classes/sun/security/provider/MD4.java b/jdk/src/share/classes/sun/security/provider/MD4.java index d04639f18e5..346bc9db10d 100644 --- a/jdk/src/share/classes/sun/security/provider/MD4.java +++ b/jdk/src/share/classes/sun/security/provider/MD4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public final class MD4 extends DigestBase { private final static Provider md4Provider; static { - md4Provider = new Provider("MD4Provider", 1.0d, "MD4 MessageDigest") { + md4Provider = new Provider("MD4Provider", 1.8d, "MD4 MessageDigest") { private static final long serialVersionUID = -8850464997518327965L; }; AccessController.doPrivileged(new PrivilegedAction() { diff --git a/jdk/src/share/classes/sun/security/provider/Sun.java b/jdk/src/share/classes/sun/security/provider/Sun.java index 4af2be50864..07ef2ff4a23 100644 --- a/jdk/src/share/classes/sun/security/provider/Sun.java +++ b/jdk/src/share/classes/sun/security/provider/Sun.java @@ -47,7 +47,7 @@ public final class Sun extends Provider { public Sun() { /* We are the SUN provider */ - super("SUN", 1.8, INFO); + super("SUN", 1.8d, INFO); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/src/share/classes/sun/security/provider/VerificationProvider.java b/jdk/src/share/classes/sun/security/provider/VerificationProvider.java index 082427d76df..296b0343706 100644 --- a/jdk/src/share/classes/sun/security/provider/VerificationProvider.java +++ b/jdk/src/share/classes/sun/security/provider/VerificationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ public final class VerificationProvider extends Provider { } public VerificationProvider() { - super("SunJarVerification", 1.7, "Jar Verification Provider"); + super("SunJarVerification", 1.8d, "Jar Verification Provider"); // register all algorithms normally registered by the Sun and SunRsaSign // providers, but only if they are missing if (ACTIVE == false) { diff --git a/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java b/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java index a00bf30172f..65ae02a080e 100644 --- a/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java +++ b/jdk/src/share/classes/sun/security/rsa/SunRsaSign.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ public final class SunRsaSign extends Provider { private static final long serialVersionUID = 866040293550393045L; public SunRsaSign() { - super("SunRsaSign", 1.7d, "Sun RSA signature provider"); + super("SunRsaSign", 1.8d, "Sun RSA signature provider"); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java b/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java index fa931922495..c0cb85688f9 100644 --- a/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java +++ b/jdk/src/share/classes/sun/security/smartcardio/SunPCSC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ public final class SunPCSC extends Provider { private static final long serialVersionUID = 6168388284028876579L; public SunPCSC() { - super("SunPCSC", 1.7d, "Sun PC/SC provider"); + super("SunPCSC", 1.8d, "Sun PC/SC provider"); AccessController.doPrivileged(new PrivilegedAction() { public Void run() { put("TerminalFactory.PC/SC", "sun.security.smartcardio.SunPCSC$Factory"); diff --git a/jdk/src/share/classes/sun/security/ssl/JsseJce.java b/jdk/src/share/classes/sun/security/ssl/JsseJce.java index d128f2e7029..4c98772aeca 100644 --- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java +++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java @@ -110,7 +110,7 @@ final class JsseJce { private static final long serialVersionUID = -3284138292032213752L; SunCertificates(final Provider p) { - super("SunCertificates", 1.0d, "SunJSSE internal"); + super("SunCertificates", 1.8d, "SunJSSE internal"); AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { diff --git a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java index 08d03f7042b..aa55be174d9 100644 --- a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java +++ b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,7 +131,7 @@ public abstract class SunJSSE extends java.security.Provider { private SunJSSE(java.security.Provider cryptoProvider, String providerName) { - super("SunJSSE", 1.6d, fipsInfo + providerName + ")"); + super("SunJSSE", 1.8d, fipsInfo + providerName + ")"); subclassCheck(); if (cryptoProvider == null) { // Calling Security.getProvider() will cause other providers to be diff --git a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java index 1af669415ee..7725b27d3c6 100644 --- a/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java +++ b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ public final class SunMSCAPI extends Provider { } public SunMSCAPI() { - super("SunMSCAPI", 1.7d, INFO); + super("SunMSCAPI", 1.8d, INFO); // if there is no security manager installed, put directly into // the provider. Otherwise, create a temporary map and use a diff --git a/jdk/test/java/security/Provider/ProviderVersionCheck.java b/jdk/test/java/security/Provider/ProviderVersionCheck.java new file mode 100644 index 00000000000..555d1df9428 --- /dev/null +++ b/jdk/test/java/security/Provider/ProviderVersionCheck.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.Provider; +import java.security.Security; +import java.lang.Exception; + +/* + * @test + * @bug 7122707 + * @run main/othervm ProviderVersionCheck + * @summary Verify all providers in the default Providers list have the proper + * version for the release + * @author Anthony Scarpino + */ + +public class ProviderVersionCheck { + + public static void main(String arg[]) throws Exception{ + + boolean failure = false; + + for (Provider p: Security.getProviders()) { + System.out.print(p.getName() + " "); + if (p.getVersion() != 1.8d) { + System.out.println("failed. " + "Version received was " + + p.getVersion()); + failure = true; + } else { + System.out.println("passed."); + } + } + + if (failure) { + throw new Exception("Provider(s) failed to have the expected " + + "version value."); + } + } + +} From cf7cbcdce886a7385a1ee152e54cf3236ec63057 Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Wed, 18 Sep 2013 14:57:29 -0700 Subject: [PATCH 015/293] 8004283: test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh failing intermittently Reviewed-by: vinnie --- jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh b/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh index 30334555302..ddfc9da0ac6 100644 --- a/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh +++ b/jdk/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -143,7 +143,8 @@ fi cd ${TESTSRC} ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \ -DDIR=${TESTSRC}${FS}BasicData${FS} \ - -classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \ + -classpath \ + ${TESTCLASSES}${PS}${TESTCLASSES}${FS}..${PS}${TESTSRC}${FS}loader.jar \ -DCUSTOM_DB_DIR=${TESTCLASSES} \ -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}BasicData${FS}p11-${token}.txt \ -DNO_DEFAULT=true \ From e9806ae426add1c7d412235d5d30fd1b6536984f Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Mon, 2 Sep 2013 09:52:08 -0700 Subject: [PATCH 016/293] 8009438: sun/security/pkcs11/Secmod tests failing on Ubuntu 12.04 Reviewed-by: vinnie --- jdk/src/share/classes/sun/security/pkcs11/Secmod.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/sun/security/pkcs11/Secmod.java b/jdk/src/share/classes/sun/security/pkcs11/Secmod.java index 927a32ae761..1d2c5c0bdc6 100644 --- a/jdk/src/share/classes/sun/security/pkcs11/Secmod.java +++ b/jdk/src/share/classes/sun/security/pkcs11/Secmod.java @@ -756,8 +756,12 @@ public final class Secmod { if (DEBUG) System.out.println("handles: " + handles.length); for (long handle : handles) { - TrustAttributes trust = new TrustAttributes(token, session, handle); - trustMap.put(trust.getHash(), trust); + try { + TrustAttributes trust = new TrustAttributes(token, session, handle); + trustMap.put(trust.getHash(), trust); + } catch (PKCS11Exception e) { + // skip put on pkcs11 error + } } } finally { token.releaseSession(session); From 3debf156b12b2f2a2d9b964886b5db3e993c2cf2 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Mon, 30 Sep 2013 16:15:49 -0700 Subject: [PATCH 017/293] 8016110: Japanese char (MS932) 0x5C cannot be used as an argument when quoted Reviewed-by: ksrini, akhil --- jdk/src/windows/bin/cmdtoargs.c | 76 ++++++++++------ jdk/test/tools/launcher/I18NArgTest.java | 111 +++++++++++++++++++++++ 2 files changed, 160 insertions(+), 27 deletions(-) create mode 100644 jdk/test/tools/launcher/I18NArgTest.java diff --git a/jdk/src/windows/bin/cmdtoargs.c b/jdk/src/windows/bin/cmdtoargs.c index 69f1aef7383..352b1553a08 100644 --- a/jdk/src/windows/bin/cmdtoargs.c +++ b/jdk/src/windows/bin/cmdtoargs.c @@ -53,6 +53,16 @@ typedef struct { static StdArg *stdargs; static int stdargc; +static int copyCh(USHORT ch, char* dest) { + if (HIBYTE(ch) == 0) { + *dest = (char)ch; + return 1; + } else { + *((USHORT *)dest) = ch; + return 2; + } +} + static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { char* src = cmdline; @@ -61,31 +71,43 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { int quotes = 0; int slashes = 0; - char prev = 0; - char ch = 0; + // "prev"/"ch" may contain either a single byte, or a double byte + // character encoded in CP_ACP. + USHORT prev = 0; + USHORT ch = 0; int i; jboolean done = JNI_FALSE; + int charLength; *wildcard = JNI_FALSE; - while ((ch = *src) != 0 && !done) { + while (!done) { + charLength = CharNextExA(CP_ACP, src, 0) - src; + if (charLength == 0) { + break; + } else if (charLength == 1) { + ch = (USHORT)(UCHAR)src[0]; + } else { + ch = ((USHORT *)src)[0]; + } + switch (ch) { - case '"': + case L'"': if (separator) { done = JNI_TRUE; break; } - if (prev == '\\') { + if (prev == L'\\') { for (i = 1; i < slashes; i += 2) { - *dest++ = prev; + dest += copyCh(prev, dest); } if (slashes % 2 == 1) { - *dest++ = ch; + dest += copyCh(ch, dest); } else { quotes++; } - } else if (prev == '"' && quotes % 2 == 0) { + } else if (prev == L'"' && quotes % 2 == 0) { quotes++; - *dest++ = ch; // emit every other consecutive quote + dest += copyCh(ch, dest); // emit every other consecutive quote } else if (quotes == 0) { quotes++; // starting quote } else { @@ -94,7 +116,7 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { slashes = 0; break; - case '\\': + case L'\\': slashes++; if (separator) { done = JNI_TRUE; @@ -102,23 +124,23 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { } break; - case ' ': - case '\t': - if (prev == '\\') { + case L' ': + case L'\t': + if (prev == L'\\') { for (i = 0 ; i < slashes; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } } if (quotes % 2 == 1) { - *dest++ = ch; + dest += copyCh(ch, dest); } else { separator = JNI_TRUE; } slashes = 0; break; - case '*': - case '?': + case L'*': + case L'?': if (separator) { done = JNI_TRUE; separator = JNI_FALSE; @@ -127,36 +149,36 @@ static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) { if (quotes % 2 == 0) { *wildcard = JNI_TRUE; } - if (prev == '\\') { + if (prev == L'\\') { for (i = 0 ; i < slashes ; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } } - *dest++ = ch; + dest += copyCh(ch, dest); break; default: - if (prev == '\\') { + if (prev == L'\\') { for (i = 0 ; i < slashes ; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } - *dest++ = ch; + dest += copyCh(ch, dest); } else if (separator) { done = JNI_TRUE; } else { - *dest++ = ch; + dest += copyCh(ch, dest); } slashes = 0; } if (!done) { prev = ch; - src++; + src += charLength; } } - if (prev == '\\') { + if (prev == L'\\') { for (i = 0; i < slashes; i++) { - *dest++ = prev; + dest += copyCh(prev, dest); } } *dest = 0; diff --git a/jdk/test/tools/launcher/I18NArgTest.java b/jdk/test/tools/launcher/I18NArgTest.java new file mode 100644 index 00000000000..d3a28be1b64 --- /dev/null +++ b/jdk/test/tools/launcher/I18NArgTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8016110 + * @summary verify Japanese character in an argument are treated correctly + * @compile -XDignore.symbol.file I18NArgTest.java + * @run main I18NArgTest + */ +import java.io.IOException; + +public class I18NArgTest extends TestHelper { + public static void main(String... args) throws IOException { + if (!isWindows) { + return; + } + if (!"MS932".equals(System.getProperty("sun.jnu.encoding"))) { + System.err.println("MS932 encoding not set, test skipped"); + return; + } + if (args.length == 0) { + execTest(0x30bd); // MS932 Katakana SO, 0x835C + } else { + testCharacters(args); + } + } + static void execTest(int unicodeValue) { + String hexValue = Integer.toHexString(unicodeValue); + String unicodeStr = Character.toString((char)unicodeValue); + execTest("\"" + unicodeStr + "\"", hexValue); + execTest("\\" + unicodeStr + "\\", hexValue); + execTest(" " + unicodeStr + " ", hexValue); + execTest("'" + unicodeStr + "'", hexValue); + execTest("\t" + unicodeStr + "\t", hexValue); + execTest("*" + unicodeStr + "*", hexValue); + execTest("?" + unicodeStr + "?", hexValue); + + execTest("\"" + unicodeStr + unicodeStr + "\"", hexValue + hexValue); + execTest("\\" + unicodeStr + unicodeStr + "\\", hexValue + hexValue); + execTest(" " + unicodeStr + unicodeStr + " ", hexValue + hexValue); + execTest("'" + unicodeStr + unicodeStr + "'", hexValue + hexValue); + execTest("\t" + unicodeStr + unicodeStr + "\t", hexValue + hexValue); + execTest("*" + unicodeStr + unicodeStr + "*", hexValue + hexValue); + execTest("?" + unicodeStr + unicodeStr + "?", hexValue + hexValue); + + execTest("\"" + unicodeStr + "a" + unicodeStr + "\"", hexValue + "61" + hexValue); + execTest("\\" + unicodeStr + "a" + unicodeStr + "\\", hexValue + "61" + hexValue); + execTest(" " + unicodeStr + "a" + unicodeStr + " ", hexValue + "61"+ hexValue); + execTest("'" + unicodeStr + "a" + unicodeStr + "'", hexValue + "61"+ hexValue); + execTest("\t" + unicodeStr + "a" + unicodeStr + "\t", hexValue + "61"+ hexValue); + execTest("*" + unicodeStr + "a" + unicodeStr + "*", hexValue + "61"+ hexValue); + execTest("?" + unicodeStr + "a" + unicodeStr + "?", hexValue + "61"+ hexValue); + + execTest("\"" + unicodeStr + "\u00b1" + unicodeStr + "\"", hexValue + "b1" + hexValue); + execTest("\\" + unicodeStr + "\u00b1" + unicodeStr + "\\", hexValue + "b1" + hexValue); + execTest(" " + unicodeStr + "\u00b1" + unicodeStr + " ", hexValue + "b1"+ hexValue); + execTest("'" + unicodeStr + "\u00b1" + unicodeStr + "'", hexValue + "b1"+ hexValue); + execTest("\t" + unicodeStr + "\u00b1" + unicodeStr + "\t", hexValue + "b1"+ hexValue); + execTest("*" + unicodeStr + "\u00b1" + unicodeStr + "*", hexValue + "b1"+ hexValue); + execTest("?" + unicodeStr + "\u00b1" + unicodeStr + "?", hexValue + "b1"+ hexValue); + } + static void execTest(String unicodeStr, String hexValue) { + TestResult tr = doExec(javaCmd, + "-Dtest.src=" + TEST_SOURCES_DIR.getAbsolutePath(), + "-Dtest.classes=" + TEST_CLASSES_DIR.getAbsolutePath(), + "-cp", TEST_CLASSES_DIR.getAbsolutePath(), + "I18NArgTest", unicodeStr, hexValue); + System.out.println(tr.testOutput); + if (!tr.isOK()) { + System.err.println(tr); + throw new RuntimeException("test fails"); + } + } + static void testCharacters(String... args) { + String input = args[0]; + String expected = args[1]; + String hexValue = ""; + for (int i = 0; i < input.length(); i++) { + hexValue = hexValue.concat(Integer.toHexString((int)input.charAt(i))); + } + System.out.println("input:" + input); + System.out.println("expected:" + expected); + System.out.println("obtained:" + hexValue); + if (!hexValue.contains(expected)) { + String message = "Error: output does not contain expected value" + + "expected:" + expected + " obtained:" + hexValue; + throw new RuntimeException(message); + } + } +} From 223c6bf379d4e03e38dacc6069978e1bf958a9a7 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Tue, 1 Oct 2013 12:19:20 +0200 Subject: [PATCH 018/293] 8024408: Specifications for Collection/List/Set/SortedSet.spliterator() need to document if all the (subclass) instances are required to return SIZED spliterators Reviewed-by: alanb --- jdk/src/share/classes/java/util/Collection.java | 14 +++++++------- jdk/src/share/classes/java/util/Set.java | 9 ++++++--- jdk/src/share/classes/java/util/SortedSet.java | 11 +++++++---- .../Spliterator/SpliteratorCharacteristics.java | 8 +++++++- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/jdk/src/share/classes/java/util/Collection.java b/jdk/src/share/classes/java/util/Collection.java index 8e8fd5a76dc..36c7b9d9de1 100644 --- a/jdk/src/share/classes/java/util/Collection.java +++ b/jdk/src/share/classes/java/util/Collection.java @@ -503,12 +503,10 @@ public interface Collection extends Iterable { /** * Creates a {@link Spliterator} over the elements in this collection. * - *

The returned {@code Spliterator} must report the characteristic - * {@link Spliterator#SIZED}; implementations should document any additional - * characteristic values reported by the returned spliterator. If - * this collection contains no elements then the returned spliterator is - * only required to report {@link Spliterator#SIZED} and is not required to - * report additional characteristic values (if any). + * Implementations should document characteristic values reported by the + * spliterator. Such characteristic values are not required to be reported + * if the spliterator reports {@link Spliterator#SIZED} and this collection + * contains no elements. * *

The default implementation should be overridden by subclasses that * can return a more efficient spliterator. In order to @@ -534,9 +532,11 @@ public interface Collection extends Iterable { * late-binding spliterator * from the collections's {@code Iterator}. The spliterator inherits the * fail-fast properties of the collection's iterator. + *

+ * The created {@code Spliterator} reports {@link Spliterator#SIZED}. * * @implNote - * The returned {@code Spliterator} additionally reports + * The created {@code Spliterator} additionally reports * {@link Spliterator#SUBSIZED}. * *

If a spliterator covers no elements then the reporting of additional diff --git a/jdk/src/share/classes/java/util/Set.java b/jdk/src/share/classes/java/util/Set.java index d47a06a4a8a..2703049b30d 100644 --- a/jdk/src/share/classes/java/util/Set.java +++ b/jdk/src/share/classes/java/util/Set.java @@ -386,15 +386,18 @@ public interface Set extends Collection { /** * Creates a {@code Spliterator} over the elements in this set. * - *

The {@code Spliterator} reports {@link Spliterator#SIZED} and - * {@link Spliterator#DISTINCT}. Implementations should document the - * reporting of additional characteristic values. + *

The {@code Spliterator} reports {@link Spliterator#DISTINCT}. + * Implementations should document the reporting of additional + * characteristic values. * * @implSpec * The default implementation creates a * late-binding spliterator * from the set's {@code Iterator}. The spliterator inherits the * fail-fast properties of the set's iterator. + *

+ * The created {@code Spliterator} additionally reports + * {@link Spliterator#SIZED}. * * @implNote * The created {@code Spliterator} additionally reports diff --git a/jdk/src/share/classes/java/util/SortedSet.java b/jdk/src/share/classes/java/util/SortedSet.java index 3e64804e7b5..3ea932949a3 100644 --- a/jdk/src/share/classes/java/util/SortedSet.java +++ b/jdk/src/share/classes/java/util/SortedSet.java @@ -223,10 +223,10 @@ public interface SortedSet extends Set { /** * Creates a {@code Spliterator} over the elements in this sorted set. * - *

The {@code Spliterator} reports {@link Spliterator#SIZED}, - * {@link Spliterator#DISTINCT}, {@link Spliterator#SORTED} and - * {@link Spliterator#ORDERED}. Implementations should document the - * reporting of additional characteristic values. + *

The {@code Spliterator} reports {@link Spliterator#DISTINCT}, + * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}. + * Implementations should document the reporting of additional + * characteristic values. * *

The spliterator's comparator (see * {@link java.util.Spliterator#getComparator()}) must be {@code null} if @@ -240,6 +240,9 @@ public interface SortedSet extends Set { * from the sorted set's {@code Iterator}. The spliterator inherits the * fail-fast properties of the set's iterator. The * spliterator's comparator is the same as the sorted set's comparator. + *

+ * The created {@code Spliterator} additionally reports + * {@link Spliterator#SIZED}. * * @implNote * The created {@code Spliterator} additionally reports diff --git a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java index 37fbcc769d0..f226a82b439 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java +++ b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8020156 8020009 8022326 8012913 8024405 + * @bug 8020156 8020009 8022326 8012913 8024405 8024408 * @run testng SpliteratorCharacteristics */ @@ -46,6 +46,7 @@ import java.util.Spliterator; import java.util.Spliterators; import java.util.TreeMap; import java.util.TreeSet; +import java.util.WeakHashMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; import java.util.function.Supplier; @@ -185,6 +186,11 @@ public class SpliteratorCharacteristics { Spliterator.SIZED | Spliterator.DISTINCT); } + public void testWeakHashMap() { + assertMapCharacteristics(new WeakHashMap<>(), + Spliterator.DISTINCT); + } + public void testHashSet() { assertSetCharacteristics(new HashSet<>(), Spliterator.SIZED | Spliterator.DISTINCT); From 2a5d8d6d8cdf11401312c5fab199abf4825d78fa Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Tue, 1 Oct 2013 17:15:43 +0400 Subject: [PATCH 019/293] 8024707: TransformerException : item() return null with node list of length != 1 Reviewed-by: joehw, lancea --- .../xml/jaxp/parsers/8024707/TestFunc.java | 35 +++++++++++++ .../javax/xml/jaxp/parsers/8024707/XSLT.java | 51 +++++++++++++++++++ .../javax/xml/jaxp/parsers/8024707/in.xml | 4 ++ .../javax/xml/jaxp/parsers/8024707/test.xsl | 10 ++++ 4 files changed, 100 insertions(+) create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/in.xml create mode 100644 jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java b/jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java new file mode 100644 index 00000000000..69f181d7f07 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/TestFunc.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * bug 8024707 + */ + +public class TestFunc { + public static Node test( NodeList list ) { + return list.item(0); + } +} diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java b/jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java new file mode 100644 index 00000000000..e6a03f5af68 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/XSLT.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8024707 + * @summary Test for XSLT extension function with 1 element sized nodelist + * @compile TestFunc.java XSLT.java + * @run main/othervm XSLT + * @author aleksej.efimov@oracle.com + */ + +import javax.xml.transform.*; +import javax.xml.transform.stream.*; +import java.io.ByteArrayOutputStream; + +public class XSLT { + static final String XMLTOTRANSFORM = "/in.xml"; + static final String XSLTRANSFORMER = "/test.xsl"; + static final String EXPECTEDRESULT = "inp1_1"; + + public static void main(String[] args) throws Exception { + ByteArrayOutputStream resStream = new ByteArrayOutputStream(); + TransformerFactory trf = TransformerFactory.newInstance(); + Transformer tr = trf.newTransformer( new StreamSource(System.getProperty("test.src", ".")+XSLTRANSFORMER)); + tr.transform( new StreamSource(System.getProperty("test.src", ".")+XMLTOTRANSFORM), new StreamResult(resStream)); + System.out.println("Transformation completed. Result:"+resStream.toString()); + if (!resStream.toString().equals(EXPECTEDRESULT)) + throw new RuntimeException("Incorrect transformation result"); + } +} diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/in.xml b/jdk/test/javax/xml/jaxp/parsers/8024707/in.xml new file mode 100644 index 00000000000..2cd31165815 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/in.xml @@ -0,0 +1,4 @@ + + +inp1_1 + diff --git a/jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl b/jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl new file mode 100644 index 00000000000..59c506370a9 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/parsers/8024707/test.xsl @@ -0,0 +1,10 @@ + + + + + + From 8fd60ce581a797dc26c2d34da7cbd33b25e5b939 Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Mon, 30 Sep 2013 15:50:06 -0700 Subject: [PATCH 020/293] 7057785: Add note about optional support of recursive methods for self-referential Collection/Map Reviewed-by: scolebourne, darcy, mduigou --- jdk/src/share/classes/java/util/Collection.java | 7 +++++++ jdk/src/share/classes/java/util/Map.java | 15 +++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/util/Collection.java b/jdk/src/share/classes/java/util/Collection.java index 36c7b9d9de1..2ae88727a06 100644 --- a/jdk/src/share/classes/java/util/Collection.java +++ b/jdk/src/share/classes/java/util/Collection.java @@ -104,6 +104,13 @@ import java.util.stream.StreamSupport; * the specified behavior of underlying {@link Object} methods wherever the * implementor deems it appropriate. * + *

Some collection operations which perform recursive traversal of the + * collection may fail with an exception for self-referential instances where + * the collection directly or indirectly contains itself. This includes the + * {@code clone()}, {@code equals()}, {@code hashCode()} and {@code toString()} + * methods. Implementations may optionally handle the self-referential scenario, + * however most current implementations do not do so. + * *

This interface is a member of the * * Java Collections Framework. diff --git a/jdk/src/share/classes/java/util/Map.java b/jdk/src/share/classes/java/util/Map.java index bf1ba8391c8..d1695ef23ee 100644 --- a/jdk/src/share/classes/java/util/Map.java +++ b/jdk/src/share/classes/java/util/Map.java @@ -86,10 +86,6 @@ import java.io.Serializable; * Such exceptions are marked as "optional" in the specification for this * interface. * - *

This interface is a member of the - * - * Java Collections Framework. - * *

Many methods in Collections Framework interfaces are defined * in terms of the {@link Object#equals(Object) equals} method. For * example, the specification for the {@link #containsKey(Object) @@ -107,6 +103,17 @@ import java.io.Serializable; * the specified behavior of underlying {@link Object} methods wherever the * implementor deems it appropriate. * + *

Some map operations which perform recursive traversal of the map may fail + * with an exception for self-referential instances where the map directly or + * indirectly contains itself. This includes the {@code clone()}, + * {@code equals()}, {@code hashCode()} and {@code toString()} methods. + * Implementations may optionally handle the self-referential scenario, however + * most current implementations do not do so. + * + *

This interface is a member of the + * + * Java Collections Framework. + * * @param the type of keys maintained by this map * @param the type of mapped values * From bf7051420838ce8ea89b9419d455622107343a1d Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Tue, 1 Oct 2013 10:23:00 -0700 Subject: [PATCH 021/293] 8025067: Unconditionally throw NPE if null op provided to Arrays.parallelPrefix Reviewed-by: henryjen, chegar, psandoz --- jdk/src/share/classes/java/util/Arrays.java | 8 + jdk/test/java/util/Arrays/ParallelPrefix.java | 146 +++++++++++++++++- 2 files changed, 147 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/util/Arrays.java b/jdk/src/share/classes/java/util/Arrays.java index 47c99ef7f82..43463a5aff6 100644 --- a/jdk/src/share/classes/java/util/Arrays.java +++ b/jdk/src/share/classes/java/util/Arrays.java @@ -1583,6 +1583,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(T[] array, BinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.CumulateTask<> (null, op, array, 0, array.length).invoke(); @@ -1606,6 +1607,7 @@ public class Arrays { */ public static void parallelPrefix(T[] array, int fromIndex, int toIndex, BinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.CumulateTask<> @@ -1627,6 +1629,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(long[] array, LongBinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.LongCumulateTask (null, op, array, 0, array.length).invoke(); @@ -1649,6 +1652,7 @@ public class Arrays { */ public static void parallelPrefix(long[] array, int fromIndex, int toIndex, LongBinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.LongCumulateTask @@ -1673,6 +1677,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(double[] array, DoubleBinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.DoubleCumulateTask (null, op, array, 0, array.length).invoke(); @@ -1695,6 +1700,7 @@ public class Arrays { */ public static void parallelPrefix(double[] array, int fromIndex, int toIndex, DoubleBinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.DoubleCumulateTask @@ -1716,6 +1722,7 @@ public class Arrays { * @since 1.8 */ public static void parallelPrefix(int[] array, IntBinaryOperator op) { + Objects.requireNonNull(op); if (array.length > 0) new ArrayPrefixHelpers.IntCumulateTask (null, op, array, 0, array.length).invoke(); @@ -1738,6 +1745,7 @@ public class Arrays { */ public static void parallelPrefix(int[] array, int fromIndex, int toIndex, IntBinaryOperator op) { + Objects.requireNonNull(op); rangeCheck(array.length, fromIndex, toIndex); if (fromIndex < toIndex) new ArrayPrefixHelpers.IntCumulateTask diff --git a/jdk/test/java/util/Arrays/ParallelPrefix.java b/jdk/test/java/util/Arrays/ParallelPrefix.java index 072de79c42c..8d0d788247a 100644 --- a/jdk/test/java/util/Arrays/ParallelPrefix.java +++ b/jdk/test/java/util/Arrays/ParallelPrefix.java @@ -22,7 +22,7 @@ */ /** - * @test + * @test 8014076 8025067 * @summary unit test for Arrays.ParallelPrefix(). * @author Tristan Yan * @run testng ParallelPrefix @@ -54,30 +54,44 @@ public class ParallelPrefix { private final static int LARGE_ARRAY_SIZE = 1 << 12; private final static int[] ARRAY_SIZE_COLLECTION = new int[]{ - SMALL_ARRAY_SIZE, THRESHOLD_ARRAY_SIZE,MEDIUM_ARRAY_SIZE, LARGE_ARRAY_SIZE}; + SMALL_ARRAY_SIZE, + THRESHOLD_ARRAY_SIZE, + MEDIUM_ARRAY_SIZE, + LARGE_ARRAY_SIZE + }; @DataProvider public static Object[][] intSet(){ - return genericData(size -> IntStream.range(0, size).toArray(), new IntBinaryOperator[]{Integer::sum, Integer::min}); + return genericData(size -> IntStream.range(0, size).toArray(), + new IntBinaryOperator[]{ + Integer::sum, + Integer::min}); } @DataProvider public static Object[][] longSet(){ - return genericData(size -> LongStream.range(0, size).toArray(), new LongBinaryOperator[]{Long::sum, Long::min}); + return genericData(size -> LongStream.range(0, size).toArray(), + new LongBinaryOperator[]{ + Long::sum, + Long::min}); } @DataProvider public static Object[][] doubleSet(){ return genericData(size -> IntStream.range(0, size).mapToDouble(i -> (double)i).toArray(), - new DoubleBinaryOperator[]{Double::sum, Double::min}); + new DoubleBinaryOperator[]{ + Double::sum, + Double::min}); } @DataProvider public static Object[][] stringSet(){ Function stringsFunc = size -> IntStream.range(0, size).mapToObj(Integer::toString).toArray(String[]::new); - BinaryOperator cancatBop = String::concat; - return genericData(stringsFunc, new BinaryOperator[]{cancatBop}); + BinaryOperator concat = String::concat; + return genericData(stringsFunc, + (BinaryOperator[]) new BinaryOperator[]{ + concat }); } private static Object[][] genericData(Function generateFunc, OPS[] ops) { @@ -161,5 +175,123 @@ public class ParallelPrefix { Arrays.parallelPrefix(parallelRangeResult, op); assertEquals(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex)); } + + @Test + public void testNPEs() { + // null array + assertThrows( () -> Arrays.parallelPrefix((int[]) null, Integer::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((long []) null, Long::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((double []) null, Double::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((String []) null, String::concat), + NullPointerException.class, "should throw NPE"); + + // null array w/ range + assertThrows( () -> Arrays.parallelPrefix((int[]) null, 0, 0, Integer::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((long []) null, 0, 0, Long::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((double []) null, 0, 0, Double::max), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix((String []) null, 0, 0, String::concat), + NullPointerException.class, "should throw NPE"); + + // null op + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, null), + NullPointerException.class, "should throw NPE"); + + // null op w/ range + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 0, null), + NullPointerException.class, "should throw NPE"); + } + + @Test + public void testIAEs() { + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 1, 0, Integer::max), + IllegalArgumentException.class, "should throw IAE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 1, 0, Long::max), + IllegalArgumentException.class, "should throw IAE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 1, 0, Double::max), + IllegalArgumentException.class, "should throw IAE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 1, 0, String::concat), + IllegalArgumentException.class, "should throw IAE"); + } + + @Test + public void testAIOBEs() { + // bad "fromIndex" + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, -1, 0, Integer::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, -1, 0, Long::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, -1, 0, Double::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, -1, 0, String::concat), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + + // bad "toIndex" + assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 1, Integer::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 1, Long::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 1, Double::max), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 1, String::concat), + ArrayIndexOutOfBoundsException.class, "should throw AIOBE"); + } + + // "library" code + + public interface Thrower { + + public void run() throws T; + } + + + public static void assertThrows(Thrower thrower, Class throwable) { + assertThrows(thrower, throwable, null); + } + + public static void assertThrows(Thrower thrower, Class throwable, String message) { + Throwable thrown; + try { + thrower.run(); + thrown = null; + } catch (Throwable caught) { + thrown = caught; + } + + assertInstance(thrown, throwable, + ((null != message) ? message : "") + + " Failed to throw " + throwable.getCanonicalName()); + } + + public static void assertThrows(Class throwable, String message, Thrower... throwers) { + for(Thrower thrower : throwers) { + assertThrows(thrower, throwable, message); + } + } + + public static void assertInstance(Object actual, Class expected) { + assertInstance(expected.isInstance(actual), null); + } + + public static void assertInstance(Object actual, Class expected, String message) { + assertTrue(expected.isInstance(actual), message); + } } From 2a3c1e97b2c2625ee66904abb195ece71f41b093 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Tue, 1 Oct 2013 10:37:05 -0700 Subject: [PATCH 022/293] 8025686: Update jdk repo netbeans projects to support NetBeans 7.4 for Java 8 support Reviewed-by: lancea, chegar --- jdk/make/netbeans/common/java-data-native.ent | 4 ++-- jdk/make/netbeans/common/java-data-no-native.ent | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/make/netbeans/common/java-data-native.ent b/jdk/make/netbeans/common/java-data-native.ent index 54c7486aafb..b50ea59afe7 100644 --- a/jdk/make/netbeans/common/java-data-native.ent +++ b/jdk/make/netbeans/common/java-data-native.ent @@ -31,14 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + ${root}/src/share/classes ${root}/src/macosx/classes ${root}/src/solaris/classes ${root}/src/windows/classes ${bootstrap.jdk}/jre/lib/rt.jar - ${root}/build/${platform}-${arch}/classes + ${root}/../build/${platform}-${arch}/jdk/classes ${root}/build/${platform}-${arch}/docs/api 1.8 diff --git a/jdk/make/netbeans/common/java-data-no-native.ent b/jdk/make/netbeans/common/java-data-no-native.ent index 8e06c66c348..882072e0e9c 100644 --- a/jdk/make/netbeans/common/java-data-no-native.ent +++ b/jdk/make/netbeans/common/java-data-no-native.ent @@ -31,11 +31,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + ${root}/src/share/classes ${bootstrap.jdk}/jre/lib/rt.jar - ${root}/build/${platform}-${arch}/classes + ${root}/../build/${platform}-${arch}/jdk/classes ${root}/build/${platform}-${arch}/docs/api 1.8 From b91ee238953c6148264605205a7bab4d7fcc8347 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Mon, 23 Sep 2013 19:51:40 +0400 Subject: [PATCH 023/293] 8001107: @Stable annotation for constant folding of lazily evaluated variables Co-authored-by: John Rose Reviewed-by: twisti, kvn, rbackman --- .../classes/java/lang/invoke/LambdaForm.java | 8 +- .../classes/java/lang/invoke/MethodType.java | 6 +- .../java/lang/invoke/MethodTypeForm.java | 9 ++- .../classes/java/lang/invoke/Stable.java | 73 +++++++++++++++++++ 4 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 jdk/src/share/classes/java/lang/invoke/Stable.java diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java index f5dcf40fd4d..96d83fb4705 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java @@ -120,7 +120,7 @@ import java.util.Objects; class LambdaForm { final int arity; final int result; - final Name[] names; + @Stable final Name[] names; final String debugName; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; @@ -971,8 +971,8 @@ class LambdaForm { static class NamedFunction { final MemberName member; - MethodHandle resolvedHandle; - MethodHandle invoker; + @Stable MethodHandle resolvedHandle; + @Stable MethodHandle invoker; NamedFunction(MethodHandle resolvedHandle) { this(resolvedHandle.internalMemberName(), resolvedHandle); @@ -1267,7 +1267,7 @@ class LambdaForm { final char type; private short index; final NamedFunction function; - final Object[] arguments; + @Stable final Object[] arguments; private Name(int index, char type, NamedFunction function, Object[] arguments) { this.index = (short)index; diff --git a/jdk/src/share/classes/java/lang/invoke/MethodType.java b/jdk/src/share/classes/java/lang/invoke/MethodType.java index f55479f1345..5fc1f377b90 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodType.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java @@ -94,9 +94,9 @@ class MethodType implements java.io.Serializable { private final Class[] ptypes; // The remaining fields are caches of various sorts: - private MethodTypeForm form; // erased form, plus cached data about primitives - private MethodType wrapAlt; // alternative wrapped/unwrapped version - private Invokers invokers; // cache of handy higher-order adapters + private @Stable MethodTypeForm form; // erased form, plus cached data about primitives + private @Stable MethodType wrapAlt; // alternative wrapped/unwrapped version + private @Stable Invokers invokers; // cache of handy higher-order adapters /** * Check the given parameters for validity and store them into the final fields. diff --git a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java index 1106e97baa3..f279035c447 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java @@ -51,12 +51,13 @@ final class MethodTypeForm { final MethodType basicType; // the canonical erasure, with primitives simplified // Cached adapter information: - /*lazy*/ MethodHandle genericInvoker; // JVM hook for inexact invoke - /*lazy*/ MethodHandle basicInvoker; // cached instance of MH.invokeBasic - /*lazy*/ MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction + @Stable String typeString; // argument type signature characters + @Stable MethodHandle genericInvoker; // JVM hook for inexact invoke + @Stable MethodHandle basicInvoker; // cached instance of MH.invokeBasic + @Stable MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction // Cached lambda form information, for basic types only: - final LambdaForm[] lambdaForms; + final @Stable LambdaForm[] lambdaForms; // Indexes into lambdaForms: static final int LF_INVVIRTUAL = 0, // DMH invokeVirtual diff --git a/jdk/src/share/classes/java/lang/invoke/Stable.java b/jdk/src/share/classes/java/lang/invoke/Stable.java new file mode 100644 index 00000000000..67a3b4fb67a --- /dev/null +++ b/jdk/src/share/classes/java/lang/invoke/Stable.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.invoke; + +import java.lang.annotation.*; + +/** + * A field may be annotated as stable if all of its component variables + * changes value at most once. + * A field's value counts as its component value. + * If the field is typed as an array, then all the non-null components + * of the array, of depth up to the rank of the field's array type, + * also count as component values. + * By extension, any variable (either array or field) which has annotated + * as stable is called a stable variable, and its non-null or non-zero + * value is called a stable value. + *

+ * Since all fields begin with a default value of null for references + * (resp., zero for primitives), it follows that this annotation indicates + * that the first non-null (resp., non-zero) value stored in the field + * will never be changed. + *

+ * If the field is not of an array type, there are no array elements, + * then the value indicated as stable is simply the value of the field. + * If the dynamic type of the field value is an array but the static type + * is not, the components of the array are not regarded as stable. + *

+ * If the field is an array type, then both the field value and + * all the components of the field value (if the field value is non-null) + * are indicated to be stable. + * If the field type is an array type with rank {@code N > 1}, + * then each component of the field value (if the field value is non-null), + * is regarded as a stable array of rank {@code N-1}. + *

+ * Fields which are declared {@code final} may also be annotated as stable. + * Since final fields already behave as stable values, such an annotation + * indicates no additional information, unless the type of the field is + * an array type. + *

+ * It is (currently) undefined what happens if a field annotated as stable + * is given a third value. In practice, if the JVM relies on this annotation + * to promote a field reference to a constant, it may be that the Java memory + * model would appear to be broken, if such a constant (the second value of the field) + * is used as the value of the field even after the field value has changed. + */ +/* package-private */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@interface Stable { +} From 8e924e70a6cea5014feb17e6065c485153157ba8 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 18 Sep 2013 20:12:05 +0400 Subject: [PATCH 024/293] 8024616: JSR292: lazily initialize core NamedFunctions used for bootstrapping Reviewed-by: jrose --- .../java/lang/invoke/DirectMethodHandle.java | 110 +++++++++--------- .../java/lang/invoke/MethodHandleImpl.java | 24 ++-- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java index b9c10d827d2..9c054519b43 100644 --- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -257,12 +257,12 @@ class DirectMethodHandle extends MethodHandle { assert(names.length == nameCursor); if (doesAlloc) { // names = { argx,y,z,... new C, init method } - names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]); - names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]); + names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]); } else if (needsInit) { - names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]); } else { - names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]); } Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class); assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args! @@ -637,18 +637,18 @@ class DirectMethodHandle extends MethodHandle { final int RESULT = nameCursor-1; // either the call or the cast Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); if (needsInit) - names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]); + names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]); if (needsCast && !isGetter) - names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); + names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]); Object[] outArgs = new Object[1 + linkerType.parameterCount()]; assert(outArgs.length == (isGetter ? 3 : 4)); outArgs[0] = UNSAFE; if (isStatic) { - outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); - outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); + outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]); } else { - outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]); - outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]); + outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]); } if (!isGetter) { outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); @@ -656,7 +656,7 @@ class DirectMethodHandle extends MethodHandle { for (Object a : outArgs) assert(a != null); names[LINKER_CALL] = new Name(linker, outArgs); if (needsCast && isGetter) - names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); + names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); for (Name n : names) assert(n != null); String fieldOrStatic = (isStatic ? "Static" : "Field"); String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging @@ -665,48 +665,54 @@ class DirectMethodHandle extends MethodHandle { return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); } - private static final NamedFunction - NF_internalMemberName, - NF_internalMemberNameEnsureInit, - NF_ensureInitialized, - NF_fieldOffset, - NF_checkBase, - NF_staticBase, - NF_staticOffset, - NF_checkCast, - NF_allocateInstance, - NF_constructorMethod; - static { - try { - NamedFunction nfs[] = { - NF_internalMemberName = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberName", Object.class)), - NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), - NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("ensureInitialized", Object.class)), - NF_fieldOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("fieldOffset", Object.class)), - NF_checkBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkBase", Object.class)), - NF_staticBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticBase", Object.class)), - NF_staticOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticOffset", Object.class)), - NF_checkCast = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkCast", Object.class, Object.class)), - NF_allocateInstance = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("allocateInstance", Object.class)), - NF_constructorMethod = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("constructorMethod", Object.class)) - }; - for (NamedFunction nf : nfs) { - // Each nf must be statically invocable or we get tied up in our bootstraps. - assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; - nf.resolve(); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction + NF_internalMemberName, + NF_internalMemberNameEnsureInit, + NF_ensureInitialized, + NF_fieldOffset, + NF_checkBase, + NF_staticBase, + NF_staticOffset, + NF_checkCast, + NF_allocateInstance, + NF_constructorMethod; + static { + try { + NamedFunction nfs[] = { + NF_internalMemberName = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberName", Object.class)), + NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), + NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("ensureInitialized", Object.class)), + NF_fieldOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("fieldOffset", Object.class)), + NF_checkBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkBase", Object.class)), + NF_staticBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticBase", Object.class)), + NF_staticOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticOffset", Object.class)), + NF_checkCast = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkCast", Object.class, Object.class)), + NF_allocateInstance = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("allocateInstance", Object.class)), + NF_constructorMethod = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("constructorMethod", Object.class)) + }; + for (NamedFunction nf : nfs) { + // Each nf must be statically invocable or we get tied up in our bootstraps. + assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; + nf.resolve(); + } + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); } - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); } } } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index 5ab7f7adb7b..6918fec1cca 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -435,7 +435,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; // Spread the array. MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType); Name array = names[argIndex]; - names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount); + names[nameCursor++] = new Name(Lazy.NF_checkSpreadArgument, array, spreadArgCount); for (int j = 0; j < spreadArgCount; i++, j++) { indexes[i] = nameCursor; names[nameCursor++] = new Name(aload, array, j); @@ -480,14 +480,20 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; throw new WrongMethodTypeException("Array is not of length "+n); } - private static final NamedFunction NF_checkSpreadArgument; - static { - try { - NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class - .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); - NF_checkSpreadArgument.resolve(); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction NF_checkSpreadArgument; + static { + try { + NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class + .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); + NF_checkSpreadArgument.resolve(); + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); + } } } From e92da66e0bb1c49f306b9d644f23b7e16a20f342 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Tue, 1 Oct 2013 17:35:32 -0400 Subject: [PATCH 025/293] 8021398: j.l.r.Parameter.getAnnotatedType().getType() for not annotated use of type returns null Fixed issue with type annotation reflection framework that would cause getType of AnnotatedTypes to be null if no annotations were present. Reviewed-by: darcy, jfranck --- .../annotation/TypeAnnotationParser.java | 16 +++++--- .../Parameter/GetAnnotatedTypeTest.java | 39 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 jdk/test/java/lang/reflect/Parameter/GetAnnotatedTypeTest.java diff --git a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java index 12fa1fa687b..bcf48ffe632 100644 --- a/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java +++ b/jdk/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java @@ -128,14 +128,18 @@ public class TypeAnnotationParser { for (int i = 0; i < size; i++) { @SuppressWarnings("unchecked") ArrayList list = l[i]; + TypeAnnotation[] typeAnnotations; if (list != null) { - TypeAnnotation[] typeAnnotations = list.toArray(new TypeAnnotation[0]); - result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i], - LocationInfo.BASE_LOCATION, - typeAnnotations, - typeAnnotations, - decl); + typeAnnotations = list.toArray(new TypeAnnotation[list.size()]); + } else { + typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY; } + result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i], + LocationInfo.BASE_LOCATION, + typeAnnotations, + typeAnnotations, + decl); + } return result; } diff --git a/jdk/test/java/lang/reflect/Parameter/GetAnnotatedTypeTest.java b/jdk/test/java/lang/reflect/Parameter/GetAnnotatedTypeTest.java new file mode 100644 index 00000000000..2fcf0b8926e --- /dev/null +++ b/jdk/test/java/lang/reflect/Parameter/GetAnnotatedTypeTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @compile -parameters GetAnnotatedTypeTest.java + * @run main GetAnnotatedTypeTest + * @summary javac should generate method parameters correctly. + */ + +public class GetAnnotatedTypeTest { + + public void meth(Object param) {} + + public static void main(String[] args) throws NoSuchMethodException { + if (GetAnnotatedTypeTest.class.getMethod("meth", Object.class).getParameters()[0].getAnnotatedType().getType() != Object.class) + throw new RuntimeException("Parameter did not have the expected annotated type"); + } +} From de7eca4a3977eece06600f9f8755f14684903df9 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Tue, 1 Oct 2013 15:40:34 -0700 Subject: [PATCH 026/293] 8025342: NLS: unsupported translation format in jar/pack/DriverResource.java Reviewed-by: naoto, mfang --- .../com/sun/java/util/jar/pack/Driver.java | 4 +- .../java/util/jar/pack/DriverResource.java | 187 +++++++++--------- 2 files changed, 90 insertions(+), 101 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java index 7ecbca05ef2..c0393d3de4a 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -303,7 +303,7 @@ class Driver { } else { if (!packfile.toLowerCase().endsWith(".pack") && !packfile.toLowerCase().endsWith(".pac")) { - System.err.println(MessageFormat.format(RESOURCE.getString(DriverResource.WIRTE_PACKGZ_FILE),packfile)); + System.err.println(MessageFormat.format(RESOURCE.getString(DriverResource.WRITE_PACKGZ_FILE),packfile)); printUsage(doPack, false, System.err); System.exit(2); } diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java index 050f8d7a263..48a01223720 100644 --- a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,110 +22,99 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package com.sun.java.util.jar.pack; import java.util.ListResourceBundle; public class DriverResource extends ListResourceBundle { - public static final String VERSION ="VERSION"; - public static final String BAD_ARGUMENT ="BAD_ARGUMENT"; - public static final String BAD_OPTION ="BAD_OPTION"; - public static final String BAD_REPACK_OUTPUT="BAD_REPACK_OUTPUT"; - public static final String DETECTED_ZIP_COMMENT="DETECTED_ZIP_COMMENT"; - public static final String SKIP_FOR_REPACKED ="SKIP_FOR_REPACKED"; - public static final String WRITE_PACK_FILE ="WRITE_PACK_FILE"; - public static final String WIRTE_PACKGZ_FILE="WIRTE_PACKGZ_FILE"; - public static final String SKIP_FOR_MOVE_FAILED="SKIP_FOR_MOVE_FAILED"; - public static final String PACK_HELP="PACK_HELP"; - public static final String UNPACK_HELP ="UNPACK_HELP"; - public static final String MORE_INFO = "MORE_INFO"; - public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; - public static final String BAD_SPEC = "BAD_SPEC"; - //The following string is duplicate in PACK and UNPACK comment,which was draw out to ruduce translation work. - private static final String PARAMETER_V = " -v, --verbose increase program verbosity"; - private static final String PARAMETER_Q = " -q, --quiet set verbosity to lowest level"; - private static final String PARAMETER_LF = " -l{F}, --log-file={F} output to the given log file, or '-' for System.out"; - private static final String PARAMETER_H = " -?, -h, --help print this message"; - private static final String PARAMETER_VER = " -V, --version print program version"; - private static final String PARAMETER_J = " -J{X} pass option X to underlying Java VM"; - - - //The following are outputs of command 'pack200' and 'unpack200'. - //Don't translate command arguments ,words with a prefix of '-' or '--'. - // - private static final Object[][] resource= { - {VERSION,"{0} version {1}"},//parameter 0:class name;parameter 1: version value - {BAD_ARGUMENT,"Bad argument: {0}"}, - {BAD_OPTION,"Bad option: {0}={1}"},//parameter 0:option name;parameter 1:option value - {BAD_REPACK_OUTPUT,"Bad --repack output: {0}"},//parameter 0:filename - {DETECTED_ZIP_COMMENT,"Detected ZIP comment: {0}"},//parameter 0:comment - {SKIP_FOR_REPACKED,"Skipping because already repacked: {0}"},//parameter 0:filename - {WRITE_PACK_FILE,"To write a *.pack file, specify --no-gzip: {0}"},//parameter 0:filename - {WIRTE_PACKGZ_FILE,"To write a *.pack.gz file, specify --gzip: {0}"},//parameter 0:filename - {SKIP_FOR_MOVE_FAILED,"Skipping unpack because move failed: {0}"},//parameter 0:filename - {PACK_HELP,new String[]{ - "Usage: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", - "", - "Packing Options", - " -g, --no-gzip output a plain *.pack file with no zipping", - " --gzip (default) post-process the pack output with gzip", - " -G, --strip-debug remove debugging attributes while packing", - " -O, --no-keep-file-order do not transmit file ordering information", - " --keep-file-order (default) preserve input file ordering", - " -S{N}, --segment-limit={N} output segment limit (default N=1Mb)", - " -E{N}, --effort={N} packing effort (default N=5)", - " -H{h}, --deflate-hint={h} transmit deflate hint: true, false, or keep (default)", - " -m{V}, --modification-time={V} transmit modtimes: latest or keep (default)", - " -P{F}, --pass-file={F} transmit the given input element(s) uncompressed", - " -U{a}, --unknown-attribute={a} unknown attribute action: error, strip, or pass (default)", - " -C{N}={L}, --class-attribute={N}={L} (user-defined attribute)", - " -F{N}={L}, --field-attribute={N}={L} (user-defined attribute)", - " -M{N}={L}, --method-attribute={N}={L} (user-defined attribute)", - " -D{N}={L}, --code-attribute={N}={L} (user-defined attribute)", - " -f{F}, --config-file={F} read file F for Pack200.Packer properties", - PARAMETER_V , - PARAMETER_Q , - PARAMETER_LF , - PARAMETER_H , - PARAMETER_VER , - PARAMETER_J, - "", - "Notes:", - " The -P, -C, -F, -M, and -D options accumulate.", - " Example attribute definition: -C SourceFile=RUH .", - " Config. file properties are defined by the Pack200 API.", - " For meaning of -S, -E, -H-, -m, -U values, see Pack200 API.", - " Layout definitions (like RUH) are defined by JSR 200.", - "", - "Repacking mode updates the JAR file with a pack/unpack cycle:", - " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" - } - }, - {UNPACK_HELP,new String[]{ - "Usage: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", - "", - "Unpacking Options", - " -H{h}, --deflate-hint={h} override transmitted deflate hint: true, false, or keep (default)", - " -r, --remove-pack-file remove input file after unpacking", - PARAMETER_V , - PARAMETER_Q , - PARAMETER_LF , - PARAMETER_H , - PARAMETER_VER , - PARAMETER_J, - } - }, - - {MORE_INFO,"(For more information, run {0} --help .)"},//parameter 0:command name - {DUPLICATE_OPTION,"duplicate option: {0}"},//parameter 0:option - {BAD_SPEC,"bad spec for {0}: {1}"},//parameter 0:option;parameter 1:specifier - }; - - protected Object[][] getContents() { - return resource; - } + public static final String VERSION = "VERSION"; + public static final String BAD_ARGUMENT = "BAD_ARGUMENT"; + public static final String BAD_OPTION = "BAD_OPTION"; + public static final String BAD_REPACK_OUTPUT = "BAD_REPACK_OUTPUT"; + public static final String DETECTED_ZIP_COMMENT = "DETECTED_ZIP_COMMENT"; + public static final String SKIP_FOR_REPACKED = "SKIP_FOR_REPACKED"; + public static final String WRITE_PACK_FILE = "WRITE_PACK_FILE"; + public static final String WRITE_PACKGZ_FILE = "WRITE_PACKGZ_FILE"; + public static final String SKIP_FOR_MOVE_FAILED = "SKIP_FOR_MOVE_FAILED"; + public static final String PACK_HELP = "PACK_HELP"; + public static final String UNPACK_HELP = "UNPACK_HELP"; + public static final String MORE_INFO = "MORE_INFO"; + public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; + public static final String BAD_SPEC = "BAD_SPEC"; + /* + * The following are the output of 'pack200' and 'unpack200' commands. + * Do not translate command arguments and words with a prefix of '-' or '--'. + */ + private static final Object[][] resource = { + {VERSION, "{0} version {1}"}, // parameter 0:class name;parameter 1: version value + {BAD_ARGUMENT, "Bad argument: {0}"}, + {BAD_OPTION, "Bad option: {0}={1}"}, // parameter 0:option name;parameter 1:option value + {BAD_REPACK_OUTPUT, "Bad --repack output: {0}"}, // parameter 0:filename + {DETECTED_ZIP_COMMENT, "Detected ZIP comment: {0}"}, // parameter 0:comment + {SKIP_FOR_REPACKED, "Skipping because already repacked: {0}"}, // parameter 0:filename + {WRITE_PACK_FILE, "To write a *.pack file, specify --no-gzip: {0}"}, // parameter 0:filename + {WRITE_PACKGZ_FILE, "To write a *.pack.gz file, specify --gzip: {0}"}, // parameter 0:filename + {SKIP_FOR_MOVE_FAILED, "Skipping unpack because move failed: {0}"}, // parameter 0:filename + {PACK_HELP, new String[] { + "Usage: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", + "", + "Packing Options", + " -g, --no-gzip output a plain *.pack file with no zipping", + " --gzip (default) post-process the pack output with gzip", + " -G, --strip-debug remove debugging attributes while packing", + " -O, --no-keep-file-order do not transmit file ordering information", + " --keep-file-order (default) preserve input file ordering", + " -S{N}, --segment-limit={N} output segment limit (default N=1Mb)", + " -E{N}, --effort={N} packing effort (default N=5)", + " -H{h}, --deflate-hint={h} transmit deflate hint: true, false, or keep (default)", + " -m{V}, --modification-time={V} transmit modtimes: latest or keep (default)", + " -P{F}, --pass-file={F} transmit the given input element(s) uncompressed", + " -U{a}, --unknown-attribute={a} unknown attribute action: error, strip, or pass (default)", + " -C{N}={L}, --class-attribute={N}={L} (user-defined attribute)", + " -F{N}={L}, --field-attribute={N}={L} (user-defined attribute)", + " -M{N}={L}, --method-attribute={N}={L} (user-defined attribute)", + " -D{N}={L}, --code-attribute={N}={L} (user-defined attribute)", + " -f{F}, --config-file={F} read file F for Pack200.Packer properties", + " -v, --verbose increase program verbosity", + " -q, --quiet set verbosity to lowest level", + " -l{F}, --log-file={F} output to the given log file, or '-' for System.out", + " -?, -h, --help print this message", + " -V, --version print program version", + " -J{X} pass option X to underlying Java VM", + "", + "Notes:", + " The -P, -C, -F, -M, and -D options accumulate.", + " Example attribute definition: -C SourceFile=RUH .", + " Config. file properties are defined by the Pack200 API.", + " For meaning of -S, -E, -H-, -m, -U values, see Pack200 API.", + " Layout definitions (like RUH) are defined by JSR 200.", + "", + "Repacking mode updates the JAR file with a pack/unpack cycle:", + " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" + } + }, + {UNPACK_HELP, new String[] { + "Usage: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", + "", + "Unpacking Options", + " -H{h}, --deflate-hint={h} override transmitted deflate hint: true, false, or keep (default)", + " -r, --remove-pack-file remove input file after unpacking", + " -v, --verbose increase program verbosity", + " -q, --quiet set verbosity to lowest level", + " -l{F}, --log-file={F} output to the given log file, or '-' for System.out", + " -?, -h, --help print this message", + " -V, --version print program version", + " -J{X} pass option X to underlying Java VM" + } + }, + {MORE_INFO, "(For more information, run {0} --help .)"}, // parameter 0:command name + {DUPLICATE_OPTION, "duplicate option: {0}"}, // parameter 0:option + {BAD_SPEC, "bad spec for {0}: {1}"}, // parameter 0:option;parameter 1:specifier + }; + protected Object[][] getContents() { + return resource; + } } From fdf6a159f59a577dbfc2b8ac379d5817d990f790 Mon Sep 17 00:00:00 2001 From: David Chase Date: Fri, 27 Sep 2013 13:32:32 -0400 Subject: [PATCH 027/293] 8022701: Accessibility checking: InvocationTargetException is thrown instead of IllegalAccessError Inserted code to convert specific exceptions, case-by-case, plus a test. Reviewed-by: jrose, twisti --- .../java/lang/invoke/MethodHandleNatives.java | 26 ++- .../java/lang/invoke/8022701/BogoLoader.java | 156 ++++++++++++++++++ .../invoke/8022701/InvokeSeveralWays.java | 106 ++++++++++++ .../java/lang/invoke/8022701/Invoker.java | 45 +++++ .../lang/invoke/8022701/MHIllegalAccess.java | 120 ++++++++++++++ .../lang/invoke/8022701/MethodSupplier.java | 36 ++++ 6 files changed, 486 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/lang/invoke/8022701/BogoLoader.java create mode 100644 jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java create mode 100644 jdk/test/java/lang/invoke/8022701/Invoker.java create mode 100644 jdk/test/java/lang/invoke/8022701/MHIllegalAccess.java create mode 100644 jdk/test/java/lang/invoke/8022701/MethodSupplier.java diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java index 4f83e82158c..9a71299a031 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -440,13 +440,33 @@ class MethodHandleNatives { Lookup lookup = IMPL_LOOKUP.in(callerClass); assert(refKindIsValid(refKind)); return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type); + } catch (IllegalAccessException ex) { + Error err = new IllegalAccessError(ex.getMessage()); + throw initCauseFrom(err, ex); + } catch (NoSuchMethodException ex) { + Error err = new NoSuchMethodError(ex.getMessage()); + throw initCauseFrom(err, ex); + } catch (NoSuchFieldException ex) { + Error err = new NoSuchFieldError(ex.getMessage()); + throw initCauseFrom(err, ex); } catch (ReflectiveOperationException ex) { Error err = new IncompatibleClassChangeError(); - err.initCause(ex); - throw err; + throw initCauseFrom(err, ex); } } + /** + * Use best possible cause for err.initCause(), substituting the + * cause for err itself if the cause has the same (or better) type. + */ + static private Error initCauseFrom(Error err, Exception ex) { + Throwable th = ex.getCause(); + if (err.getClass().isInstance(th)) + return (Error) th; + err.initCause(th == null ? ex : th); + return err; + } + /** * Is this method a caller-sensitive method? * I.e., does it call Reflection.getCallerClass or a similer method diff --git a/jdk/test/java/lang/invoke/8022701/BogoLoader.java b/jdk/test/java/lang/invoke/8022701/BogoLoader.java new file mode 100644 index 00000000000..e77be6f44ff --- /dev/null +++ b/jdk/test/java/lang/invoke/8022701/BogoLoader.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Set; +import java.util.Vector; +import jdk.internal.org.objectweb.asm.*; + +public class BogoLoader extends ClassLoader { + + static interface VisitorMaker { + ClassVisitor make(ClassVisitor visitor); + } + + + /** + * Use this property to verify that the desired classloading is happening. + */ + private final boolean verbose = Boolean.getBoolean("bogoloader.verbose"); + /** + * Use this property to disable replacement for testing purposes. + */ + private final boolean noReplace = Boolean.getBoolean("bogoloader.noreplace"); + + /** + * Set of class names that should be loaded with this loader. + * Others are loaded with the system class loader, except for those + * that are transformed. + */ + private Set nonSystem; + + /** + * Map from class names to a bytecode transformer factory. + */ + private Map replaced; + + /** + * Keep track (not terribly efficiently) of which classes have already + * been loaded by this class loader. + */ + private final Vector history = new Vector(); + + private boolean useSystemLoader(String name) { + return ! nonSystem.contains(name) && ! replaced.containsKey(name); + } + + public BogoLoader(Set non_system, Map replaced) { + super(Thread.currentThread().getContextClassLoader()); + this.nonSystem = non_system; + this.replaced = replaced; + } + + private byte[] readResource(String className) throws IOException { + return readResource(className, "class"); + } + + private byte[] readResource(String className, String suffix) throws IOException { + // Note to the unwary -- "/" works on Windows, leave it alone. + String fileName = className.replace('.', '/') + "." + suffix; + InputStream origStream = getResourceAsStream(fileName); + if (origStream == null) { + throw new IOException("Resource not found : " + fileName); + } + BufferedInputStream stream = new java.io.BufferedInputStream(origStream); + byte[] data = new byte[stream.available()]; + int how_many = stream.read(data); + // Really ought to deal with the corner cases of stream.available() + return data; + } + + protected byte[] getClass(String name) throws ClassNotFoundException, + IOException { + return readResource(name, "class"); + } + + /** + * Loads the named class from the system class loader unless + * the name appears in either replaced or nonSystem. + * nonSystem classes are loaded into this classloader, + * and replaced classes get their content from the specified array + * of bytes (and are also loaded into this classloader). + */ + protected Class loadClass(String name, boolean resolve) + throws ClassNotFoundException { + Class clazz; + + if (history.contains(name)) { + Class c = this.findLoadedClass(name); + return c; + } + if (useSystemLoader(name)) { + clazz = findSystemClass(name); + if (verbose) System.err.println("Loading system class " + name); + } else { + history.add(name); + try { + if (verbose) { + System.err.println("Loading classloader class " + name); + } + byte[] classData = getClass(name);; + boolean expanded = false; + if (!noReplace && replaced.containsKey(name)) { + if (verbose) { + System.err.println("Replacing class " + name); + } + ClassReader cr = new ClassReader(classData); + ClassWriter cw = new ClassWriter(0); + VisitorMaker vm = replaced.get(name); + cr.accept(vm.make(cw), 0); + classData = cw.toByteArray(); + } + clazz = defineClass(name, classData, 0, classData.length); + } catch (java.io.EOFException ioe) { + throw new ClassNotFoundException( + "IO Exception in reading class : " + name + " ", ioe); + } catch (ClassFormatError ioe) { + throw new ClassNotFoundException( + "ClassFormatError in reading class file: ", ioe); + } catch (IOException ioe) { + throw new ClassNotFoundException( + "IO Exception in reading class file: ", ioe); + } + } + if (clazz == null) { + throw new ClassNotFoundException(name); + } + if (resolve) { + resolveClass(clazz); + } + return clazz; + } +} diff --git a/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java b/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java new file mode 100644 index 00000000000..a5099dd60c5 --- /dev/null +++ b/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.lang.reflect.InvocationTargetException; + +/** + * Tries various ways of ultimately invoking MethodSupplier.m(), + * except that m has been made inaccessible and some exception should be + * thrown instead. + */ +public class InvokeSeveralWays { + public static int test(String args[], Class expected) throws Exception { + int failures = 0; + try { + Class.forName("Invoker").getMethod("invoke").invoke(null); + System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier"); + failures++; + } catch (InvocationTargetException e) { + Throwable c = e.getCause(); + if (expected.isInstance(c)) + System.out.println("EXPECTED: " + expected.getName() + ", "+ c); + else { + failures++; + System.out.println("FAIL: Unexpected wrapped exception " + c); + e.printStackTrace(System.out); + } + } catch (Throwable e) { + failures++; + System.out.println("FAIL: Unexpected exception has been caught " + e); + e.printStackTrace(System.out); + } + System.out.println(); + try { + Class.forName("Invoker").getMethod("invoke2").invoke(null); + System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier"); + failures++; + } catch (InvocationTargetException e) { + Throwable c = e.getCause(); + if (expected.isInstance(c)) + System.out.println("EXPECTED: " + expected.getName() + ", "+ c); + else { + failures++; + System.out.println("FAIL: Unexpected wrapped exception " + c); + e.printStackTrace(System.out); + } + } catch (Throwable e) { + failures++; + System.out.println("FAIL: Unexpected exception has been caught " + e); + e.printStackTrace(System.out); + } + System.out.println(); + try { + Invoker.invoke(); + System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier"); + failures++; + } catch (Throwable e) { + if (expected.isInstance(e)) + System.out.println("EXPECTED: " + expected.getName() + ", "+ e); + else { + failures++; + System.out.println("FAIL: Unexpected exception has been caught " + e); + e.printStackTrace(System.out); + } + } + System.out.println(); + try { + Invoker.invoke2(); + System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier"); + failures++; + } catch (Throwable e) { + if (expected.isInstance(e)) + System.out.println("EXPECTED: " + expected.getName() + ", "+ e); + else { + failures++; + System.out.println("FAIL: Unexpected exception has been caught " + e); + e.printStackTrace(System.out); + } + } + System.out.println(); + if (failures > 0) { + System.out.println("Saw " + failures + " failures"); + } + return failures; + } +} diff --git a/jdk/test/java/lang/invoke/8022701/Invoker.java b/jdk/test/java/lang/invoke/8022701/Invoker.java new file mode 100644 index 00000000000..a97159e9e29 --- /dev/null +++ b/jdk/test/java/lang/invoke/8022701/Invoker.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +public class Invoker { + /** + * Use a method handle to invoke m. + */ + public static void invoke() { + MyFunctionalInterface fi = null; + fi = new MethodSupplier()::m; + fi.invokeMethodReference(); + } + /** + * Invoke m directly. + */ + public static void invoke2() { + MethodSupplier ms = new MethodSupplier(); + ms.m(); + } +} + +interface MyFunctionalInterface { + void invokeMethodReference(); +} diff --git a/jdk/test/java/lang/invoke/8022701/MHIllegalAccess.java b/jdk/test/java/lang/invoke/8022701/MHIllegalAccess.java new file mode 100644 index 00000000000..44aa9c98253 --- /dev/null +++ b/jdk/test/java/lang/invoke/8022701/MHIllegalAccess.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8022701 + * @summary Illegal access exceptions via methodhandle invocations threw wrong error. + * + * @compile -XDignore.symbol.file BogoLoader.java InvokeSeveralWays.java MHIllegalAccess.java MethodSupplier.java + * @run main/othervm MHIllegalAccess + */ + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.HashSet; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; + +public class MHIllegalAccess implements Opcodes { + + public static void main(String args[]) throws Throwable { + System.out.println("Classpath is " + System.getProperty("java.class.path")); + System.out.println(); + + /** + * Make method m be private to provoke an IllegalAccessError. + */ + BogoLoader.VisitorMaker privatize = new BogoLoader.VisitorMaker() { + public ClassVisitor make(ClassVisitor cv) { + return new ClassVisitor(Opcodes.ASM5, cv) { + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + if (name.equals("m")) + access = (access | ACC_PRIVATE) & ~ (ACC_PUBLIC | ACC_PROTECTED); + return super.visitMethod(access, name, desc, signature, exceptions); + } + }; + } + }; + + /** + * Rename method m as nemo to provoke a NoSuchMethodError. + */ + BogoLoader.VisitorMaker changeName = new BogoLoader.VisitorMaker() { + public ClassVisitor make(ClassVisitor cv) { + return new ClassVisitor(Opcodes.ASM5, cv) { + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + if (name.equals("m")) + name = "nemo"; + return super.visitMethod(access, name, desc, signature, exceptions); + } + }; + } + }; + + int failures = 0; + failures += testOneError(privatize, args, IllegalAccessError.class); + failures += testOneError(changeName, args, NoSuchMethodError.class); + if (failures > 0) { + System.out.println("Saw " + failures + " failures, see standard out for details"); + throw new Error("FAIL test"); + } + } + + /** + * + * @param vm VisitorMaker, to be stored in a table and passed to a BogoLoader + * @param args A copy of the main args, to be passed on to InvokeSeveralWays.test + * @param expected The class of the exception that should be thrown after + * attempted invocation of MethodSupplier.m. + * @throws ClassNotFoundException + * @throws Throwable + */ + private static int testOneError(BogoLoader.VisitorMaker vm, String[] args, Class expected) throws ClassNotFoundException, Throwable { + HashMap replace = new HashMap(); + replace.put("MethodSupplier", vm); + + HashSet in_bogus = new HashSet(); + in_bogus.add("InvokeSeveralWays"); + in_bogus.add("MyFunctionalInterface"); + in_bogus.add("Invoker"); + + BogoLoader bl = new BogoLoader(in_bogus, replace); + Class isw = bl.loadClass("InvokeSeveralWays"); + Object[] arg_for_args = new Object[2]; + arg_for_args[0] = args; + arg_for_args[1] = expected; + try { + Object result = isw.getMethod("test", String[].class, Class.class).invoke(null, arg_for_args); + return (Integer)result; + } catch (InvocationTargetException e) { + Throwable th = e.getCause(); + throw th == null ? e : th; + } + } +} diff --git a/jdk/test/java/lang/invoke/8022701/MethodSupplier.java b/jdk/test/java/lang/invoke/8022701/MethodSupplier.java new file mode 100644 index 00000000000..4699a52aaff --- /dev/null +++ b/jdk/test/java/lang/invoke/8022701/MethodSupplier.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * Note: this class is only used in this form to facilitate compilation of the + * rest of the code. Before execution, the bytecodes are mutilated in a + * BogoLoader to either make m be private or have a different name. + */ + +public class MethodSupplier { + public void m() { + System.out.println("good"); + } +} + From 54ebd8d42e1bf15909994e505cfe56d0b157360c Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Tue, 1 Oct 2013 20:25:44 -0700 Subject: [PATCH 028/293] 8025123: SNI support in Kerberos cipher suites Reviewed-by: weijun, xuelei --- .../sun/security/ssl/ClientHandshaker.java | 56 +++++++++++++++---- .../classes/sun/security/ssl/Handshaker.java | 8 --- .../ssl/KerberosClientKeyExchange.java | 8 +-- .../krb5/KerberosClientKeyExchangeImpl.java | 34 ++++++----- jdk/test/sun/security/krb5/auto/SSL.java | 54 +++++++++++++----- 5 files changed, 112 insertions(+), 48 deletions(-) diff --git a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java index 459a0aed7f8..5c3abbcdab5 100644 --- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java +++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,6 +92,8 @@ final class ClientHandshaker extends Handshaker { private List requestedServerNames = Collections.emptyList(); + private boolean serverNamesAccepted = false; + /* * Constructors */ @@ -567,7 +569,9 @@ final class ClientHandshaker extends Handshaker { // check extensions for (HelloExtension ext : mesg.extensions.list()) { ExtensionType type = ext.type; - if ((type != ExtensionType.EXT_ELLIPTIC_CURVES) + if (type == ExtensionType.EXT_SERVER_NAME) { + serverNamesAccepted = true; + } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES) && (type != ExtensionType.EXT_EC_POINT_FORMATS) && (type != ExtensionType.EXT_SERVER_NAME) && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) { @@ -864,15 +868,47 @@ final class ClientHandshaker extends Handshaker { break; case K_KRB5: case K_KRB5_EXPORT: - String hostname = getHostSE(); - if (hostname == null) { - throw new IOException("Hostname is required" + - " to use Kerberos cipher suites"); + String sniHostname = null; + for (SNIServerName serverName : requestedServerNames) { + if (serverName instanceof SNIHostName) { + sniHostname = ((SNIHostName) serverName).getAsciiName(); + break; + } } - KerberosClientKeyExchange kerberosMsg = - new KerberosClientKeyExchange( - hostname, isLoopbackSE(), getAccSE(), protocolVersion, - sslContext.getSecureRandom()); + + KerberosClientKeyExchange kerberosMsg = null; + if (sniHostname != null) { + // use first requested SNI hostname + try { + kerberosMsg = new KerberosClientKeyExchange( + sniHostname, getAccSE(), protocolVersion, + sslContext.getSecureRandom()); + } catch(IOException e) { + if (serverNamesAccepted) { + // server accepted requested SNI hostname, + // so it must be used + throw e; + } + // fallback to using hostname + if (debug != null && Debug.isOn("handshake")) { + System.out.println( + "Warning, cannot use Server Name Indication: " + + e.getMessage()); + } + } + } + + if (kerberosMsg == null) { + String hostname = getHostSE(); + if (hostname == null) { + throw new IOException("Hostname is required" + + " to use Kerberos cipher suites"); + } + kerberosMsg = new KerberosClientKeyExchange( + hostname, getAccSE(), protocolVersion, + sslContext.getSecureRandom()); + } + // Record the principals involved in exchange session.setPeerPrincipal(kerberosMsg.getPeerPrincipal()); session.setLocalPrincipal(kerberosMsg.getLocalPrincipal()); diff --git a/jdk/src/share/classes/sun/security/ssl/Handshaker.java b/jdk/src/share/classes/sun/security/ssl/Handshaker.java index a92320451e0..7fde1d22ef6 100644 --- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java +++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java @@ -335,14 +335,6 @@ abstract class Handshaker { } } - boolean isLoopbackSE() { - if (conn != null) { - return conn.getInetAddress().isLoopbackAddress(); - } else { - return false; - } - } - int getPortSE() { if (conn != null) { return conn.getPort(); diff --git a/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java b/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java index 7b4decf1be7..ff393d9a5c3 100644 --- a/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java +++ b/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java @@ -77,12 +77,12 @@ public class KerberosClientKeyExchange extends HandshakeMessage { // please won't check the value of impl variable } - public KerberosClientKeyExchange(String serverName, boolean isLoopback, + public KerberosClientKeyExchange(String serverName, AccessControlContext acc, ProtocolVersion protocolVersion, SecureRandom rand) throws IOException { if (impl != null) { - init(serverName, isLoopback, acc, protocolVersion, rand); + init(serverName, acc, protocolVersion, rand); } else { throw new IllegalStateException("Kerberos is unavailable"); } @@ -120,12 +120,12 @@ public class KerberosClientKeyExchange extends HandshakeMessage { impl.print(p); } - public void init(String serverName, boolean isLoopback, + public void init(String serverName, AccessControlContext acc, ProtocolVersion protocolVersion, SecureRandom rand) throws IOException { if (impl != null) { - impl.init(serverName, isLoopback, acc, protocolVersion, rand); + impl.init(serverName, acc, protocolVersion, rand); } } diff --git a/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java b/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java index bd6f04e61ad..1fb770871d8 100644 --- a/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java +++ b/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,12 +105,12 @@ public final class KerberosClientKeyExchangeImpl * secret */ @Override - public void init(String serverName, boolean isLoopback, + public void init(String serverName, AccessControlContext acc, ProtocolVersion protocolVersion, SecureRandom rand) throws IOException { // Get service ticket - KerberosTicket ticket = getServiceTicket(serverName, isLoopback, acc); + KerberosTicket ticket = getServiceTicket(serverName, acc); encodedTicket = ticket.getEncoded(); // Record the Kerberos principals @@ -292,25 +292,33 @@ public final class KerberosClientKeyExchangeImpl } // Similar to sun.security.jgss.krb5.Krb5InitCredenetial/Krb5Context - private static KerberosTicket getServiceTicket(String srvName, - boolean isLoopback, final AccessControlContext acc) throws IOException { + private static KerberosTicket getServiceTicket(String serverName, + final AccessControlContext acc) throws IOException { - // get the local hostname if srvName is loopback address - String serverName = srvName; - if (isLoopback) { + if ("localhost".equals(serverName) || + "localhost.localdomain".equals(serverName)) { + + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Get the local hostname"); + } String localHost = java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public String run() { - String hostname; try { - hostname = InetAddress.getLocalHost().getHostName(); + return InetAddress.getLocalHost().getHostName(); } catch (java.net.UnknownHostException e) { - hostname = "localhost"; + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Warning," + + " cannot get the local hostname: " + + e.getMessage()); + } + return null; } - return hostname; } }); - serverName = localHost; + if (localHost != null) { + serverName = localHost; + } } // Resolve serverName (possibly in IP addr form) to Kerberos principal diff --git a/jdk/test/sun/security/krb5/auto/SSL.java b/jdk/test/sun/security/krb5/auto/SSL.java index 8d64460430d..aab262244ac 100644 --- a/jdk/test/sun/security/krb5/auto/SSL.java +++ b/jdk/test/sun/security/krb5/auto/SSL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,12 @@ /* * @test - * @bug 6894643 6913636 8005523 + * @bug 6894643 6913636 8005523 8025123 * @summary Test JSSE Kerberos ciphersuite * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA unbound + * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA unbound sni * @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_SHA * @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_MD5 * @run main/othervm SSL TLS_KRB5_WITH_DES_CBC_SHA @@ -44,6 +45,9 @@ import java.security.Permission; import javax.net.ssl.*; import java.security.Principal; import java.util.Date; +import java.util.List; +import java.util.ArrayList; +import java.util.Locale; import javax.security.auth.kerberos.ServicePermission; import sun.security.jgss.GSSUtil; import sun.security.krb5.PrincipalName; @@ -56,6 +60,8 @@ public class SSL extends SecurityManager { private static int loopCount = 0; private static volatile String server; private static volatile int port; + private static String sniHostname = null; + private static String sniMatcherPattern = null; private static String permChecks = ""; @@ -84,11 +90,11 @@ public class SSL extends SecurityManager { System.setSecurityManager(new SSL()); KDC kdc = KDC.create(OneKDC.REALM); - // Run this after KDC, so our own DNS service can be started - try { - server = InetAddress.getLocalHost().getHostName().toLowerCase(); - } catch (java.net.UnknownHostException e) { - server = "localhost"; + server = "host." + OneKDC.REALM.toLowerCase(Locale.US); + + if (args.length > 2) { + sniHostname = "test." + server; + sniMatcherPattern = ".*"; } kdc.addPrincipal(OneKDC.USER, OneKDC.PASS); @@ -98,15 +104,21 @@ public class SSL extends SecurityManager { // Add 3 versions of keys into keytab KeyTab ktab = KeyTab.create(OneKDC.KTAB); + String serviceName = null; + if (sniHostname != null) { + serviceName = "host/" + sniHostname; + } else { + serviceName = "host/" + server; + } PrincipalName service = new PrincipalName( - "host/" + server, PrincipalName.KRB_NT_SRV_HST); + serviceName, PrincipalName.KRB_NT_SRV_HST); ktab.addEntry(service, "pass1".toCharArray(), 1, true); ktab.addEntry(service, "pass2".toCharArray(), 2, true); ktab.addEntry(service, "pass3".toCharArray(), 3, true); ktab.save(); // and use the middle one as the real key - kdc.addPrincipal("host/" + server, "pass2".toCharArray()); + kdc.addPrincipal(serviceName, "pass2".toCharArray()); // JAAS config entry name ssl @@ -118,7 +130,7 @@ public class SSL extends SecurityManager { " com.sun.security.auth.module.Krb5LoginModule required\n" + (unbound ? " principal=*\n" : - " principal=\"host/" + server + "\"\n") + + " principal=\"" + serviceName + "\"\n") + " useKeyTab=true\n" + " keyTab=" + OneKDC.KTAB + "\n" + " isInitiator=false\n" + @@ -153,7 +165,7 @@ public class SSL extends SecurityManager { } c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); - c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID); + c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID); c.doAs(new JsseClientAction(), null); // Add another version of key, make sure it can be loaded @@ -161,10 +173,10 @@ public class SSL extends SecurityManager { ktab = KeyTab.getInstance(OneKDC.KTAB); ktab.addEntry(service, "pass4".toCharArray(), 4, true); ktab.save(); - kdc.addPrincipal("host/" + server, "pass4".toCharArray()); + kdc.addPrincipal(serviceName, "pass4".toCharArray()); c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); - c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID); + c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID); c.doAs(new JsseClientAction(), null); // Permission checking check. Please note this is highly @@ -199,6 +211,14 @@ public class SSL extends SecurityManager { sslSocket.setEnabledCipherSuites(enabledSuites); // Should check for exception if enabledSuites is not supported + if (sniHostname != null) { + List serverNames = new ArrayList<>(); + serverNames.add(new SNIHostName(sniHostname)); + SSLParameters params = sslSocket.getSSLParameters(); + params.setServerNames(serverNames); + sslSocket.setSSLParameters(params); + } + BufferedReader in = new BufferedReader(new InputStreamReader( sslSocket.getInputStream())); BufferedWriter out = new BufferedWriter(new OutputStreamWriter( @@ -242,6 +262,14 @@ public class SSL extends SecurityManager { sslServerSocket.setEnabledCipherSuites(enabledSuites); // Should check for exception if enabledSuites is not supported + if (sniMatcherPattern != null) { + List matchers = new ArrayList<>(); + matchers.add(SNIHostName.createSNIMatcher(sniMatcherPattern)); + SSLParameters params = sslServerSocket.getSSLParameters(); + params.setSNIMatchers(matchers); + sslServerSocket.setSSLParameters(params); + } + while (loopCount++ < LOOP_LIMIT) { System.out.println("Waiting for incoming connection..."); From 824b25cc94508e0920ec8fa4a13503a0a4474974 Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu Date: Wed, 2 Oct 2013 15:31:35 +0900 Subject: [PATCH 029/293] 6902861: (cal) GregorianCalendar roll WEEK_OF_YEAR is broken for January 1 2010 Reviewed-by: peytoia --- .../classes/java/util/GregorianCalendar.java | 75 +++++++++++++------ jdk/test/java/util/Calendar/Bug6902861.java | 69 +++++++++++++++++ 2 files changed, 123 insertions(+), 21 deletions(-) create mode 100644 jdk/test/java/util/Calendar/Bug6902861.java diff --git a/jdk/src/share/classes/java/util/GregorianCalendar.java b/jdk/src/share/classes/java/util/GregorianCalendar.java index 8381a4fab4b..eadb5d020dc 100644 --- a/jdk/src/share/classes/java/util/GregorianCalendar.java +++ b/jdk/src/share/classes/java/util/GregorianCalendar.java @@ -41,11 +41,8 @@ package java.util; import java.io.IOException; import java.io.ObjectInputStream; import java.time.Instant; -import java.time.ZoneId; import java.time.ZonedDateTime; -import java.time.chrono.IsoChronology; import java.time.temporal.ChronoField; -import java.time.temporal.TemporalQuery; import sun.util.calendar.BaseCalendar; import sun.util.calendar.CalendarDate; import sun.util.calendar.CalendarSystem; @@ -867,6 +864,7 @@ public class GregorianCalendar extends Calendar { * false otherwise. * @see Calendar#compareTo(Calendar) */ + @Override public boolean equals(Object obj) { return obj instanceof GregorianCalendar && super.equals(obj) && @@ -876,6 +874,7 @@ public class GregorianCalendar extends Calendar { /** * Generates the hash code for this GregorianCalendar object. */ + @Override public int hashCode() { return super.hashCode() ^ (int)gregorianCutoverDate; } @@ -908,6 +907,7 @@ public class GregorianCalendar extends Calendar { * or if any calendar fields have out-of-range values in * non-lenient mode. */ + @Override public void add(int field, int amount) { // If amount == 0, do nothing even the given field is out of // range. This is tested by JCK. @@ -1106,6 +1106,7 @@ public class GregorianCalendar extends Calendar { * @see #add(int,int) * @see #set(int,int) */ + @Override public void roll(int field, boolean up) { roll(field, up ? +1 : -1); } @@ -1154,6 +1155,7 @@ public class GregorianCalendar extends Calendar { * @see #set(int,int) * @since 1.2 */ + @Override public void roll(int field, int amount) { // If amount == 0, do nothing even the given field is out of // range. This is tested by JCK. @@ -1272,25 +1274,44 @@ public class GregorianCalendar extends Calendar { int woy = internalGet(WEEK_OF_YEAR); int value = woy + amount; if (!isCutoverYear(y)) { - // If the new value is in between min and max - // (exclusive), then we can use the value. - if (value > min && value < max) { - set(WEEK_OF_YEAR, value); - return; - } - long fd = getCurrentFixedDate(); - // Make sure that the min week has the current DAY_OF_WEEK - long day1 = fd - (7 * (woy - min)); - if (calsys.getYearFromFixedDate(day1) != y) { - min++; - } + int weekYear = getWeekYear(); + if (weekYear == y) { + // If the new value is in between min and max + // (exclusive), then we can use the value. + if (value > min && value < max) { + set(WEEK_OF_YEAR, value); + return; + } + long fd = getCurrentFixedDate(); + // Make sure that the min week has the current DAY_OF_WEEK + // in the calendar year + long day1 = fd - (7 * (woy - min)); + if (calsys.getYearFromFixedDate(day1) != y) { + min++; + } - // Make sure the same thing for the max week - fd += 7 * (max - internalGet(WEEK_OF_YEAR)); - if (calsys.getYearFromFixedDate(fd) != y) { - max--; + // Make sure the same thing for the max week + fd += 7 * (max - internalGet(WEEK_OF_YEAR)); + if (calsys.getYearFromFixedDate(fd) != y) { + max--; + } + } else { + // When WEEK_OF_YEAR and YEAR are out of sync, + // adjust woy and amount to stay in the calendar year. + if (weekYear > y) { + if (amount < 0) { + amount++; + } + woy = max; + } else { + if (amount > 0) { + amount -= woy - max; + } + woy = min; + } } - break; + set(field, getRolledValue(woy, amount, min, max)); + return; } // Handle cutover here. @@ -1510,6 +1531,7 @@ public class GregorianCalendar extends Calendar { * @see #getActualMinimum(int) * @see #getActualMaximum(int) */ + @Override public int getMinimum(int field) { return MIN_VALUES[field]; } @@ -1533,6 +1555,7 @@ public class GregorianCalendar extends Calendar { * @see #getActualMinimum(int) * @see #getActualMaximum(int) */ + @Override public int getMaximum(int field) { switch (field) { case MONTH: @@ -1581,6 +1604,7 @@ public class GregorianCalendar extends Calendar { * @see #getActualMinimum(int) * @see #getActualMaximum(int) */ + @Override public int getGreatestMinimum(int field) { if (field == DAY_OF_MONTH) { BaseCalendar.Date d = getGregorianCutoverDate(); @@ -1610,6 +1634,7 @@ public class GregorianCalendar extends Calendar { * @see #getActualMinimum(int) * @see #getActualMaximum(int) */ + @Override public int getLeastMaximum(int field) { switch (field) { case MONTH: @@ -1659,6 +1684,7 @@ public class GregorianCalendar extends Calendar { * @see #getActualMaximum(int) * @since 1.2 */ + @Override public int getActualMinimum(int field) { if (field == DAY_OF_MONTH) { GregorianCalendar gc = getNormalizedCalendar(); @@ -1702,6 +1728,7 @@ public class GregorianCalendar extends Calendar { * @see #getActualMinimum(int) * @since 1.2 */ + @Override public int getActualMaximum(int field) { final int fieldsForFixedMax = ERA_MASK|DAY_OF_WEEK_MASK|HOUR_MASK|AM_PM_MASK| HOUR_OF_DAY_MASK|MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK| @@ -1970,6 +1997,7 @@ public class GregorianCalendar extends Calendar { (internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET)); } + @Override public Object clone() { GregorianCalendar other = (GregorianCalendar) super.clone(); @@ -1987,6 +2015,7 @@ public class GregorianCalendar extends Calendar { return other; } + @Override public TimeZone getTimeZone() { TimeZone zone = super.getTimeZone(); // To share the zone by CalendarDates @@ -1997,6 +2026,7 @@ public class GregorianCalendar extends Calendar { return zone; } + @Override public void setTimeZone(TimeZone zone) { super.setTimeZone(zone); // To share the zone by CalendarDates @@ -2227,6 +2257,7 @@ public class GregorianCalendar extends Calendar { * @see #getActualMaximum(int) * @since 1.7 */ + @Override public int getWeeksInWeekYear() { GregorianCalendar gc = getNormalizedCalendar(); int weekYear = gc.getWeekYear(); @@ -2262,8 +2293,9 @@ public class GregorianCalendar extends Calendar { * * @see Calendar#complete */ + @Override protected void computeFields() { - int mask = 0; + int mask; if (isPartiallyNormalized()) { // Determine which calendar fields need to be computed. mask = getSetStateFields(); @@ -2598,6 +2630,7 @@ public class GregorianCalendar extends Calendar { * * @exception IllegalArgumentException if any calendar fields are invalid. */ + @Override protected void computeTime() { // In non-lenient mode, perform brief checking of calendar // fields which have been set externally. Through this diff --git a/jdk/test/java/util/Calendar/Bug6902861.java b/jdk/test/java/util/Calendar/Bug6902861.java new file mode 100644 index 00000000000..e8633f3449d --- /dev/null +++ b/jdk/test/java/util/Calendar/Bug6902861.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6902861 + * @summary Test for a workaround when WEEK_OF_YEAR and YEAR are out of sync. + */ + +import java.util.*; +import static java.util.GregorianCalendar.*; + +public class Bug6902861 { + static int errors = 0; + + public static void main(String [] args) { + Locale loc = Locale.getDefault(); + try { + Locale.setDefault(Locale.GERMANY); + test(2010, JANUARY, 1, +1, 1); + test(2010, JANUARY, 1, +2, 2); + test(2010, JANUARY, 1, -1, 52); + test(2010, JANUARY, 1, -2, 51); + test(2008, DECEMBER, 31, +1, 1); + test(2008, DECEMBER, 31, +2, 2); + test(2008, DECEMBER, 31, -1, 52); + test(2008, DECEMBER, 31, -2, 51); + if (errors > 0) { + throw new RuntimeException("Failed"); + } + } finally { + Locale.setDefault(loc); + } + } + + static void test(int year, int month, int dayOfMonth, int amount, int expected) { + Calendar calendar = new GregorianCalendar(year, month, dayOfMonth); + int week = calendar.get(WEEK_OF_YEAR); // fix the date + calendar.roll(WEEK_OF_YEAR, amount); + int got = calendar.get(WEEK_OF_YEAR); + int y = calendar.get(YEAR); + if (got != expected || y != year) { + String date = String.format("%04d-%02d-%02d", year, month+1, dayOfMonth); + System.err.printf("%s: roll %+d: got: %d,%2d; expected: %d,%2d%n", + date, amount, y, got, year, expected); + errors++; + } + } +} From 8d0e77641f5d881247ecacc335f5dde9b0b23f23 Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Wed, 2 Oct 2013 09:21:02 +0100 Subject: [PATCH 030/293] 8024952: ClassCastException in PlainSocketImpl.accept() when using custom socketImpl Reviewed-by: chegar --- .../classes/java/net/PlainSocketImpl.java | 19 ++-- .../CustomSocketImplFactory.java | 107 ++++++++++++++++++ 2 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 jdk/test/java/net/PlainSocketImpl/CustomSocketImplFactory.java diff --git a/jdk/src/windows/classes/java/net/PlainSocketImpl.java b/jdk/src/windows/classes/java/net/PlainSocketImpl.java index 1b6287d47f5..55ebc8ecbeb 100644 --- a/jdk/src/windows/classes/java/net/PlainSocketImpl.java +++ b/jdk/src/windows/classes/java/net/PlainSocketImpl.java @@ -191,14 +191,17 @@ class PlainSocketImpl extends AbstractPlainSocketImpl } protected synchronized void accept(SocketImpl s) throws IOException { - // pass in the real impl not the wrapper. - SocketImpl delegate = ((PlainSocketImpl)s).impl; - delegate.address = new InetAddress(); - delegate.fd = new FileDescriptor(); - impl.accept(delegate); - - // set fd to delegate's fd to be compatible with older releases - s.fd = delegate.fd; + if (s instanceof PlainSocketImpl) { + // pass in the real impl not the wrapper. + SocketImpl delegate = ((PlainSocketImpl)s).impl; + delegate.address = new InetAddress(); + delegate.fd = new FileDescriptor(); + impl.accept(delegate); + // set fd to delegate's fd to be compatible with older releases + s.fd = delegate.fd; + } else { + impl.accept(s); + } } void setFileDescriptor(FileDescriptor fd) { diff --git a/jdk/test/java/net/PlainSocketImpl/CustomSocketImplFactory.java b/jdk/test/java/net/PlainSocketImpl/CustomSocketImplFactory.java new file mode 100644 index 00000000000..9ec1eee9a43 --- /dev/null +++ b/jdk/test/java/net/PlainSocketImpl/CustomSocketImplFactory.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024952 + * @summary ClassCastException in PlainSocketImpl.accept() when using custom socketImpl + * @run main/othervm CustomSocketImplFactory + */ + +import java.net.*; +import java.io.*; + +public class CustomSocketImplFactory implements SocketImplFactory { + + @Override + public SocketImpl createSocketImpl() { + try { + SocketImpl s = new CustomSocketImpl(); + System.out.println("Created " + s); + return s; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void main(String[] args) throws Exception { + + Socket.setSocketImplFactory(new CustomSocketImplFactory()); + try (ServerSocket ss = new ServerSocket(0)) { + ss.setSoTimeout(1); + ss.accept(); + System.out.println("PASS"); + } catch (SocketTimeoutException | NullPointerException e) { + // Not a real socket impl + } + } + + class CustomSocketImpl extends SocketImpl { + + public void create(boolean stream) throws IOException { + } + + public void connect(String host, int port) throws IOException { + } + + public void connect(InetAddress addr, int port) throws IOException { + } + + public void connect(SocketAddress addr, int timeout) throws IOException { + } + + public void bind(InetAddress host, int port) throws IOException { + } + + public void listen(int backlog) throws IOException { + } + + public void accept(SocketImpl s) throws IOException { + } + + public InputStream getInputStream() throws IOException { + return null; + } + + public OutputStream getOutputStream() throws IOException { + return null; + } + + public int available() throws IOException { + return 0; + } + + public void close() throws IOException { + } + + public void sendUrgentData(int data) throws IOException { + } + + public Object getOption(int i) throws SocketException { + return null; + } + + public void setOption(int i, Object o) throws SocketException { + } + } +} From f640e20e654aeba7aae0ec76f437739878e6aaed Mon Sep 17 00:00:00 2001 From: Masayoshi Okutsu Date: Wed, 2 Oct 2013 17:57:04 +0900 Subject: [PATCH 031/293] 8022666: java.util.Calendar.set(int,int,int,int,int,int) documentation typo Reviewed-by: peytoia --- jdk/src/share/classes/java/util/Calendar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/Calendar.java b/jdk/src/share/classes/java/util/Calendar.java index 076b59db52c..03342411d0b 100644 --- a/jdk/src/share/classes/java/util/Calendar.java +++ b/jdk/src/share/classes/java/util/Calendar.java @@ -1937,7 +1937,7 @@ public abstract class Calendar implements Serializable, Cloneable, ComparableYEAR, MONTH, - * DAY_OF_MONTH, HOUR, MINUTE, and + * DAY_OF_MONTH, HOUR_OF_DAY, MINUTE, and * SECOND. * Previous values of other fields are retained. If this is not desired, * call {@link #clear()} first. From 7ee60c366e0cb49188c7bea270c1d75acf24cbce Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Tue, 1 Oct 2013 18:20:03 +0200 Subject: [PATCH 032/293] 8025535: Unsafe typecast in java.util.stream.SortedOps Reviewed-by: mduigou, chegar --- .../classes/java/util/stream/SortedOps.java | 24 ++++--- .../tests/java/util/stream/SortedOpTest.java | 65 +++++++++++++++++++ 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/util/stream/SortedOps.java b/jdk/src/share/classes/java/util/stream/SortedOps.java index 9df65e352e2..c9d04bd0763 100644 --- a/jdk/src/share/classes/java/util/stream/SortedOps.java +++ b/jdk/src/share/classes/java/util/stream/SortedOps.java @@ -277,8 +277,10 @@ final class SortedOps { } } + private static final String BAD_SIZE = "Stream size exceeds max array size"; + /** - * {@link ForkJoinTask} for implementing sort on SIZED reference streams. + * {@link Sink} for implementing sort on SIZED reference streams. */ private static final class SizedRefSortingSink extends Sink.ChainedReference { private final Comparator comparator; @@ -293,16 +295,12 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); array = (T[]) new Object[(int) size]; } @Override public void end() { - // Need to use offset rather than array.length since the downstream - // many be short-circuiting - // @@@ A better approach is to know if the downstream short-circuits - // and check sink.cancellationRequested Arrays.sort(array, 0, offset, comparator); downstream.begin(offset); for (int i = 0; i < offset; i++) @@ -331,6 +329,8 @@ final class SortedOps { @Override public void begin(long size) { + if (size >= Nodes.MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); list = (size >= 0) ? new ArrayList((int) size) : new ArrayList(); } @@ -363,7 +363,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); array = new int[(int) size]; } @@ -395,6 +395,8 @@ final class SortedOps { @Override public void begin(long size) { + if (size >= Nodes.MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); b = (size > 0) ? new SpinedBuffer.OfInt((int) size) : new SpinedBuffer.OfInt(); } @@ -428,7 +430,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); array = new long[(int) size]; } @@ -460,6 +462,8 @@ final class SortedOps { @Override public void begin(long size) { + if (size >= Nodes.MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); b = (size > 0) ? new SpinedBuffer.OfLong((int) size) : new SpinedBuffer.OfLong(); } @@ -493,7 +497,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); array = new double[(int) size]; } @@ -525,6 +529,8 @@ final class SortedOps { @Override public void begin(long size) { + if (size >= Nodes.MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); b = (size > 0) ? new SpinedBuffer.OfDouble((int) size) : new SpinedBuffer.OfDouble(); } diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java index 6c8cab21825..960e614fdc4 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java @@ -26,6 +26,8 @@ import org.testng.annotations.Test; import java.util.*; import java.util.Spliterators; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.*; import static java.util.stream.LambdaTestHelpers.*; @@ -37,6 +39,69 @@ import static java.util.stream.LambdaTestHelpers.*; */ @Test public class SortedOpTest extends OpTestCase { + + public void testRefStreamTooLarge() { + Function> f = s -> + // Clear the SORTED flag + s.mapToObj(i -> i) + .sorted(); + + testStreamTooLarge(f, Stream::findFirst); + } + + public void testIntStreamTooLarge() { + Function f = s -> + // Clear the SORTED flag + s.mapToInt(i -> (int) i) + .sorted(); + + testStreamTooLarge(f, IntStream::findFirst); + } + + public void testLongStreamTooLarge() { + Function f = s -> + // Clear the SORTED flag + s.map(i -> i) + .sorted(); + + testStreamTooLarge(f, LongStream::findFirst); + } + + public void testDoubleStreamTooLarge() { + Function f = s -> + // Clear the SORTED flag + s.mapToDouble(i -> (double) i) + .sorted(); + + testStreamTooLarge(f, DoubleStream::findFirst); + } + + > void testStreamTooLarge(Function s, + Function terminal) { + // Set up conditions for a large input > maximum array size + Supplier input = () -> LongStream.range(0, 1L + Integer.MAX_VALUE); + + // Transformation functions + List> transforms = Arrays.asList( + ls -> ls, + ls -> ls.parallel(), + // Clear the SIZED flag + ls -> ls.limit(Long.MAX_VALUE), + ls -> ls.limit(Long.MAX_VALUE).parallel()); + + for (Function transform : transforms) { + RuntimeException caught = null; + try { + terminal.apply(s.apply(transform.apply(input.get()))); + } catch (RuntimeException e) { + caught = e; + } + assertNotNull(caught, "Expected an instance of exception IllegalArgumentException but no exception thrown"); + assertTrue(caught instanceof IllegalArgumentException, + String.format("Expected an instance of exception IllegalArgumentException but got %s", caught)); + } + } + public void testSorted() { assertCountSum(countTo(0).stream().sorted(), 0, 0); assertCountSum(countTo(10).stream().sorted(), 10, 55); From 65580cea4313f74b8bde587dcf4b9f3e354548b2 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Tue, 1 Oct 2013 17:48:01 +0200 Subject: [PATCH 033/293] 6696975: JTop plugin fails if connected readonly to target JVM Reviewed-by: mchung, jbachorik, sla, sjiang --- jdk/src/share/demo/management/JTop/JTop.java | 53 ++++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/demo/management/JTop/JTop.java b/jdk/src/share/demo/management/JTop/JTop.java index e3703c6872f..ab0cd94e33d 100644 --- a/jdk/src/share/demo/management/JTop/JTop.java +++ b/jdk/src/share/demo/management/JTop/JTop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -87,12 +87,36 @@ import javax.swing.table.*; */ public class JTop extends JPanel { + private static class StatusBar extends JPanel { + private static final long serialVersionUID = -6483392381797633018L; + private final JLabel statusText; + + public StatusBar(boolean defaultVisible) { + super(new GridLayout(1, 1)); + statusText = new JLabel(); + statusText.setVisible(defaultVisible); + add(statusText); + } + + @Override + public Dimension getMaximumSize() { + Dimension maximum = super.getMaximumSize(); + Dimension minimum = getMinimumSize(); + return new Dimension(maximum.width, minimum.height); + } + + public void setMessage(String text) { + statusText.setText(text); + statusText.setVisible(true); + } + } private static final long serialVersionUID = -1499762160973870696L; private MBeanServerConnection server; private ThreadMXBean tmbean; private MyTableModel tmodel; + private final StatusBar statusBar; public JTop() { - super(new GridLayout(1,0)); + super(new GridBagLayout()); tmodel = new MyTableModel(); JTable table = new JTable(tmodel); @@ -108,7 +132,22 @@ public class JTop extends JPanel { JScrollPane scrollPane = new JScrollPane(table); // Add the scroll pane to this panel. - add(scrollPane); + GridBagConstraints c1 = new GridBagConstraints(); + c1.fill = GridBagConstraints.BOTH; + c1.gridy = 0; + c1.gridx = 0; + c1.weightx = 1; + c1.weighty = 1; + add(scrollPane, c1); + + statusBar = new StatusBar(false); + GridBagConstraints c2 = new GridBagConstraints(); + c2.fill = GridBagConstraints.HORIZONTAL; + c2.gridy = 1; + c2.gridx = 0; + c2.weightx = 1.0; + c2.weighty = 0.0; + add(statusBar, c2); } // Set the MBeanServerConnection object for communicating @@ -123,9 +162,13 @@ public class JTop extends JPanel { e.printStackTrace(); } if (!tmbean.isThreadCpuTimeSupported()) { - System.err.println("This VM does not support thread CPU time monitoring"); + statusBar.setMessage("Monitored VM does not support thread CPU time measurement"); } else { - tmbean.setThreadCpuTimeEnabled(true); + try { + tmbean.setThreadCpuTimeEnabled(true); + } catch (SecurityException e) { + statusBar.setMessage("Monitored VM does not have permission for enabling thread cpu time measurement"); + } } } From 47f46da3fa23c99fe4b72f85a97b03e5d500509f Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Wed, 2 Oct 2013 09:38:57 -0700 Subject: [PATCH 034/293] 8025694: Rename getStrongSecureRandom based on feedback 8014838: getStrongSecureRandom() should require at least one implementation Reviewed-by: mullan, darcy --- .../classes/java/security/SecureRandom.java | 35 ++++++++----------- .../share/lib/security/java.security-windows | 2 +- .../SecureRandom/StrongSecureRandom.java | 9 ++++- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/java/security/SecureRandom.java b/jdk/src/share/classes/java/security/SecureRandom.java index 5afec7b0797..b9ae7220b38 100644 --- a/jdk/src/share/classes/java/security/SecureRandom.java +++ b/jdk/src/share/classes/java/security/SecureRandom.java @@ -578,39 +578,30 @@ public class SecureRandom extends java.util.Random { /** * Returns a {@code SecureRandom} object that was selected by using * the algorithms/providers specified in the {@code - * securerandom.strongAlgorithms} Security property. + * securerandom.strongAlgorithms} {@link Security} property. *

* Some situations require strong random values, such as when * creating high-value/long-lived secrets like RSA public/private * keys. To help guide applications in selecting a suitable strong - * {@code SecureRandom} implementation, Java distributions should + * {@code SecureRandom} implementation, Java distributions * include a list of known strong {@code SecureRandom} * implementations in the {@code securerandom.strongAlgorithms} * Security property. - * - *

-     *     SecureRandom sr = SecureRandom.getStrongSecureRandom();
-     *
-     *     if (sr == null) {
-     *         // Decide if this is a problem, and whether to recover.
-     *         sr = new SecureRandom();
-     *         if (!goodEnough(sr)) {
-     *             return;
-     *         }
-     *     }
-     *
-     *     keyPairGenerator.initialize(2048, sr);
-     * 
+ *

+ * Every implementation of the Java platform is required to + * support at least one strong {@code SecureRandom} implementation. * * @return a strong {@code SecureRandom} implementation as indicated - * by the {@code securerandom.strongAlgorithms} Security property, or - * null if none are available. + * by the {@code securerandom.strongAlgorithms} Security property + * + * @throws NoSuchAlgorithmException if no algorithm is available * * @see Security#getProperty(String) * * @since 1.8 */ - public static SecureRandom getStrongSecureRandom() { + public static SecureRandom getInstanceStrong() + throws NoSuchAlgorithmException { String property = AccessController.doPrivileged( new PrivilegedAction() { @@ -622,7 +613,8 @@ public class SecureRandom extends java.util.Random { }); if ((property == null) || (property.length() == 0)) { - return null; + throw new NoSuchAlgorithmException( + "Null/empty securerandom.strongAlgorithms Security Property"); } String remainder = property; @@ -649,7 +641,8 @@ public class SecureRandom extends java.util.Random { } } - return null; + throw new NoSuchAlgorithmException( + "No strong SecureRandom impls available: " + property); } // Declare serialVersionUID to be compatible with JDK1.1 diff --git a/jdk/src/share/lib/security/java.security-windows b/jdk/src/share/lib/security/java.security-windows index cca53ae3961..1c371f022df 100644 --- a/jdk/src/share/lib/security/java.security-windows +++ b/jdk/src/share/lib/security/java.security-windows @@ -127,7 +127,7 @@ securerandom.source=file:/dev/random # This is a comma-separated list of algorithm and/or algorithm:provider # entries. # -securerandom.strongAlgorithms=Windows-PRNG:SunMSCAPI +securerandom.strongAlgorithms=Windows-PRNG:SunMSCAPI,SHA1PRNG:SUN # # Class to instantiate as the javax.security.auth.login.Configuration diff --git a/jdk/test/sun/security/provider/SecureRandom/StrongSecureRandom.java b/jdk/test/sun/security/provider/SecureRandom/StrongSecureRandom.java index 5050d1fccd4..2a45522cad8 100644 --- a/jdk/test/sun/security/provider/SecureRandom/StrongSecureRandom.java +++ b/jdk/test/sun/security/provider/SecureRandom/StrongSecureRandom.java @@ -120,7 +120,14 @@ public class StrongSecureRandom { private static void testStrongInstance(boolean expected) throws Exception { - boolean result = (SecureRandom.getStrongSecureRandom() != null); + boolean result; + + try { + SecureRandom.getInstanceStrong(); + result = true; + } catch (NoSuchAlgorithmException e) { + result = false; + } if (expected != result) { throw new Exception("Received: " + result); From 367fa5ac0ee697dd6afb71fe7f860d7719199146 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Wed, 2 Oct 2013 19:13:42 -0400 Subject: [PATCH 035/293] 8020981: Update methods of java.lang.reflect.Parameter to throw correct exceptions Fix behavior of parameter reflection API for malformed class files. Reviewed-by: darcy --- .../classes/java/lang/reflect/Executable.java | 38 +- .../reflect/MalformedParametersException.java | 60 +++ .../classes/java/lang/reflect/Parameter.java | 7 +- .../lang/reflect/Parameter/BadClassFiles.java | 462 ++++++++++++++++++ 4 files changed, 563 insertions(+), 4 deletions(-) create mode 100644 jdk/src/share/classes/java/lang/reflect/MalformedParametersException.java create mode 100644 jdk/test/java/lang/reflect/Parameter/BadClassFiles.java diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java index 43b9cc64f06..c92c9a57f78 100644 --- a/jdk/src/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java @@ -286,12 +286,14 @@ public abstract class Executable extends AccessibleObject * this object. Returns an array of length 0 if the executable * has no parameters. * - * The parameters of the underlying executable do not necessarily + *

The parameters of the underlying executable do not necessarily * have unique names, or names that are legal identifiers in the * Java programming language (JLS 3.8). * + * @throws MalformedParametersException if the class file contains + * a MethodParameters attribute that is improperly formatted. * @return an array of {@code Parameter} objects representing all - * the parameters to the executable this object represents + * the parameters to the executable this object represents. */ public Parameter[] getParameters() { // TODO: This may eventually need to be guarded by security @@ -315,6 +317,30 @@ public abstract class Executable extends AccessibleObject return out; } + private void verifyParameters(final Parameter[] parameters) { + final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED; + + if (getParameterTypes().length != parameters.length) + throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute"); + + for (Parameter parameter : parameters) { + final String name = parameter.getRealName(); + final int mods = parameter.getModifiers(); + + if (name != null) { + if (name.isEmpty() || name.indexOf('.') != -1 || + name.indexOf(';') != -1 || name.indexOf('[') != -1 || + name.indexOf('/') != -1) { + throw new MalformedParametersException("Invalid parameter name \"" + name + "\""); + } + } + + if (mods != (mods & mask)) { + throw new MalformedParametersException("Invalid parameter modifiers"); + } + } + } + private Parameter[] privateGetParameters() { // Use tmp to avoid multiple writes to a volatile. Parameter[] tmp = parameters; @@ -322,7 +348,12 @@ public abstract class Executable extends AccessibleObject if (tmp == null) { // Otherwise, go to the JVM to get them - tmp = getParameters0(); + try { + tmp = getParameters0(); + } catch(IllegalArgumentException e) { + // Rethrow ClassFormatErrors + throw new MalformedParametersException("Invalid constant pool index"); + } // If we get back nothing, then synthesize parameters if (tmp == null) { @@ -330,6 +361,7 @@ public abstract class Executable extends AccessibleObject tmp = synthesizeAllParams(); } else { hasRealParameterData = true; + verifyParameters(tmp); } parameters = tmp; diff --git a/jdk/src/share/classes/java/lang/reflect/MalformedParametersException.java b/jdk/src/share/classes/java/lang/reflect/MalformedParametersException.java new file mode 100644 index 00000000000..c68600b412a --- /dev/null +++ b/jdk/src/share/classes/java/lang/reflect/MalformedParametersException.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +/** + * Thrown when {@link java.lang.reflect.Executable#getParameters the + * java.lang.reflect package} attempts to read method parameters from + * a class file and determines that one or more parameters are + * malformed. + * + *

The following is a list of conditions under which this exception + * can be thrown: + *

    + *
  • The number of parameters (parameter_count) is wrong for the method + *
  • A constant pool index is out of bounds. + *
  • A constant pool index does not refer to a UTF-8 entry + *
  • A parameter's name is "", or contains an illegal character + *
  • The flags field contains an illegal flag (something other than + * FINAL, SYNTHETIC, or MANDATED) + *
+ * + * See {@link java.lang.reflect.Executable#getParameters} for more + * information. + * + * @see java.lang.reflect.Executable#getParameters + * @since 1.8 + */ +public class MalformedParametersException extends RuntimeException { + + private static final long serialVersionUID = 20130919L; + + public MalformedParametersException() {} + + public MalformedParametersException(String reason) { + super(reason); + } +} diff --git a/jdk/src/share/classes/java/lang/reflect/Parameter.java b/jdk/src/share/classes/java/lang/reflect/Parameter.java index 0568d9ee2e0..2285819c27b 100644 --- a/jdk/src/share/classes/java/lang/reflect/Parameter.java +++ b/jdk/src/share/classes/java/lang/reflect/Parameter.java @@ -104,7 +104,7 @@ public final class Parameter implements AnnotatedElement { * to the class file. */ public boolean isNamePresent() { - return executable.hasRealParameterData(); + return executable.hasRealParameterData() && name != null; } /** @@ -182,6 +182,11 @@ public final class Parameter implements AnnotatedElement { return name; } + // Package-private accessor to the real name field. + String getRealName() { + return name; + } + /** * Returns a {@code Type} object that identifies the parameterized * type for the parameter represented by this {@code Parameter} diff --git a/jdk/test/java/lang/reflect/Parameter/BadClassFiles.java b/jdk/test/java/lang/reflect/Parameter/BadClassFiles.java new file mode 100644 index 00000000000..581d4ef6f5f --- /dev/null +++ b/jdk/test/java/lang/reflect/Parameter/BadClassFiles.java @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @run main BadClassFiles + * @summary The reflection API should throw the correct exceptions. + */ +import java.lang.Class; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.lang.reflect.MalformedParametersException; +import java.lang.ClassLoader; +import java.lang.ClassNotFoundException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class BadClassFiles { + private int errors = 0; + + + /* Class files were created by compiling the following source and + * then editing it: + * + * public class EmptyName { + * public void m(int a, int b) {} + * } + * + */ + private static final byte[] EmptyName_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,0,1, + 0,1,98,1,0,10,83,111, + 117,114,99,101,70,105,108,101, + 1,0,14,69,109,112,116,121, + 78,97,109,101,46,106,97,118, + 97,12,0,4,0,5,1,0, + 9,69,109,112,116,121,78,97, + 109,101,1,0,16,106,97,118, + 97,47,108,97,110,103,47,79, + 98,106,101,99,116,0,33,0, + 2,0,3,0,0,0,0,0, + 2,0,1,0,4,0,5,0, + 1,0,6,0,0,0,29,0, + 1,0,1,0,0,0,5,42, + -73,0,1,-79,0,0,0,1, + 0,7,0,0,0,6,0,1, + 0,0,0,1,0,1,0,8, + 0,9,0,2,0,6,0,0, + 0,25,0,0,0,3,0,0, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,2,0,10,0,0,0, + 9,2,0,11,0,0,0,12, + 0,0,0,1,0,13,0,0, + 0,2,0,14 + }; + + private static final byte[] BadModifiers_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,97, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,17,66,97,100,77, + 111,100,105,102,105,101,114,115, + 46,106,97,118,97,12,0,4, + 0,5,1,0,12,66,97,100, + 77,111,100,105,102,105,101,114, + 115,1,0,16,106,97,118,97, + 47,108,97,110,103,47,79,98, + 106,101,99,116,0,33,0,2, + 0,3,0,0,0,0,0,2, + 0,1,0,4,0,5,0,1, + 0,6,0,0,0,29,0,1, + 0,1,0,0,0,5,42,-73, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,1,0,1,0,8,0, + 9,0,2,0,6,0,0,0, + 25,0,0,0,3,0,0,0, + 1,-79,0,0,0,1,0,7, + 0,0,0,6,0,1,0,0, + 0,2,0,10,0,0,0,9, + 2,0,11,0,51,51,12,0, + 0,0,1,0,13,0,0,0, + 2,0,14 + }; + + private static final byte[] BadNameIndex_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,97, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,17,66,97,100,78, + 97,109,101,73,110,100,101,120, + 46,106,97,118,97,12,0,4, + 0,5,1,0,12,66,97,100, + 78,97,109,101,73,110,100,101, + 120,1,0,16,106,97,118,97, + 47,108,97,110,103,47,79,98, + 106,101,99,116,0,33,0,2, + 0,3,0,0,0,0,0,2, + 0,1,0,4,0,5,0,1, + 0,6,0,0,0,29,0,1, + 0,1,0,0,0,5,42,-73, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,1,0,1,0,8,0, + 9,0,2,0,6,0,0,0, + 25,0,0,0,3,0,0,0, + 1,-79,0,0,0,1,0,7, + 0,0,0,6,0,1,0,0, + 0,2,0,10,0,0,0,9, + 2,0,1,0,0,0,12,0, + 0,0,1,0,13,0,0,0, + 2,0,14 + }; + + private static final byte[] NameIndexOutOfBounds_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,97, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,25,78,97,109,101, + 73,110,100,101,120,79,117,116, + 79,102,66,111,117,110,100,115, + 46,106,97,118,97,12,0,4, + 0,5,1,0,20,78,97,109, + 101,73,110,100,101,120,79,117, + 116,79,102,66,111,117,110,100, + 115,1,0,16,106,97,118,97, + 47,108,97,110,103,47,79,98, + 106,101,99,116,0,33,0,2, + 0,3,0,0,0,0,0,2, + 0,1,0,4,0,5,0,1, + 0,6,0,0,0,29,0,1, + 0,1,0,0,0,5,42,-73, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,1,0,1,0,8,0, + 9,0,2,0,6,0,0,0, + 25,0,0,0,3,0,0,0, + 1,-79,0,0,0,1,0,7, + 0,0,0,6,0,1,0,0, + 0,2,0,10,0,0,0,9, + 2,0,-1,0,0,0,12,0, + 0,0,1,0,13,0,0,0, + 2,0,14 + + }; + + private static final byte[] ExtraParams_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,97, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,16,69,120,116,114, + 97,80,97,114,97,109,115,46, + 106,97,118,97,12,0,4,0, + 5,1,0,11,69,120,116,114, + 97,80,97,114,97,109,115,1, + 0,16,106,97,118,97,47,108, + 97,110,103,47,79,98,106,101, + 99,116,0,33,0,2,0,3, + 0,0,0,0,0,2,0,1, + 0,4,0,5,0,1,0,6, + 0,0,0,29,0,1,0,1, + 0,0,0,5,42,-73,0,1, + -79,0,0,0,1,0,7,0, + 0,0,6,0,1,0,0,0, + 1,0,1,0,8,0,9,0, + 2,0,6,0,0,0,25,0, + 0,0,3,0,0,0,1,-79, + 0,0,0,1,0,7,0,0, + 0,6,0,1,0,0,0,2, + 0,10,0,0,0,13,3,0, + 11,0,0,0,12,0,0,0, + 11,0,0,0,1,0,13,0, + 0,0,2,0,14 + }; + + private static final byte[] BadName1_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,46, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,13,66,97,100,78, + 97,109,101,49,46,106,97,118, + 97,12,0,4,0,5,1,0, + 8,66,97,100,78,97,109,101, + 49,1,0,16,106,97,118,97, + 47,108,97,110,103,47,79,98, + 106,101,99,116,0,33,0,2, + 0,3,0,0,0,0,0,2, + 0,1,0,4,0,5,0,1, + 0,6,0,0,0,29,0,1, + 0,1,0,0,0,5,42,-73, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,1,0,1,0,8,0, + 9,0,2,0,6,0,0,0, + 25,0,0,0,3,0,0,0, + 1,-79,0,0,0,1,0,7, + 0,0,0,6,0,1,0,0, + 0,2,0,10,0,0,0,9, + 2,0,11,0,0,0,12,0, + 0,0,1,0,13,0,0,0, + 2,0,14 + }; + + private static final byte[] BadName2_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,91, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,13,66,97,100,78, + 97,109,101,50,46,106,97,118, + 97,12,0,4,0,5,1,0, + 8,66,97,100,78,97,109,101, + 50,1,0,16,106,97,118,97, + 47,108,97,110,103,47,79,98, + 106,101,99,116,0,33,0,2, + 0,3,0,0,0,0,0,2, + 0,1,0,4,0,5,0,1, + 0,6,0,0,0,29,0,1, + 0,1,0,0,0,5,42,-73, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,1,0,1,0,8,0, + 9,0,2,0,6,0,0,0, + 25,0,0,0,3,0,0,0, + 1,-79,0,0,0,1,0,7, + 0,0,0,6,0,1,0,0, + 0,2,0,10,0,0,0,9, + 2,0,11,0,0,0,12,0, + 0,0,1,0,13,0,0,0, + 2,0,14 + }; + + private static final byte[] BadName3_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,59, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,13,66,97,100,78, + 97,109,101,51,46,106,97,118, + 97,12,0,4,0,5,1,0, + 8,66,97,100,78,97,109,101, + 51,1,0,16,106,97,118,97, + 47,108,97,110,103,47,79,98, + 106,101,99,116,0,33,0,2, + 0,3,0,0,0,0,0,2, + 0,1,0,4,0,5,0,1, + 0,6,0,0,0,29,0,1, + 0,1,0,0,0,5,42,-73, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,1,0,1,0,8,0, + 9,0,2,0,6,0,0,0, + 25,0,0,0,3,0,0,0, + 1,-79,0,0,0,1,0,7, + 0,0,0,6,0,1,0,0, + 0,2,0,10,0,0,0,9, + 2,0,11,0,0,0,12,0, + 0,0,1,0,13,0,0,0, + 2,0,14 + }; + + private static final byte[] BadName4_bytes = { + -54,-2,-70,-66,0,0,0,52, + 0,18,10,0,3,0,15,7, + 0,16,7,0,17,1,0,6, + 60,105,110,105,116,62,1,0, + 3,40,41,86,1,0,4,67, + 111,100,101,1,0,15,76,105, + 110,101,78,117,109,98,101,114, + 84,97,98,108,101,1,0,1, + 109,1,0,5,40,73,73,41, + 86,1,0,16,77,101,116,104, + 111,100,80,97,114,97,109,101, + 116,101,114,115,1,0,1,47, + 1,0,1,98,1,0,10,83, + 111,117,114,99,101,70,105,108, + 101,1,0,13,66,97,100,78, + 97,109,101,52,46,106,97,118, + 97,12,0,4,0,5,1,0, + 8,66,97,100,78,97,109,101, + 52,1,0,16,106,97,118,97, + 47,108,97,110,103,47,79,98, + 106,101,99,116,0,33,0,2, + 0,3,0,0,0,0,0,2, + 0,1,0,4,0,5,0,1, + 0,6,0,0,0,29,0,1, + 0,1,0,0,0,5,42,-73, + 0,1,-79,0,0,0,1,0, + 7,0,0,0,6,0,1,0, + 0,0,1,0,1,0,8,0, + 9,0,2,0,6,0,0,0, + 25,0,0,0,3,0,0,0, + 1,-79,0,0,0,1,0,7, + 0,0,0,6,0,1,0,0, + 0,2,0,10,0,0,0,9, + 2,0,11,0,0,0,12,0, + 0,0,1,0,13,0,0,0, + 2,0,14 + }; + + private static class InMemoryClassLoader extends ClassLoader { + public Class defineClass(String name, byte[] b) { + return defineClass(name, b, 0, b.length); + } + }; + + private static final InMemoryClassLoader loader = new InMemoryClassLoader(); + + private final Class[] classes; + + private BadClassFiles() throws ClassNotFoundException { + classes = new Class[] { + loader.defineClass("EmptyName", EmptyName_bytes), + loader.defineClass("BadModifiers", BadModifiers_bytes), + loader.defineClass("BadNameIndex", BadNameIndex_bytes), + loader.defineClass("NameIndexOutOfBounds", NameIndexOutOfBounds_bytes), + loader.defineClass("ExtraParams", ExtraParams_bytes), + // Name with . + loader.defineClass("BadName1", BadName1_bytes), + // Name with [ + loader.defineClass("BadName2", BadName2_bytes), + // Name with ; + loader.defineClass("BadName3", BadName3_bytes), + // Name with / + loader.defineClass("BadName4", BadName4_bytes) + }; + } + + public static void main(String... args) + throws NoSuchMethodException, IOException, ClassNotFoundException { + new BadClassFiles().run(); + } + + public void assertBadParameters(Class cls) throws NoSuchMethodException { + try { + System.err.println("Trying " + cls); + final Method method = cls.getMethod("m", int.class, int.class); + final Parameter[] params = method.getParameters(); + System.err.println("Name " + params[0].getName()); + System.err.println("Did not see expected exception"); + errors++; + } catch(MalformedParametersException e) { + System.err.println("Expected exception seen"); + } + } + + public void run() throws NoSuchMethodException { + for (Class cls : classes) + assertBadParameters(cls); + + if (errors != 0) + throw new RuntimeException(errors + " errors in test"); + } +} From 10a6fcc8a01f38df17d32a9f657096a0b05f86f7 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Wed, 2 Oct 2013 16:34:12 +0200 Subject: [PATCH 036/293] 8025534: Unsafe typecast in java.util.stream.Streams.Nodes 8025538: Unsafe typecast in java.util.stream.SpinedBuffer 8025533: Unsafe typecast in java.util.stream.Streams.RangeIntSpliterator.splitPoint() 8025525: Unsafe typecast in java.util.stream.Node.OfPrimitive.asArray() Reviewed-by: chegar --- .../share/classes/java/util/stream/Node.java | 10 ++- .../share/classes/java/util/stream/Nodes.java | 64 +++++++++++++------ .../classes/java/util/stream/SortedOps.java | 18 +++--- .../java/util/stream/SpinedBuffer.java | 29 ++++++--- .../classes/java/util/stream/Streams.java | 4 +- 5 files changed, 86 insertions(+), 39 deletions(-) diff --git a/jdk/src/share/classes/java/util/stream/Node.java b/jdk/src/share/classes/java/util/stream/Node.java index bf4c2c6340a..381d06defbe 100644 --- a/jdk/src/share/classes/java/util/stream/Node.java +++ b/jdk/src/share/classes/java/util/stream/Node.java @@ -149,7 +149,9 @@ interface Node { /** * Copies the content of this {@code Node} into an array, starting at a * given offset into the array. It is the caller's responsibility to ensure - * there is sufficient room in the array. + * there is sufficient room in the array, otherwise unspecified behaviour + * will occur if the array length is less than the number of elements + * contained in this node. * * @param array the array into which to copy the contents of this * {@code Node} @@ -258,6 +260,12 @@ interface Node { */ @Override default T[] asArray(IntFunction generator) { + if (java.util.stream.Tripwire.ENABLED) + java.util.stream.Tripwire.trip(getClass(), "{0} calling Node.OfPrimitive.asArray"); + + long size = count(); + if (size >= Nodes.MAX_ARRAY_SIZE) + throw new IllegalArgumentException(Nodes.BAD_SIZE); T[] boxed = generator.apply((int) count()); copyInto(boxed, 0); return boxed; diff --git a/jdk/src/share/classes/java/util/stream/Nodes.java b/jdk/src/share/classes/java/util/stream/Nodes.java index 687174462b3..d69b9f61b1a 100644 --- a/jdk/src/share/classes/java/util/stream/Nodes.java +++ b/jdk/src/share/classes/java/util/stream/Nodes.java @@ -60,6 +60,9 @@ final class Nodes { */ static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + // IllegalArgumentException messages + static final String BAD_SIZE = "Stream size exceeds max array size"; + @SuppressWarnings("raw") private static final Node EMPTY_NODE = new EmptyNode.OfRef(); private static final Node.OfInt EMPTY_INT_NODE = new EmptyNode.OfInt(); @@ -317,7 +320,7 @@ final class Nodes { long size = helper.exactOutputSizeIfKnown(spliterator); if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); P_OUT[] array = generator.apply((int) size); new SizedCollectorTask.OfRef<>(spliterator, helper, array).invoke(); return node(array); @@ -354,7 +357,7 @@ final class Nodes { long size = helper.exactOutputSizeIfKnown(spliterator); if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); int[] array = new int[(int) size]; new SizedCollectorTask.OfInt<>(spliterator, helper, array).invoke(); return node(array); @@ -392,7 +395,7 @@ final class Nodes { long size = helper.exactOutputSizeIfKnown(spliterator); if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); long[] array = new long[(int) size]; new SizedCollectorTask.OfLong<>(spliterator, helper, array).invoke(); return node(array); @@ -430,7 +433,7 @@ final class Nodes { long size = helper.exactOutputSizeIfKnown(spliterator); if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); double[] array = new double[(int) size]; new SizedCollectorTask.OfDouble<>(spliterator, helper, array).invoke(); return node(array); @@ -460,7 +463,10 @@ final class Nodes { */ public static Node flatten(Node node, IntFunction generator) { if (node.getChildCount() > 0) { - T[] array = generator.apply((int) node.count()); + long size = node.count(); + if (size >= MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); + T[] array = generator.apply((int) size); new ToArrayTask.OfRef<>(node, array, 0).invoke(); return node(array); } else { @@ -483,7 +489,10 @@ final class Nodes { */ public static Node.OfInt flattenInt(Node.OfInt node) { if (node.getChildCount() > 0) { - int[] array = new int[(int) node.count()]; + long size = node.count(); + if (size >= MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); + int[] array = new int[(int) size]; new ToArrayTask.OfInt(node, array, 0).invoke(); return node(array); } else { @@ -506,7 +515,10 @@ final class Nodes { */ public static Node.OfLong flattenLong(Node.OfLong node) { if (node.getChildCount() > 0) { - long[] array = new long[(int) node.count()]; + long size = node.count(); + if (size >= MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); + long[] array = new long[(int) size]; new ToArrayTask.OfLong(node, array, 0).invoke(); return node(array); } else { @@ -529,7 +541,10 @@ final class Nodes { */ public static Node.OfDouble flattenDouble(Node.OfDouble node) { if (node.getChildCount() > 0) { - double[] array = new double[(int) node.count()]; + long size = node.count(); + if (size >= MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); + double[] array = new double[(int) size]; new ToArrayTask.OfDouble(node, array, 0).invoke(); return node(array); } else { @@ -627,7 +642,7 @@ final class Nodes { @SuppressWarnings("unchecked") ArrayNode(long size, IntFunction generator) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); this.array = generator.apply((int) size); this.curSize = 0; } @@ -777,12 +792,17 @@ final class Nodes { public void copyInto(T[] array, int offset) { Objects.requireNonNull(array); left.copyInto(array, offset); + // Cast to int is safe since it is the callers responsibility to + // ensure that there is sufficient room in the array right.copyInto(array, offset + (int) left.count()); } @Override public T[] asArray(IntFunction generator) { - T[] array = generator.apply((int) count()); + long size = count(); + if (size >= MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); + T[] array = generator.apply((int) size); copyInto(array, 0); return array; } @@ -836,12 +856,17 @@ final class Nodes { @Override public void copyInto(T_ARR array, int offset) { left.copyInto(array, offset); + // Cast to int is safe since it is the callers responsibility to + // ensure that there is sufficient room in the array right.copyInto(array, offset + (int) left.count()); } @Override public T_ARR asPrimitiveArray() { - T_ARR array = newArray((int) count()); + long size = count(); + if (size >= MAX_ARRAY_SIZE) + throw new IllegalArgumentException(BAD_SIZE); + T_ARR array = newArray((int) size); copyInto(array, 0); return array; } @@ -1287,7 +1312,7 @@ final class Nodes { IntArrayNode(long size) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); this.array = new int[(int) size]; this.curSize = 0; } @@ -1343,7 +1368,7 @@ final class Nodes { LongArrayNode(long size) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); this.array = new long[(int) size]; this.curSize = 0; } @@ -1397,7 +1422,7 @@ final class Nodes { DoubleArrayNode(long size) { if (size >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + throw new IllegalArgumentException(BAD_SIZE); this.array = new double[(int) size]; this.curSize = 0; } @@ -1843,8 +1868,8 @@ final class Nodes { task = task.makeChild(rightSplit, task.offset + leftSplitSize, task.length - leftSplitSize); } - if (task.offset + task.length >= MAX_ARRAY_SIZE) - throw new IllegalArgumentException("Stream size exceeds max array size"); + + assert task.offset + task.length < MAX_ARRAY_SIZE; T_SINK sink = (T_SINK) task; task.helper.wrapAndCopyInto(sink, rightSplit); task.propagateCompletion(); @@ -1854,10 +1879,13 @@ final class Nodes { @Override public void begin(long size) { - if(size > length) + if (size > length) throw new IllegalStateException("size passed to Sink.begin exceeds array length"); + // Casts to int are safe since absolute size is verified to be within + // bounds when the root concrete SizedCollectorTask is constructed + // with the shared array index = (int) offset; - fence = (int) offset + (int) length; + fence = index + (int) length; } @SuppressWarnings("serial") diff --git a/jdk/src/share/classes/java/util/stream/SortedOps.java b/jdk/src/share/classes/java/util/stream/SortedOps.java index c9d04bd0763..8dcabb49145 100644 --- a/jdk/src/share/classes/java/util/stream/SortedOps.java +++ b/jdk/src/share/classes/java/util/stream/SortedOps.java @@ -277,8 +277,6 @@ final class SortedOps { } } - private static final String BAD_SIZE = "Stream size exceeds max array size"; - /** * {@link Sink} for implementing sort on SIZED reference streams. */ @@ -295,7 +293,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); array = (T[]) new Object[(int) size]; } @@ -330,7 +328,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); list = (size >= 0) ? new ArrayList((int) size) : new ArrayList(); } @@ -363,7 +361,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); array = new int[(int) size]; } @@ -396,7 +394,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); b = (size > 0) ? new SpinedBuffer.OfInt((int) size) : new SpinedBuffer.OfInt(); } @@ -430,7 +428,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); array = new long[(int) size]; } @@ -463,7 +461,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); b = (size > 0) ? new SpinedBuffer.OfLong((int) size) : new SpinedBuffer.OfLong(); } @@ -497,7 +495,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); array = new double[(int) size]; } @@ -530,7 +528,7 @@ final class SortedOps { @Override public void begin(long size) { if (size >= Nodes.MAX_ARRAY_SIZE) - throw new IllegalArgumentException(BAD_SIZE); + throw new IllegalArgumentException(Nodes.BAD_SIZE); b = (size > 0) ? new SpinedBuffer.OfDouble((int) size) : new SpinedBuffer.OfDouble(); } diff --git a/jdk/src/share/classes/java/util/stream/SpinedBuffer.java b/jdk/src/share/classes/java/util/stream/SpinedBuffer.java index 7312c984a51..e7fac67510f 100644 --- a/jdk/src/share/classes/java/util/stream/SpinedBuffer.java +++ b/jdk/src/share/classes/java/util/stream/SpinedBuffer.java @@ -156,6 +156,9 @@ class SpinedBuffer public E get(long index) { // @@@ can further optimize by caching last seen spineIndex, // which is going to be right most of the time + + // Casts to int are safe since the spine array index is the index minus + // the prior element count from the current spine if (spineIndex == 0) { if (index < elementIndex) return curChunk[((int) index)]; @@ -201,11 +204,11 @@ class SpinedBuffer * elements into it. */ public E[] asArray(IntFunction arrayFactory) { - // @@@ will fail for size == MAX_VALUE - E[] result = arrayFactory.apply((int) count()); - + long size = count(); + if (size >= Nodes.MAX_ARRAY_SIZE) + throw new IllegalArgumentException(Nodes.BAD_SIZE); + E[] result = arrayFactory.apply((int) size); copyInto(result, 0); - return result; } @@ -547,8 +550,10 @@ class SpinedBuffer } public T_ARR asPrimitiveArray() { - // @@@ will fail for size == MAX_VALUE - T_ARR result = newArray((int) count()); + long size = count(); + if (size >= Nodes.MAX_ARRAY_SIZE) + throw new IllegalArgumentException(Nodes.BAD_SIZE); + T_ARR result = newArray((int) size); copyInto(result, 0); return result; } @@ -760,11 +765,13 @@ class SpinedBuffer } public int get(long index) { + // Casts to int are safe since the spine array index is the index minus + // the prior element count from the current spine int ch = chunkFor(index); if (spineIndex == 0 && ch == 0) return curChunk[(int) index]; else - return spine[ch][(int) (index-priorElementCount[ch])]; + return spine[ch][(int) (index - priorElementCount[ch])]; } @Override @@ -871,11 +878,13 @@ class SpinedBuffer } public long get(long index) { + // Casts to int are safe since the spine array index is the index minus + // the prior element count from the current spine int ch = chunkFor(index); if (spineIndex == 0 && ch == 0) return curChunk[(int) index]; else - return spine[ch][(int) (index-priorElementCount[ch])]; + return spine[ch][(int) (index - priorElementCount[ch])]; } @Override @@ -984,11 +993,13 @@ class SpinedBuffer } public double get(long index) { + // Casts to int are safe since the spine array index is the index minus + // the prior element count from the current spine int ch = chunkFor(index); if (spineIndex == 0 && ch == 0) return curChunk[(int) index]; else - return spine[ch][(int) (index-priorElementCount[ch])]; + return spine[ch][(int) (index - priorElementCount[ch])]; } @Override diff --git a/jdk/src/share/classes/java/util/stream/Streams.java b/jdk/src/share/classes/java/util/stream/Streams.java index 8af33f2b3c2..41f3adad592 100644 --- a/jdk/src/share/classes/java/util/stream/Streams.java +++ b/jdk/src/share/classes/java/util/stream/Streams.java @@ -169,7 +169,9 @@ final class Streams { private int splitPoint(long size) { int d = (size < BALANCED_SPLIT_THRESHOLD) ? 2 : RIGHT_BALANCED_SPLIT_RATIO; - // 2 <= size <= 2^32 + // Cast to int is safe since: + // 2 <= size < 2^32 + // 2 <= d <= 8 return (int) (size / d); } } From 1604846c446c839bf7f7604d8a9728a3385616dd Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Thu, 3 Oct 2013 10:59:51 +0200 Subject: [PATCH 037/293] 8025567: Mark relevant public stream tests as serialization hostile Reviewed-by: alanb --- .../openjdk/tests/java/util/stream/ForEachOpTest.java | 8 ++++---- .../org/openjdk/tests/java/util/stream/SliceOpTest.java | 9 ++++++--- .../tests/java/util/stream/StreamBuilderTest.java | 8 ++++---- .../openjdk/tests/java/util/stream/ToArrayOpTest.java | 3 ++- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java index d5bb72cda5b..e7337e608a3 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java @@ -69,7 +69,7 @@ public class ForEachOpTest extends OpTestCase { }; } - @Test + @Test(groups = { "serialization-hostile" }) public void testForEachOrdered() { List input = countTo(10000); TestData.OfRef data = TestData.Factory.ofCollection("[1, 10000]", input); @@ -116,7 +116,7 @@ public class ForEachOpTest extends OpTestCase { // - @Test + @Test(groups = { "serialization-hostile" }) public void testIntForEachOrdered() { List input = countTo(10000); TestData.OfInt data = TestData.Factory.ofIntSupplier("[1, 10000]", @@ -164,7 +164,7 @@ public class ForEachOpTest extends OpTestCase { // - @Test + @Test(groups = { "serialization-hostile" }) public void testLongForEachOrdered() { List input = countTo(10000); TestData.OfLong data = TestData.Factory.ofLongSupplier("[1, 10000]", @@ -212,7 +212,7 @@ public class ForEachOpTest extends OpTestCase { // - @Test + @Test(groups = { "serialization-hostile" }) public void testDoubleForEachOrdered() { List input = countTo(10000); TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("[1, 10000]", diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java index b8c9b54a343..a02348623c2 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java @@ -147,7 +147,8 @@ public class SliceOpTest extends OpTestCase { return Math.max(0, dataSize - skip); } - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class, + groups = { "serialization-hostile" }) public void testSkipOps(String name, TestData.OfRef data) { List skips = sizes(data.size()); @@ -169,7 +170,8 @@ public class SliceOpTest extends OpTestCase { } } - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class, + groups = { "serialization-hostile" }) public void testSkipLimitOps(String name, TestData.OfRef data) { List skips = sizes(data.size()); List limits = skips; @@ -242,7 +244,8 @@ public class SliceOpTest extends OpTestCase { testSkipLimitOps("testSkipLimitOpsWithNonSplittingSpliterator", data); } - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class, + groups = { "serialization-hostile" }) public void testLimitOps(String name, TestData.OfRef data) { List limits = sizes(data.size()); diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java index cbf87b1e779..d8d46fd6368 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java @@ -97,7 +97,7 @@ public class StreamBuilderTest extends OpTestCase { checkISE(() -> sb.build()); } - @Test(dataProvider = "sizes") + @Test(dataProvider = "sizes", groups = { "serialization-hostile" }) public void testStreamBuilder(int size) { testStreamBuilder(size, (s) -> { Stream.Builder sb = Stream.builder(); @@ -159,7 +159,7 @@ public class StreamBuilderTest extends OpTestCase { checkISE(() -> sb.build()); } - @Test(dataProvider = "sizes") + @Test(dataProvider = "sizes", groups = { "serialization-hostile" }) public void testIntStreamBuilder(int size) { testIntStreamBuilder(size, (s) -> { IntStream.Builder sb = IntStream.builder(); @@ -221,7 +221,7 @@ public class StreamBuilderTest extends OpTestCase { checkISE(() -> sb.build()); } - @Test(dataProvider = "sizes") + @Test(dataProvider = "sizes", groups = { "serialization-hostile" }) public void testLongStreamBuilder(int size) { testLongStreamBuilder(size, (s) -> { LongStream.Builder sb = LongStream.builder(); @@ -282,7 +282,7 @@ public class StreamBuilderTest extends OpTestCase { checkISE(() -> sb.build()); } - @Test(dataProvider = "sizes") + @Test(dataProvider = "sizes", groups = { "serialization-hostile" }) public void testDoubleStreamBuilder(int size) { testDoubleStreamBuilder(size, (s) -> { DoubleStream.Builder sb = DoubleStream.builder(); diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java index 04475e87260..5132d9d91ec 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java @@ -165,7 +165,8 @@ public class ToArrayOpTest extends OpTestCase { }; } - @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) + @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class, + groups = { "serialization-hostile" }) public void testStatefulOpPermutations(String name, TestData.OfRef data) { for (Function, Stream> f : statefulOpPermutations) { withData(data).terminal(f, s -> s.toArray()) From d95f70f9d384e5c13f431df20a9b8e6c5353ef57 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Thu, 3 Oct 2013 16:54:55 +0400 Subject: [PATCH 038/293] 8009213: sun/management/jdp/JdpTest.sh fails with exit code 1 There's no guarantee that the java process has executed far enough to be found by jps when we try to obtain it's pid. Reviewed-by: sla --- jdk/test/sun/management/jdp/JdpTest.sh | 32 ++++++++++++++++++-------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/jdk/test/sun/management/jdp/JdpTest.sh b/jdk/test/sun/management/jdp/JdpTest.sh index 3a0a74c37ee..12698e4a570 100644 --- a/jdk/test/sun/management/jdp/JdpTest.sh +++ b/jdk/test/sun/management/jdp/JdpTest.sh @@ -84,15 +84,29 @@ _app_start(){ ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} ${testappname} >> ${_logname} 2>&1 & _last_pid=$! - npid=`_get_pid` - if [ "${npid}" = "" ] - then - echo "ERROR: Test app not started. Please check machine resources before filing a bug." - if [ "${_jtreg}" = "yes" ] - then - exit 255 - fi - fi +# wait until VM is actually starts. +# please note, if vm doesn't start for some reason +# jtreg kills the test by timeout. Don't file a bug. + cnt=1 + while true + do + npid=`_get_pid` + if [ "${npid}" != "" ] + then + break + fi + if [ "${cnt}" = "10" ] + then + echo "ERROR: Test app not started. Please check machine resources before filing a bug." + if [ "${_jtreg}" = "yes" ] + then + exit 255 + fi + break + fi + cnt=`expr $cnt + 1` + sleep 1 + done } _get_pid(){ From ccbfbe87360b4b102196de037fca42289423ad34 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Thu, 3 Oct 2013 17:40:45 +0400 Subject: [PATCH 039/293] 8025738: locale related test fails on langtools mac 10.7 test host Reviewed-by: ksrini --- jdk/test/tools/launcher/DiacriticTest.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/jdk/test/tools/launcher/DiacriticTest.java b/jdk/test/tools/launcher/DiacriticTest.java index 44107bae42f..e43cedffc40 100644 --- a/jdk/test/tools/launcher/DiacriticTest.java +++ b/jdk/test/tools/launcher/DiacriticTest.java @@ -54,7 +54,13 @@ public class DiacriticTest extends TestHelper { "}\n"; ArrayList content = new ArrayList<>(); content.add(source); - createFile(sourceFile, content); + try { + createFile(sourceFile, content); + } catch (java.nio.file.InvalidPathException ipe) { + System.out.println("The locale or file system is configured in a way " + + "that prevents file creation. Real testing impossible."); + return; + } HashMap env = new HashMap<>(); env.put("LC_CTYPE", "UTF-8"); From 551b5e50c6ba047d3c2f115850f6aa60e34f5a5e Mon Sep 17 00:00:00 2001 From: Robert Field Date: Thu, 3 Oct 2013 10:23:48 -0700 Subject: [PATCH 040/293] 8010433: Remove lambda metafactory work-around to JDK-8005119 Restore invokespecial to lambda metafactory Reviewed-by: ksrini --- .../lang/invoke/AbstractValidatingLambdaMetafactory.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java index 92a44a048f3..793a2d13f01 100644 --- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java +++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java @@ -125,10 +125,7 @@ import static sun.invoke.util.Wrapper.isWrapperType; this.implMethod = implMethod; this.implInfo = caller.revealDirect(implMethod); - // @@@ Temporary work-around pending resolution of 8005119 - this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial) - ? MethodHandleInfo.REF_invokeVirtual - : implInfo.getReferenceKind(); + this.implKind = implInfo.getReferenceKind(); this.implIsInstanceMethod = implKind == MethodHandleInfo.REF_invokeVirtual || implKind == MethodHandleInfo.REF_invokeSpecial || From 1705cfa533b6ba2ec34807fcdd9eb9571b2b8551 Mon Sep 17 00:00:00 2001 From: Robert Field Date: Thu, 3 Oct 2013 11:26:53 -0700 Subject: [PATCH 041/293] 8020849: jdk/lambda/vm/DefaultMethodsTest.java Bridge generation has been removed from the VM. Fix is to remove tests that no longer make sense. Reviewed-by: ksrini --- .../jdk/lambda/vm/DefaultMethodsTest.java | 175 +----------------- 1 file changed, 1 insertion(+), 174 deletions(-) diff --git a/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java b/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java index a02ce752540..aabd8f9e697 100644 --- a/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java +++ b/jdk/test/jdk/lambda/vm/DefaultMethodsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -386,37 +386,6 @@ public class DefaultMethodsTest extends TestHarness { assertInvokeInterfaceEquals(99, C, I); } - /** - * interface I { default int m(T t) { return 99; } } - * Class C implements I { public int m() { return 88; } } - * - * TEST: C c = new C(); c.m() == 88; - * TEST: I i = new C(); i.m() == 88; - */ - public void testSelfFill() { - // This test ensures that a concrete method overrides a default method - // that matches at the language-level, but has a different method - // signature due to erasure. - - // debugTest(); - - DefaultMethod dm = new DefaultMethod( - "int", "m", "return 99;", new MethodParameter("T", "t")); - ConcreteMethod cm = new ConcreteMethod( - "int", "m", "return 88;", AccessFlag.PUBLIC, - new MethodParameter("String", "s")); - - Interface I = new Interface("I", new TypeParameter("T"), dm); - Class C = new Class("C", I.with("String"), cm); - - AbstractMethod pm = new AbstractMethod( - "int", "m", new MethodParameter("T", "t")); - - assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\""); - assertInvokeInterfaceEquals( - new Integer(88), C, I.with("String"), pm, "\"string\""); - } - /** * interface I { default int m() { return 99; } } * class C implements I {} @@ -470,58 +439,6 @@ public class DefaultMethodsTest extends TestHarness { compiler.cleanup(); } - /** - * interface I { default int m(T t, V v, W w) { return 99; } } - * interface J extends I { int m(T t, V v, String w); } } - * interface K extends J { int m(T t, String v, String w); } } - * class C implements K { - * public int m(String t, String v, String w) { return 88; } - * } - * - * TEST: I i = new C(); i.m("A","B","C") == 88; - * TEST: J j = new C(); j.m("A","B","C") == 88; - * TEST: K k = new C(); k.m("A","B","C") == 88; - */ - public void testBridges() { - DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;", - new MethodParameter("T", "t"), new MethodParameter("V", "v"), - new MethodParameter("W", "w")); - - AbstractMethod pm0 = new AbstractMethod("int", stdMethodName, - new MethodParameter("T", "t"), new MethodParameter("V", "v"), - new MethodParameter("W", "w")); - - AbstractMethod pm1 = new AbstractMethod("int", stdMethodName, - new MethodParameter("T", "t"), new MethodParameter("V", "v"), - new MethodParameter("String", "w")); - - AbstractMethod pm2 = new AbstractMethod("int", stdMethodName, - new MethodParameter("T", "t"), new MethodParameter("String", "v"), - new MethodParameter("String", "w")); - - ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;", - AccessFlag.PUBLIC, - new MethodParameter("String", "t"), - new MethodParameter("String", "v"), - new MethodParameter("String", "w")); - - Interface I = new Interface("I", new TypeParameter("T"), - new TypeParameter("V"), new TypeParameter("W"), dm); - Interface J = new Interface("J", - new TypeParameter("T"), new TypeParameter("V"), - I.with("String", "T", "V"), pm1); - Interface K = new Interface("K", new TypeParameter("T"), - J.with("String", "T"), pm2); - Class C = new Class("C", K.with("String"), cm); - - String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" }; - assertInvokeInterfaceEquals(new Integer(88), C, - I.with("String", "String", "String"), pm0, args); - assertInvokeInterfaceEquals(new Integer(88), C, - J.with("String", "String"), pm1, args); - assertInvokeInterfaceEquals(new Integer(88), C, - K.with("String"), pm2, args); - } /** * interface J { default int m() { return 88; } } @@ -663,33 +580,6 @@ public class DefaultMethodsTest extends TestHarness { "-1", "\"string\""); } - /** - * interface I { default Integer m() { return new Integer(88); } } - * class C { Number m() { return new Integer(99); } } - * class D extends C implements I {} - * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; - * TEST: S s = new S(); s.foo() == new Integer(99) - */ - public void testCovarBridge() { - Interface I = new Interface("I", new DefaultMethod( - "Integer", "m", "return new Integer(88);")); - Class C = new Class("C", new ConcreteMethod( - "Number", "m", "return new Integer(99);", AccessFlag.PUBLIC)); - Class D = new Class("D", I, C); - - ConcreteMethod DstubMethod = new ConcreteMethod( - "Integer", "m", "return null;", AccessFlag.PUBLIC); - Class Dstub = new Class("D", DstubMethod); - - ConcreteMethod toCall = new ConcreteMethod( - "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC); - Class S = new Class("S", D, toCall); - S.addCompilationDependency(Dstub); - S.addCompilationDependency(DstubMethod); - - assertInvokeVirtualEquals(new Integer(99), S, toCall, "null"); - } - /** * interface I { default Integer m() { return new Integer(88); } } * class C { int m() { return 99; } } @@ -737,69 +627,6 @@ public class DefaultMethodsTest extends TestHarness { assertInvokeVirtualEquals(99, C); } - /** - * interface I { int m(T t, V v, W w); } - * interface J implements I { int m(T t, V v, String w); } - * interface K implements J { - * int m(T t, String v, String w); { return 99; } } - * class C implements K { - * public int m(Object t, Object v, String w) { return 77; } - * } - * TEST C = new C(); ((I)c).m(Object,Object,Object) == 99 - * TEST C = new C(); ((J)c).m(Object,Object,String) == 77 - * TEST C = new C(); ((K)c).m(Object,String,String) == 99 - * - * Test that a erased-signature-matching method does not implement - * non-language-level matching methods - */ - public void testNonConcreteFill() { - AbstractMethod ipm = new AbstractMethod("int", "m", - new MethodParameter("T", "t"), - new MethodParameter("V", "s"), - new MethodParameter("W", "w")); - Interface I = new Interface("I", - new TypeParameter("T"), - new TypeParameter("V"), - new TypeParameter("W"), ipm); - - AbstractMethod jpm = new AbstractMethod("int", "m", - new MethodParameter("T", "t"), - new MethodParameter("V", "s"), - new MethodParameter("String", "w")); - Interface J = new Interface("J", - new TypeParameter("T"), - new TypeParameter("V"), - I.with("T", "V", "String"), jpm); - - AbstractMethod kpm = new AbstractMethod("int", "m", - new MethodParameter("T", "t"), - new MethodParameter("String", "s"), - new MethodParameter("String", "w")); - Interface K = new Interface("K", - new TypeParameter("T"), - J.with("T", "String"), - new DefaultMethod("int", "m", "return 99;", - new MethodParameter("T", "t"), - new MethodParameter("String", "v"), - new MethodParameter("String", "w"))); - - Class C = new Class("C", - K.with("String"), - new ConcreteMethod("int", "m", "return 77;", - AccessFlag.PUBLIC, - new MethodParameter("Object", "t"), - new MethodParameter("Object", "v"), - new MethodParameter("String", "w"))); - - String a = "\"\""; - assertInvokeInterfaceEquals(99, C, - K.with("String"), kpm, a, a, a); - assertInvokeInterfaceEquals(77, C, - J.with("String", "String"), jpm, a, a, a); - assertInvokeInterfaceEquals(99, C, - I.with("String", "String", "String"), ipm, a, a, a); - } - public void testStrictfpDefault() { try { java.lang.Class.forName("vm.StrictfpDefault"); From a4b39faa4fd60cc8171d7c81fd209b4e51590b53 Mon Sep 17 00:00:00 2001 From: Paul Rank Date: Thu, 22 Aug 2013 10:01:47 -0700 Subject: [PATCH 042/293] 8024896: Refactor java.time serialization tests into separate subpackage Move serialization tests to .serial subpackage Reviewed-by: sherman --- .../java/time/tck/java/time/TCKDuration.java | 20 -- .../java/time/tck/java/time/TCKInstant.java | 18 -- .../java/time/tck/java/time/TCKLocalDate.java | 22 -- .../time/tck/java/time/TCKLocalDateTime.java | 25 -- .../java/time/tck/java/time/TCKLocalTime.java | 57 ---- .../java/time/tck/java/time/TCKMonthDay.java | 18 -- .../time/tck/java/time/TCKOffsetDateTime.java | 37 --- .../time/tck/java/time/TCKOffsetTime.java | 34 --- .../java/time/tck/java/time/TCKPeriod.java | 8 - jdk/test/java/time/tck/java/time/TCKYear.java | 19 -- .../java/time/tck/java/time/TCKYearMonth.java | 18 -- .../java/time/tck/java/time/TCKZoneId.java | 104 ------- .../time/tck/java/time/TCKZoneOffset.java | 40 --- .../time/tck/java/time/TCKZonedDateTime.java | 48 ---- .../java/time/chrono/TCKChronoLocalDate.java | 17 -- .../time/chrono/TCKChronoLocalDateTime.java | 17 -- .../chrono/serial/TCKChronoLocalDate.java | 111 ++++++++ .../chrono/serial/TCKChronoLocalDateTime.java | 110 ++++++++ .../TCKChronologySerialization.java | 8 +- .../tck/java/time/serial/TCKDuration.java | 95 +++++++ .../time/tck/java/time/serial/TCKInstant.java | 95 +++++++ .../tck/java/time/serial/TCKLocalDate.java | 107 +++++++ .../java/time/serial/TCKLocalDateTime.java | 104 +++++++ .../tck/java/time/serial/TCKLocalTime.java | 145 ++++++++++ .../tck/java/time/serial/TCKMonthDay.java | 107 +++++++ .../java/time/serial/TCKOffsetDateTime.java | 127 +++++++++ .../tck/java/time/serial/TCKOffsetTime.java | 122 ++++++++ .../time/tck/java/time/serial/TCKPeriod.java | 82 ++++++ .../time/tck/java/time/serial/TCKYear.java | 94 +++++++ .../tck/java/time/serial/TCKYearMonth.java | 106 +++++++ .../time/tck/java/time/serial/TCKZoneId.java | 263 ++++++++++++++++++ .../tck/java/time/serial/TCKZoneOffset.java | 118 ++++++++ .../java/time/serial/TCKZonedDateTime.java | 143 ++++++++++ .../tck/java/time/temporal/TCKWeekFields.java | 6 - .../time/temporal/serial/TCKWeekFields.java | 94 +++++++ .../tck/java/time/zone/TCKFixedZoneRules.java | 18 -- .../time/zone/TCKZoneOffsetTransition.java | 14 - .../zone/TCKZoneOffsetTransitionRule.java | 25 -- .../time/tck/java/time/zone/TCKZoneRules.java | 21 -- .../time/zone/serial/TCKFixedZoneRules.java | 117 ++++++++ .../zone/serial/TCKZoneOffsetTransition.java | 91 ++++++ .../serial/TCKZoneOffsetTransitionRule.java | 114 ++++++++ .../java/time/zone/serial/TCKZoneRules.java | 122 ++++++++ 43 files changed, 2471 insertions(+), 590 deletions(-) create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java rename jdk/test/java/time/tck/java/time/chrono/{ => serial}/TCKChronologySerialization.java (96%) create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKDuration.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKInstant.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKPeriod.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKYear.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKZoneId.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java create mode 100644 jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java diff --git a/jdk/test/java/time/tck/java/time/TCKDuration.java b/jdk/test/java/time/tck/java/time/TCKDuration.java index bae2cf69805..c3bb0c9c906 100644 --- a/jdk/test/java/time/tck/java/time/TCKDuration.java +++ b/jdk/test/java/time/tck/java/time/TCKDuration.java @@ -103,26 +103,6 @@ public class TCKDuration extends AbstractTCKTest { private static final long CYCLE_SECS = 146097L * 86400L; - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Duration.ofHours(5)); - assertSerializable(Duration.ofHours(0)); - assertSerializable(Duration.ofHours(-5)); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(1); - dos.writeLong(654321); - dos.writeInt(123456789); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKInstant.java b/jdk/test/java/time/tck/java/time/TCKInstant.java index 05d7b83fcf1..bb3a765de42 100644 --- a/jdk/test/java/time/tck/java/time/TCKInstant.java +++ b/jdk/test/java/time/tck/java/time/TCKInstant.java @@ -154,24 +154,6 @@ public class TCKInstant extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Instant.ofEpochMilli(134l)); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(2); - dos.writeLong(654321); - dos.writeInt(123456789); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(Instant.ofEpochSecond(654321, 123456789), bytes); - } - //----------------------------------------------------------------------- private void check(Instant instant, long epochSecs, int nos) { assertEquals(instant.getEpochSecond(), epochSecs); diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/TCKLocalDate.java index 597dd4f6574..3d4cbbbc884 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java @@ -196,28 +196,6 @@ public class TCKLocalDate extends AbstractDateTimeTest { return list; } - - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_2007_07_15); - assertSerializable(LocalDate.MIN); - assertSerializable(LocalDate.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(3); - dos.writeInt(2012); - dos.writeByte(9); - dos.writeByte(16); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes); - } - //----------------------------------------------------------------------- private void check(LocalDate test, int y, int m, int d) { assertEquals(test.getYear(), y); diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java index f55bdb4a961..040704cd9bc 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java @@ -241,31 +241,6 @@ public class TCKLocalDateTime extends AbstractDateTimeTest { return LocalDateTime.of(year, month, day, 0, 0); } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_2007_07_15_12_30_40_987654321); - assertSerializable(LocalDateTime.MIN); - assertSerializable(LocalDateTime.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(5); - dos.writeInt(2012); - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(459_000_000); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java index dbba80d1cec..2291b5ca16b 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java @@ -191,64 +191,7 @@ public class TCKLocalTime extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_12_30_40_987654321); - assertSerializable(LocalTime.MIN); - assertSerializable(LocalTime.MAX); - } - @Test - public void test_serialization_format_h() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(-1 - 22); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 0), bytes); - } - - @Test - public void test_serialization_format_hm() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(-1 - 17); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 17), bytes); - } - - @Test - public void test_serialization_format_hms() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(-1 - 59); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 17, 59), bytes); - } - - @Test - public void test_serialization_format_hmsn() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(459_000_000); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(LocalTime.of(22, 17, 59, 459_000_000), bytes); - } - - //----------------------------------------------------------------------- private void check(LocalTime test, int h, int m, int s, int n) { assertEquals(test.getHour(), h); assertEquals(test.getMinute(), m); diff --git a/jdk/test/java/time/tck/java/time/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/TCKMonthDay.java index f2a2b93f473..e9b1730cb71 100644 --- a/jdk/test/java/time/tck/java/time/TCKMonthDay.java +++ b/jdk/test/java/time/tck/java/time/TCKMonthDay.java @@ -136,24 +136,6 @@ public class TCKMonthDay extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws ClassNotFoundException, IOException { - assertSerializable(TEST_07_15); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(13); // java.time.temporal.Ser.MONTH_DAY_TYPE - dos.writeByte(9); - dos.writeByte(16); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(MonthDay.of(9, 16), bytes); - } - //----------------------------------------------------------------------- void check(MonthDay test, int m, int d) { assertEquals(test.getMonth().getValue(), m); diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java index 7cfc2a61dec..0cf024fdde1 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java @@ -209,43 +209,6 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_2008_6_30_11_30_59_000000500); - assertSerializable(OffsetDateTime.MIN); - assertSerializable(OffsetDateTime.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(10); // java.time.Ser.OFFSET_DATE_TIME_TYPE - } - byte[] bytes = baos.toByteArray(); - ByteArrayOutputStream baosDateTime = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosDateTime) ) { - dos.writeByte(5); - dos.writeInt(2012); - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(464_000_000); - } - byte[] bytesDateTime = baosDateTime.toByteArray(); - ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { - dos.writeByte(8); - dos.writeByte(4); // quarter hours stored: 3600 / 900 - } - byte[] bytesOffset = baosOffset.toByteArray(); - LocalDateTime ldt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 464_000_000); - assertSerializedBySer(OffsetDateTime.of(ldt, ZoneOffset.ofHours(1)), bytes, bytesDateTime, bytesOffset); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java index b3d7e5b26a9..ee5b2d3f69f 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java @@ -183,40 +183,6 @@ public class TCKOffsetTime extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(TEST_11_30_59_500_PONE); - assertSerializable(OffsetTime.MIN); - assertSerializable(OffsetTime.MAX); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(9); // java.time.Ser.OFFSET_TIME_TYPE - } - byte[] bytes = baos.toByteArray(); - ByteArrayOutputStream baosTime = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosTime) ) { - dos.writeByte(4); - dos.writeByte(22); - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(464_000_000); - } - byte[] bytesTime = baosTime.toByteArray(); - ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { - dos.writeByte(8); - dos.writeByte(4); // quarter hours stored: 3600 / 900 - } - byte[] bytesOffset = baosOffset.toByteArray(); - assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes, - bytesTime, bytesOffset); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKPeriod.java b/jdk/test/java/time/tck/java/time/TCKPeriod.java index 7a06b95e6ef..3a1fe42ec45 100644 --- a/jdk/test/java/time/tck/java/time/TCKPeriod.java +++ b/jdk/test/java/time/tck/java/time/TCKPeriod.java @@ -86,14 +86,6 @@ import org.testng.annotations.Test; @Test public class TCKPeriod extends AbstractTCKTest { - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Period.ZERO); - assertSerializable(Period.ofDays(1)); - assertSerializable(Period.of(1, 2, 3)); - } - //----------------------------------------------------------------------- // ofYears(int) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKYear.java b/jdk/test/java/time/tck/java/time/TCKYear.java index 53f0db0b56e..c0a35967a7b 100644 --- a/jdk/test/java/time/tck/java/time/TCKYear.java +++ b/jdk/test/java/time/tck/java/time/TCKYear.java @@ -151,25 +151,6 @@ public class TCKYear extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(Year.of(2)); - assertSerializable(Year.of(0)); - assertSerializable(Year.of(-2)); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(11); // java.time.temporal.Ser.YEAR_TYPE - dos.writeInt(2012); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(Year.of(2012), bytes); - } - //----------------------------------------------------------------------- // now() //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/TCKYearMonth.java index 66f691b0746..e1f1a466574 100644 --- a/jdk/test/java/time/tck/java/time/TCKYearMonth.java +++ b/jdk/test/java/time/tck/java/time/TCKYearMonth.java @@ -156,24 +156,6 @@ public class TCKYearMonth extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws IOException, ClassNotFoundException { - assertSerializable(TEST_2008_06); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(12); // java.time.temporal.Ser.YEAR_MONTH_TYPE - dos.writeInt(2012); - dos.writeByte(9); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(YearMonth.of(2012, 9), bytes); - } - //----------------------------------------------------------------------- void check(YearMonth test, int y, int m) { assertEquals(test.getYear(), y); diff --git a/jdk/test/java/time/tck/java/time/TCKZoneId.java b/jdk/test/java/time/tck/java/time/TCKZoneId.java index c63b393d29d..0d47403db4e 100644 --- a/jdk/test/java/time/tck/java/time/TCKZoneId.java +++ b/jdk/test/java/time/tck/java/time/TCKZoneId.java @@ -92,110 +92,6 @@ import org.testng.annotations.Test; @Test public class TCKZoneId extends AbstractTCKTest { - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(ZoneId.of("Europe/London")); - assertSerializable(ZoneId.of("America/Chicago")); - } - - @Test - public void test_serialization_format() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(7); - dos.writeUTF("Europe/London"); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneId.of("Europe/London"), bytes); - } - - @Test - public void test_deserialization_lenient_characters() throws Exception { - // an ID can be loaded without validation during deserialization - String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-"; - ZoneId deser = deserialize(id); - // getId, equals, hashCode, toString and normalized are OK - assertEquals(deser.getId(), id); - assertEquals(deser.toString(), id); - assertEquals(deser, deser); - assertEquals(deser.hashCode(), deser.hashCode()); - assertEquals(deser.normalized(), deser); - // getting the rules is not - try { - deser.getRules(); - fail(); - } catch (ZoneRulesException ex) { - // expected - } - } - - @Test(expectedExceptions=DateTimeException.class) - public void test_deserialization_lenient_badCharacters() throws Exception { - // an ID can be loaded without validation during deserialization - // but there is a check to ensure the ID format is valid - deserialize("|!?"); - } - - @Test(dataProvider="offsetBasedValid") - public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception { - ZoneId deserialized = deserialize(input); - assertEquals(deserialized, ZoneId.of(input)); - assertEquals(deserialized, ZoneId.of(resolvedId)); - } - - @Test(dataProvider="offsetBasedValidPrefix") - public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId, String offsetId) throws Exception { - ZoneId deserialized = deserialize("UTC" + input); - assertEquals(deserialized, ZoneId.of("UTC" + input)); - assertEquals(deserialized, ZoneId.of("UTC" + resolvedId)); - } - - @Test(dataProvider="offsetBasedValidPrefix") - public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId, String offsetId) throws Exception { - ZoneId deserialized = deserialize("GMT" + input); - assertEquals(deserialized, ZoneId.of("GMT" + input)); - assertEquals(deserialized, ZoneId.of("GMT" + resolvedId)); - } - - @Test(dataProvider="offsetBasedValidPrefix") - public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId, String offsetId) throws Exception { - ZoneId deserialized = deserialize("UT" + input); - assertEquals(deserialized, ZoneId.of("UT" + input)); - assertEquals(deserialized, ZoneId.of("UT" + resolvedId)); - } - - private ZoneId deserialize(String id) throws Exception { - String serClass = ZoneId.class.getPackage().getName() + ".Ser"; - Class serCls = Class.forName(serClass); - Field field = serCls.getDeclaredField("serialVersionUID"); - field.setAccessible(true); - long serVer = (Long) field.get(null); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos)) { - dos.writeShort(ObjectStreamConstants.STREAM_MAGIC); - dos.writeShort(ObjectStreamConstants.STREAM_VERSION); - dos.writeByte(ObjectStreamConstants.TC_OBJECT); - dos.writeByte(ObjectStreamConstants.TC_CLASSDESC); - dos.writeUTF(serClass); - dos.writeLong(serVer); - dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA); - dos.writeShort(0); // number of fields - dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of classdesc - dos.writeByte(ObjectStreamConstants.TC_NULL); // no superclasses - dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); - dos.writeByte(1 + 2 + id.length()); // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF) - dos.writeByte(7); // ZoneId - dos.writeUTF(id); - dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of blockdata - } - ZoneId deser = null; - try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { - deser = (ZoneId) ois.readObject(); - } - return deser; - } - //----------------------------------------------------------------------- // OLD_SHORT_IDS //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java index 94f2eb52e64..cf9098a188b 100644 --- a/jdk/test/java/time/tck/java/time/TCKZoneOffset.java +++ b/jdk/test/java/time/tck/java/time/TCKZoneOffset.java @@ -120,46 +120,6 @@ public class TCKZoneOffset extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws Exception { - assertSerializable(ZoneOffset.of("+01:30")); - } - - @Test - public void test_serialization_format_quarterPositive() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(8); - dos.writeByte(6); // stored as quarter hours - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneOffset.ofHoursMinutes(1, 30), bytes); - } - - @Test - public void test_serialization_format_quarterNegative() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(8); - dos.writeByte(-10); // stored as quarter hours - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneOffset.ofHoursMinutes(-2, -30), bytes); - } - - @Test - public void test_serialization_format_full() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(8); - dos.writeByte(127); - dos.writeInt(53265); - } - byte[] bytes = baos.toByteArray(); - assertSerializedBySer(ZoneOffset.ofTotalSeconds(53265), bytes); - } - //----------------------------------------------------------------------- // constants //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java index d1db67fca90..1f5bee32283 100644 --- a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java @@ -222,54 +222,6 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { return list; } - //----------------------------------------------------------------------- - @Test - public void test_serialization() throws ClassNotFoundException, IOException { - assertSerializable(TEST_DATE_TIME); - } - - @Test - public void test_serialization_format_zoneId() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(6); - dos.writeInt(2012); // date - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); // time - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(470_000_000); - dos.writeByte(4); // offset - dos.writeByte(7); // zoneId - dos.writeUTF("Europe/London"); - } - byte[] bytes = baos.toByteArray(); - ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneId.of("Europe/London")); - assertSerializedBySer(zdt, bytes); - } - - @Test - public void test_serialization_format_zoneOffset() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream dos = new DataOutputStream(baos) ) { - dos.writeByte(6); - dos.writeInt(2012); // date - dos.writeByte(9); - dos.writeByte(16); - dos.writeByte(22); // time - dos.writeByte(17); - dos.writeByte(59); - dos.writeInt(470_000_000); - dos.writeByte(4); // offset - dos.writeByte(8); // zoneId - dos.writeByte(4); - } - byte[] bytes = baos.toByteArray(); - ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneOffset.ofHours(1)); - assertSerializedBySer(zdt, bytes); - } - //----------------------------------------------------------------------- // now() //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java index 92f083ef6f4..32001354ff2 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java @@ -306,23 +306,6 @@ public class TCKChronoLocalDate { } } - //----------------------------------------------------------------------- - // Test Serialization of Calendars - //----------------------------------------------------------------------- - @Test( dataProvider="calendars") - public void test_ChronoSerialization(Chronology chrono) throws Exception { - LocalDate ref = LocalDate.of(2013, 1, 5); - ChronoLocalDate orginal = chrono.date(ref); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); - } //----------------------------------------------------------------------- @Test(dataProvider="calendars") diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java index 129a1903998..7ca03e2e3fb 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java @@ -317,23 +317,6 @@ public class TCKChronoLocalDateTime { } } - //----------------------------------------------------------------------- - // Test Serialization of ISO via chrono API - //----------------------------------------------------------------------- - @Test( dataProvider="calendars") - public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception { - LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3); - ChronoLocalDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - ChronoLocalDateTime ser = (ChronoLocalDateTime) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); - } - //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_from_TemporalAccessor(Chronology chrono) { diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java new file mode 100644 index 00000000000..4bec5cdc952 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.LocalDate; +import java.time.chrono.*; + +import static org.testng.Assert.assertEquals; + +/** + * Test assertions that must be true for all built-in chronologies. + */ +@Test +public class TCKChronoLocalDate { + + //----------------------------------------------------------------------- + // regular data factory for names and descriptions of available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Chronology[][] data_of_calendars() { + return new Chronology[][]{ + {HijrahChronology.INSTANCE}, + {IsoChronology.INSTANCE}, + {JapaneseChronology.INSTANCE}, + {MinguoChronology.INSTANCE}, + {ThaiBuddhistChronology.INSTANCE}}; + } + + + //----------------------------------------------------------------------- + // Test Serialization of Calendars + //----------------------------------------------------------------------- + @Test( dataProvider="calendars") + public void test_ChronoSerialization(Chronology chrono) throws Exception { + LocalDate ref = LocalDate.of(2013, 1, 5); + ChronoLocalDate orginal = chrono.date(ref); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(orginal); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + @SuppressWarnings("unchecked") + ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); + assertEquals(ser, orginal, "deserialized date is wrong"); + } + + //----------------------------------------------------------------------- + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java new file mode 100644 index 00000000000..1ab1cda92c5 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.chrono.*; + +import static org.testng.Assert.assertEquals; + +/** + * Test assertions that must be true for all built-in chronologies. + */ +@Test +public class TCKChronoLocalDateTime { + + //----------------------------------------------------------------------- + // regular data factory for available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Chronology[][] data_of_calendars() { + return new Chronology[][]{ + {HijrahChronology.INSTANCE}, + {IsoChronology.INSTANCE}, + {JapaneseChronology.INSTANCE}, + {MinguoChronology.INSTANCE}, + {ThaiBuddhistChronology.INSTANCE}}; + } + + //----------------------------------------------------------------------- + // Test Serialization ZonedDateTime for each Chronology + //----------------------------------------------------------------------- + @Test( dataProvider="calendars") + public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception { + LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3); + ChronoLocalDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(orginal); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream in = new ObjectInputStream(bais); + ChronoLocalDateTime ser = (ChronoLocalDateTime) in.readObject(); + assertEquals(ser, orginal, "deserialized date is wrong"); + } + + //----------------------------------------------------------------------- + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java rename to jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java index 35620ad755e..aed919adafa 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java @@ -54,7 +54,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package tck.java.time.chrono; +package tck.java.time.chrono.serial; import static org.testng.Assert.assertEquals; @@ -73,6 +73,7 @@ import java.time.chrono.ThaiBuddhistChronology; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +@Test public class TCKChronologySerialization { //----------------------------------------------------------------------- @@ -93,13 +94,12 @@ public class TCKChronologySerialization { //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_ChronoSerialization(Chronology chrono) throws Exception { + System.out.printf(" ChronoSerialization: %s%n", chrono); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(baos); out.writeObject(chrono); out.close(); - - byte[] bytes = baos.toByteArray(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bais); @SuppressWarnings("unchecked") diff --git a/jdk/test/java/time/tck/java/time/serial/TCKDuration.java b/jdk/test/java/time/tck/java/time/serial/TCKDuration.java new file mode 100644 index 00000000000..e4a9a3f9a18 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKDuration.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.Duration; + +/** + * Test Duration. + */ +@Test +public class TCKDuration extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Duration.ofHours(5)); + assertSerializable(Duration.ofHours(0)); + assertSerializable(Duration.ofHours(-5)); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(1); + dos.writeLong(654321); + dos.writeInt(123456789); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes); + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKInstant.java b/jdk/test/java/time/tck/java/time/serial/TCKInstant.java new file mode 100644 index 00000000000..783ad586375 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKInstant.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.Instant; + +/** + * Test Instant. + */ +@Test +public class TCKInstant extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Instant.ofEpochMilli(134l)); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(2); + dos.writeLong(654321); + dos.writeInt(123456789); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(Instant.ofEpochSecond(654321, 123456789), bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java new file mode 100644 index 00000000000..aeaa96d372d --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalDate; + +/** + * Test LocalDate. + */ +@Test +public class TCKLocalDate extends AbstractTCKTest { + + private LocalDate TEST_2007_07_15; + + @BeforeMethod + public void setUp() { + TEST_2007_07_15 = LocalDate.of(2007, 7, 15); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_2007_07_15); + assertSerializable(LocalDate.MIN); + assertSerializable(LocalDate.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(3); + dos.writeInt(2012); + dos.writeByte(9); + dos.writeByte(16); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes); + } + + //----------------------------------------------------------------------- + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java new file mode 100644 index 00000000000..a2ae9d2357c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalDateTime; + +/** + * Test LocalDateTime. + */ +@Test +public class TCKLocalDateTime extends AbstractTCKTest { + + private LocalDateTime TEST_2007_07_15_12_30_40_987654321 = LocalDateTime.of(2007, 7, 15, 12, 30, 40, 987654321); + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_2007_07_15_12_30_40_987654321); + assertSerializable(LocalDateTime.MIN); + assertSerializable(LocalDateTime.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(5); + dos.writeInt(2012); + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(459_000_000); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes); + } + + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java new file mode 100644 index 00000000000..06f2ce4c898 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalTime; + +/** + * Test LocalTime. + */ +@Test +public class TCKLocalTime extends AbstractTCKTest { + + + private LocalTime TEST_12_30_40_987654321; + + + @BeforeMethod + public void setUp() { + TEST_12_30_40_987654321 = LocalTime.of(12, 30, 40, 987654321); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_12_30_40_987654321); + assertSerializable(LocalTime.MIN); + assertSerializable(LocalTime.MAX); + } + + @Test + public void test_serialization_format_h() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(-1 - 22); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 0), bytes); + } + + @Test + public void test_serialization_format_hm() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(-1 - 17); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 17), bytes); + } + + @Test + public void test_serialization_format_hms() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(-1 - 59); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 17, 59), bytes); + } + + @Test + public void test_serialization_format_hmsn() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(459_000_000); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(LocalTime.of(22, 17, 59, 459_000_000), bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java new file mode 100644 index 00000000000..cd441663099 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.MonthDay; + +/** + * Test MonthDay. + */ +@Test +public class TCKMonthDay extends AbstractTCKTest { + + private MonthDay TEST_07_15; + + @BeforeMethod + public void setUp() { + TEST_07_15 = MonthDay.of(7, 15); + } + + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws ClassNotFoundException, IOException { + assertSerializable(TEST_07_15); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(13); // java.time.temporal.Ser.MONTH_DAY_TYPE + dos.writeByte(9); + dos.writeByte(16); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(MonthDay.of(9, 16), bytes); + } + + //----------------------------------------------------------------------- + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java new file mode 100644 index 00000000000..8a1406b8727 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Test OffsetDateTime. + */ +@Test +public class TCKOffsetDateTime extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); + private OffsetDateTime TEST_2008_6_30_11_30_59_000000500; + + @BeforeMethod + public void setUp() { + TEST_2008_6_30_11_30_59_000000500 = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 500, OFFSET_PONE); + } + + //----------------------------------------------------------------------- + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_2008_6_30_11_30_59_000000500); + assertSerializable(OffsetDateTime.MIN); + assertSerializable(OffsetDateTime.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(10); // java.time.Ser.OFFSET_DATE_TIME_TYPE + } + byte[] bytes = baos.toByteArray(); + ByteArrayOutputStream baosDateTime = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosDateTime) ) { + dos.writeByte(5); + dos.writeInt(2012); + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(464_000_000); + } + byte[] bytesDateTime = baosDateTime.toByteArray(); + ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { + dos.writeByte(8); + dos.writeByte(4); // quarter hours stored: 3600 / 900 + } + byte[] bytesOffset = baosOffset.toByteArray(); + LocalDateTime ldt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 464_000_000); + assertSerializedBySer(OffsetDateTime.of(ldt, ZoneOffset.ofHours(1)), bytes, bytesDateTime, bytesOffset); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java new file mode 100644 index 00000000000..6bdddba2fb3 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.OffsetTime; +import java.time.ZoneOffset; + +/** + * Test OffsetTime. + */ +@Test +public class TCKOffsetTime extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); + private OffsetTime TEST_11_30_59_500_PONE; + + @BeforeMethod + public void setUp() { + TEST_11_30_59_500_PONE = OffsetTime.of(11, 30, 59, 500, OFFSET_PONE); + } + + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(TEST_11_30_59_500_PONE); + assertSerializable(OffsetTime.MIN); + assertSerializable(OffsetTime.MAX); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(9); // java.time.Ser.OFFSET_TIME_TYPE + } + byte[] bytes = baos.toByteArray(); + ByteArrayOutputStream baosTime = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosTime) ) { + dos.writeByte(4); + dos.writeByte(22); + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(464_000_000); + } + byte[] bytesTime = baosTime.toByteArray(); + ByteArrayOutputStream baosOffset = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baosOffset) ) { + dos.writeByte(8); + dos.writeByte(4); // quarter hours stored: 3600 / 900 + } + byte[] bytesOffset = baosOffset.toByteArray(); + assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes, + bytesTime, bytesOffset); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java b/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java new file mode 100644 index 00000000000..2f94df132f0 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.time.Period; + +/** + * Test Period. + */ +@Test +public class TCKPeriod extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Period.ZERO); + assertSerializable(Period.ofDays(1)); + assertSerializable(Period.of(1, 2, 3)); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYear.java b/jdk/test/java/time/tck/java/time/serial/TCKYear.java new file mode 100644 index 00000000000..954dacf0c99 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKYear.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.Year; + +/** + * Test Year. + */ +@Test +public class TCKYear extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(Year.of(2)); + assertSerializable(Year.of(0)); + assertSerializable(Year.of(-2)); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(11); // java.time.temporal.Ser.YEAR_TYPE + dos.writeInt(2012); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(Year.of(2012), bytes); + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java new file mode 100644 index 00000000000..675767d976c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.YearMonth; + +/** + * Test YearMonth. + */ +@Test +public class TCKYearMonth extends AbstractTCKTest { + + private YearMonth TEST_2008_06; + + @BeforeMethod + public void setUp() { + TEST_2008_06 = YearMonth.of(2008, 6); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws IOException, ClassNotFoundException { + assertSerializable(TEST_2008_06); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(12); // java.time.temporal.Ser.YEAR_MONTH_TYPE + dos.writeInt(2012); + dos.writeByte(9); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(YearMonth.of(2012, 9), bytes); + } + + //----------------------------------------------------------------------- + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java new file mode 100644 index 00000000000..26923f12a80 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.*; +import java.lang.reflect.Field; +import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.zone.ZoneRulesException; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + +/** + * Test ZoneId. + */ +@Test +public class TCKZoneId extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(ZoneId.of("Europe/London")); + assertSerializable(ZoneId.of("America/Chicago")); + } + + @Test + public void test_serialization_format() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(7); + dos.writeUTF("Europe/London"); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneId.of("Europe/London"), bytes); + } + + @Test + public void test_deserialization_lenient_characters() throws Exception { + // an ID can be loaded without validation during deserialization + String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-"; + ZoneId deser = deserialize(id); + // getId, equals, hashCode, toString and normalized are OK + assertEquals(deser.getId(), id); + assertEquals(deser.toString(), id); + assertEquals(deser, deser); + assertEquals(deser.hashCode(), deser.hashCode()); + assertEquals(deser.normalized(), deser); + // getting the rules is not + try { + deser.getRules(); + fail(); + } catch (ZoneRulesException ex) { + // expected + } + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_deserialization_lenient_badCharacters() throws Exception { + // an ID can be loaded without validation during deserialization + // but there is a check to ensure the ID format is valid + deserialize("|!?"); + } + + @Test(dataProvider="offsetBasedValid") + public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception { + ZoneId deserialized = deserialize(input); + assertEquals(deserialized, ZoneId.of(input)); + assertEquals(deserialized, ZoneId.of(resolvedId)); + } + + @Test(dataProvider="offsetBasedValidPrefix") + public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId, String offsetId) throws Exception { + ZoneId deserialized = deserialize("UTC" + input); + assertEquals(deserialized, ZoneId.of("UTC" + input)); + assertEquals(deserialized, ZoneId.of("UTC" + resolvedId)); + } + + @Test(dataProvider="offsetBasedValidPrefix") + public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId, String offsetId) throws Exception { + ZoneId deserialized = deserialize("GMT" + input); + assertEquals(deserialized, ZoneId.of("GMT" + input)); + assertEquals(deserialized, ZoneId.of("GMT" + resolvedId)); + } + + @Test(dataProvider="offsetBasedValidPrefix") + public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId, String offsetId) throws Exception { + ZoneId deserialized = deserialize("UT" + input); + assertEquals(deserialized, ZoneId.of("UT" + input)); + assertEquals(deserialized, ZoneId.of("UT" + resolvedId)); + } + + private ZoneId deserialize(String id) throws Exception { + String serClass = ZoneId.class.getPackage().getName() + ".Ser"; + Class serCls = Class.forName(serClass); + Field field = serCls.getDeclaredField("serialVersionUID"); + field.setAccessible(true); + long serVer = (Long) field.get(null); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos)) { + dos.writeShort(ObjectStreamConstants.STREAM_MAGIC); + dos.writeShort(ObjectStreamConstants.STREAM_VERSION); + dos.writeByte(ObjectStreamConstants.TC_OBJECT); + dos.writeByte(ObjectStreamConstants.TC_CLASSDESC); + dos.writeUTF(serClass); + dos.writeLong(serVer); + dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA); + dos.writeShort(0); // number of fields + dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of classdesc + dos.writeByte(ObjectStreamConstants.TC_NULL); // no superclasses + dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); + dos.writeByte(1 + 2 + id.length()); // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF) + dos.writeByte(7); // ZoneId + dos.writeUTF(id); + dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of blockdata + } + ZoneId deser = null; + try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { + deser = (ZoneId) ois.readObject(); + } + return deser; + } + + //----------------------------------------------------------------------- + // regular factory and .normalized() + //----------------------------------------------------------------------- + @DataProvider(name="offsetBasedValid") + Object[][] data_offsetBasedValid() { + return new Object[][] { + {"Z", "Z"}, + {"+0", "Z"}, + {"-0", "Z"}, + {"+00", "Z"}, + {"+0000", "Z"}, + {"+00:00", "Z"}, + {"+000000", "Z"}, + {"+00:00:00", "Z"}, + {"-00", "Z"}, + {"-0000", "Z"}, + {"-00:00", "Z"}, + {"-000000", "Z"}, + {"-00:00:00", "Z"}, + {"+5", "+05:00"}, + {"+01", "+01:00"}, + {"+0100", "+01:00"}, + {"+01:00", "+01:00"}, + {"+010000", "+01:00"}, + {"+01:00:00", "+01:00"}, + {"+12", "+12:00"}, + {"+1234", "+12:34"}, + {"+12:34", "+12:34"}, + {"+123456", "+12:34:56"}, + {"+12:34:56", "+12:34:56"}, + {"-02", "-02:00"}, + {"-5", "-05:00"}, + {"-0200", "-02:00"}, + {"-02:00", "-02:00"}, + {"-020000", "-02:00"}, + {"-02:00:00", "-02:00"}, + }; + } + + //----------------------------------------------------------------------- + @DataProvider(name="offsetBasedValidPrefix") + Object[][] data_offsetBasedValidPrefix() { + return new Object[][] { + {"", "", "Z"}, + {"+0", "", "Z"}, + {"-0", "", "Z"}, + {"+00", "", "Z"}, + {"+0000", "", "Z"}, + {"+00:00", "", "Z"}, + {"+000000", "", "Z"}, + {"+00:00:00", "", "Z"}, + {"-00", "", "Z"}, + {"-0000", "", "Z"}, + {"-00:00", "", "Z"}, + {"-000000", "", "Z"}, + {"-00:00:00", "", "Z"}, + {"+5", "+05:00", "+05:00"}, + {"+01", "+01:00", "+01:00"}, + {"+0100", "+01:00", "+01:00"}, + {"+01:00", "+01:00", "+01:00"}, + {"+010000", "+01:00", "+01:00"}, + {"+01:00:00", "+01:00", "+01:00"}, + {"+12", "+12:00", "+12:00"}, + {"+1234", "+12:34", "+12:34"}, + {"+12:34", "+12:34", "+12:34"}, + {"+123456", "+12:34:56", "+12:34:56"}, + {"+12:34:56", "+12:34:56", "+12:34:56"}, + {"-02", "-02:00", "-02:00"}, + {"-5", "-05:00", "-05:00"}, + {"-0200", "-02:00", "-02:00"}, + {"-02:00", "-02:00", "-02:00"}, + {"-020000", "-02:00", "-02:00"}, + {"-02:00:00", "-02:00", "-02:00"}, + }; + } + + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java new file mode 100644 index 00000000000..61196e909a1 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.time.ZoneOffset; + +/** + * Test ZoneOffset. + */ +@Test +public class TCKZoneOffset extends AbstractTCKTest { + + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws Exception { + assertSerializable(ZoneOffset.of("+01:30")); + } + + @Test + public void test_serialization_format_quarterPositive() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(8); + dos.writeByte(6); // stored as quarter hours + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneOffset.ofHoursMinutes(1, 30), bytes); + } + + @Test + public void test_serialization_format_quarterNegative() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(8); + dos.writeByte(-10); // stored as quarter hours + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneOffset.ofHoursMinutes(-2, -30), bytes); + } + + @Test + public void test_serialization_format_full() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(8); + dos.writeByte(127); + dos.writeInt(53265); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(ZoneOffset.ofTotalSeconds(53265), bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java new file mode 100644 index 00000000000..a44946b7450 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +/** + * Test ZonedDateTime. + */ +@Test +public class TCKZonedDateTime extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_0100 = ZoneOffset.ofHours(1); + private static final ZoneId ZONE_0100 = OFFSET_0100; + private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris"); + private LocalDateTime TEST_LOCAL_2008_06_30_11_30_59_500; + private ZonedDateTime TEST_DATE_TIME; + + + @BeforeMethod + public void setUp() { + TEST_LOCAL_2008_06_30_11_30_59_500 = LocalDateTime.of(2008, 6, 30, 11, 30, 59, 500); + TEST_DATE_TIME = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100); + } + + + //----------------------------------------------------------------------- + @Test + public void test_serialization() throws ClassNotFoundException, IOException { + assertSerializable(TEST_DATE_TIME); + } + + @Test + public void test_serialization_format_zoneId() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(6); + dos.writeInt(2012); // date + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); // time + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(470_000_000); + dos.writeByte(4); // offset + dos.writeByte(7); // zoneId + dos.writeUTF("Europe/London"); + } + byte[] bytes = baos.toByteArray(); + ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneId.of("Europe/London")); + assertSerializedBySer(zdt, bytes); + } + + @Test + public void test_serialization_format_zoneOffset() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(6); + dos.writeInt(2012); // date + dos.writeByte(9); + dos.writeByte(16); + dos.writeByte(22); // time + dos.writeByte(17); + dos.writeByte(59); + dos.writeInt(470_000_000); + dos.writeByte(4); // offset + dos.writeByte(8); // zoneId + dos.writeByte(4); + } + byte[] bytes = baos.toByteArray(); + ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneOffset.ofHours(1)); + assertSerializedBySer(zdt, bytes); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java index 4367ee92511..f2e94884371 100644 --- a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java @@ -713,12 +713,6 @@ public class TCKWeekFields extends AbstractTCKTest { } } - //----------------------------------------------------------------------- - @Test(dataProvider="weekFields") - public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException { - WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays); - assertSerializableSame(weekDef); // spec state singleton - } //----------------------------------------------------------------------- @DataProvider(name="weekFields") diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java new file mode 100644 index 00000000000..749515e7c9d --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.io.IOException; +import java.time.DayOfWeek; +import java.time.temporal.WeekFields; + +/** + * Test WeekFields. + */ +@Test +public class TCKWeekFields extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test(dataProvider="weekFields") + public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException { + WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays); + assertSerializableSame(weekDef); // spec state singleton + } + + //----------------------------------------------------------------------- + @DataProvider(name="weekFields") + Object[][] data_weekFields() { + Object[][] objects = new Object[49][]; + int i = 0; + for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) { + for (int minDays = 1; minDays <= 7; minDays++) { + objects[i++] = new Object[] {firstDayOfWeek, minDays}; + } + } + return objects; + } + + +} diff --git a/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java b/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java index 418d1ad9ec2..08df5433349 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java @@ -107,25 +107,7 @@ public class TCKFixedZoneRules { //----------------------------------------------------------------------- // Basics //----------------------------------------------------------------------- - @Test(dataProvider="rules") - public void test_serialization(ZoneRules test, ZoneOffset expectedOffset) throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(test); - baos.close(); - byte[] bytes = baos.toByteArray(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ObjectInputStream in = new ObjectInputStream(bais); - ZoneRules result = (ZoneRules) in.readObject(); - - assertEquals(result, test); - assertEquals(result.getClass(), test.getClass()); - } - - //----------------------------------------------------------------------- - // basics - //----------------------------------------------------------------------- @Test(dataProvider="rules") public void test_getOffset_Instant(ZoneRules test, ZoneOffset expectedOffset) { assertEquals(test.getOffset(INSTANT), expectedOffset); diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java index c5da309d872..891deb76733 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java @@ -146,20 +146,6 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertSerializable(test); } - //----------------------------------------------------------------------- - @Test - public void test_serialization_unusual1() throws Exception { - LocalDateTime ldt = LocalDateTime.of(Year.MAX_VALUE, 12, 31, 1, 31, 53); - ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("-10:02:34")); - assertSerializable(test); - } - - @Test - public void test_serialization_unusual2() throws Exception { - LocalDateTime ldt = LocalDateTime.of(Year.MIN_VALUE, 1, 1, 12, 1, 3); - ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("+10:02:34")); - assertSerializable(test); - } //----------------------------------------------------------------------- // isValidOffset() diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java index fedded75337..9ad26627edd 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java @@ -210,31 +210,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertSerializable(test); } - @Test - public void test_serialization_unusualOffsets() throws Exception { - ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( - Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD, - ZoneOffset.ofHoursMinutesSeconds(-12, -20, -50), - ZoneOffset.ofHoursMinutesSeconds(-4, -10, -34), - ZoneOffset.ofHours(-18)); - assertSerializable(test); - } - - @Test - public void test_serialization_endOfDay() throws Exception { - ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( - Month.MARCH, 20, DayOfWeek.FRIDAY, LocalTime.MIDNIGHT, true, TimeDefinition.UTC, - OFFSET_0200, OFFSET_0200, OFFSET_0300); - assertSerializable(test); - } - - @Test - public void test_serialization_unusualTime() throws Exception { - ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( - Month.MARCH, 20, DayOfWeek.WEDNESDAY, LocalTime.of(13, 34, 56), false, TimeDefinition.STANDARD, - OFFSET_0200, OFFSET_0200, OFFSET_0300); - assertSerializable(test); - } //----------------------------------------------------------------------- // createTransition() diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java index af07063ebe7..19f8239c230 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java @@ -103,28 +103,7 @@ public class TCKZoneRules { private static final int OVERLAP = 2; private static final int GAP = 0; - //----------------------------------------------------------------------- - // Basics - //----------------------------------------------------------------------- - public void test_serialization_loaded() throws Exception { - assertSerialization(europeLondon()); - assertSerialization(europeParis()); - assertSerialization(americaNewYork()); - } - private void assertSerialization(ZoneRules test) throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(test); - baos.close(); - byte[] bytes = baos.toByteArray(); - - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ObjectInputStream in = new ObjectInputStream(bais); - ZoneRules result = (ZoneRules) in.readObject(); - - assertEquals(result, test); - } //----------------------------------------------------------------------- // Europe/London diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java new file mode 100644 index 00000000000..b5d88d4f983 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.ZoneOffset; +import java.time.zone.ZoneRules; + +import static org.testng.Assert.assertEquals; + +/** + * Test ZoneRules for fixed offset time-zones. + */ +@Test +public class TCKFixedZoneRules { + + private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); + private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2); + private static final ZoneOffset OFFSET_M18 = ZoneOffset.ofHours(-18); + + private ZoneRules make(ZoneOffset offset) { + return offset.getRules(); + } + + @DataProvider(name="rules") + Object[][] data_rules() { + return new Object[][] { + {make(OFFSET_PONE), OFFSET_PONE}, + {make(OFFSET_PTWO), OFFSET_PTWO}, + {make(OFFSET_M18), OFFSET_M18}, + }; + } + + //----------------------------------------------------------------------- + // Basics + //----------------------------------------------------------------------- + @Test(dataProvider="rules") + public void test_serialization(ZoneRules test, ZoneOffset expectedOffset) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(test); + baos.close(); + byte[] bytes = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ObjectInputStream in = new ObjectInputStream(bais); + ZoneRules result = (ZoneRules) in.readObject(); + + assertEquals(result, test); + assertEquals(result.getClass(), test.getClass()); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java new file mode 100644 index 00000000000..a57d31eaf71 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +import java.time.LocalDateTime; +import java.time.Year; +import java.time.ZoneOffset; +import java.time.zone.ZoneOffsetTransition; + +/** + * Test ZoneOffsetTransition. + */ +@Test +public class TCKZoneOffsetTransition extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_serialization_unusual1() throws Exception { + LocalDateTime ldt = LocalDateTime.of(Year.MAX_VALUE, 12, 31, 1, 31, 53); + ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("-10:02:34")); + assertSerializable(test); + } + + @Test + public void test_serialization_unusual2() throws Exception { + LocalDateTime ldt = LocalDateTime.of(Year.MIN_VALUE, 1, 1, 12, 1, 3); + ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("+10:02:34")); + assertSerializable(test); + } + +} diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java new file mode 100644 index 00000000000..1ccae56c8d9 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2010-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import static org.testng.Assert.assertEquals; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.time.ZoneOffset; +import java.time.zone.ZoneOffsetTransitionRule; +import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +/** + * Test ZoneOffsetTransitionRule. + */ +@Test +public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { + + private static final LocalTime TIME_0100 = LocalTime.of(1, 0); + private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2); + private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3); + + + + @Test + public void test_serialization_unusualOffsets() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD, + ZoneOffset.ofHoursMinutesSeconds(-12, -20, -50), + ZoneOffset.ofHoursMinutesSeconds(-4, -10, -34), + ZoneOffset.ofHours(-18)); + assertSerializable(test); + } + + @Test + public void test_serialization_endOfDay() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, DayOfWeek.FRIDAY, LocalTime.MIDNIGHT, true, TimeDefinition.UTC, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_unusualTime() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, DayOfWeek.WEDNESDAY, LocalTime.of(13, 34, 56), false, TimeDefinition.STANDARD, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + +} diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java new file mode 100644 index 00000000000..6f83223f07c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.zone.serial; + +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.ZoneId; +import java.time.zone.ZoneRules; + +import static org.testng.Assert.assertEquals; + +/** + * Test ZoneRules. + */ +@Test +public class TCKZoneRules { + + public void test_serialization_loaded() throws Exception { + assertSerialization(europeLondon()); + assertSerialization(europeParis()); + assertSerialization(americaNewYork()); + } + + private void assertSerialization(ZoneRules test) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(test); + baos.close(); + byte[] bytes = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ObjectInputStream in = new ObjectInputStream(bais); + ZoneRules result = (ZoneRules) in.readObject(); + + assertEquals(result, test); + } + + //----------------------------------------------------------------------- + // Europe/London + //----------------------------------------------------------------------- + private ZoneRules europeLondon() { + return ZoneId.of("Europe/London").getRules(); + } + + + //----------------------------------------------------------------------- + // Europe/Paris + //----------------------------------------------------------------------- + private ZoneRules europeParis() { + return ZoneId.of("Europe/Paris").getRules(); + } + + //----------------------------------------------------------------------- + // America/New_York + //----------------------------------------------------------------------- + private ZoneRules americaNewYork() { + return ZoneId.of("America/New_York").getRules(); + } + + +} From 81cd0a873837c1a1c5899ed5727347cdf05d6b7d Mon Sep 17 00:00:00 2001 From: Shanliang Jiang Date: Wed, 18 Sep 2013 08:51:23 +0200 Subject: [PATCH 043/293] 8023954: MBean*Info.equals: throw NPE Reviewed-by: dfuchs, dholmes --- .../javax/management/MBeanAttributeInfo.java | 8 +- .../management/MBeanConstructorInfo.java | 6 +- .../javax/management/MBeanFeatureInfo.java | 7 +- .../management/MBeanNotificationInfo.java | 7 +- .../javax/management/MBeanOperationInfo.java | 8 +- .../javax/management/MBeanParameterInfo.java | 9 +- .../MBeanInfo/MBeanInfoEqualsNPETest.java | 216 ++++++++++++++++++ 7 files changed, 240 insertions(+), 21 deletions(-) create mode 100644 jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java diff --git a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java index a70fb3a3571..7a3adaa5ad8 100644 --- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java @@ -286,10 +286,10 @@ public class MBeanAttributeInfo extends MBeanFeatureInfo implements Cloneable { if (!(o instanceof MBeanAttributeInfo)) return false; MBeanAttributeInfo p = (MBeanAttributeInfo) o; - return (p.getName().equals(getName()) && - p.getType().equals(getType()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getType(), getType()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor()) && p.isReadable() == isReadable() && p.isWritable() == isWritable() && p.isIs() == isIs()); diff --git a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java index ad2176367d2..d02ffce3a8d 100644 --- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java @@ -191,10 +191,10 @@ public class MBeanConstructorInfo extends MBeanFeatureInfo implements Cloneable if (!(o instanceof MBeanConstructorInfo)) return false; MBeanConstructorInfo p = (MBeanConstructorInfo) o; - return (p.getName().equals(getName()) && - p.getDescription().equals(getDescription()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getDescription(), getDescription()) && Arrays.equals(p.fastGetSignature(), fastGetSignature()) && - p.getDescriptor().equals(getDescriptor())); + Objects.equals(p.getDescriptor(), getDescriptor())); } /* Unlike attributes and operations, it's quite likely we'll have diff --git a/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java b/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java index a2349a8c69f..ec8e8b622b8 100644 --- a/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java @@ -30,6 +30,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.io.StreamCorruptedException; +import java.util.Objects; /** *

Provides general information for an MBean descriptor object. @@ -147,9 +148,9 @@ public class MBeanFeatureInfo implements Serializable, DescriptorRead { if (!(o instanceof MBeanFeatureInfo)) return false; MBeanFeatureInfo p = (MBeanFeatureInfo) o; - return (p.getName().equals(getName()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor())); + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor())); } public int hashCode() { diff --git a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java index b4bbbe80292..ad1c74f83d5 100644 --- a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java @@ -26,6 +26,7 @@ package javax.management; import java.util.Arrays; +import java.util.Objects; /** *

The MBeanNotificationInfo class is used to describe the @@ -191,9 +192,9 @@ public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable if (!(o instanceof MBeanNotificationInfo)) return false; MBeanNotificationInfo p = (MBeanNotificationInfo) o; - return (p.getName().equals(getName()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor()) && Arrays.equals(p.fastGetNotifTypes(), fastGetNotifTypes())); } diff --git a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java index 8effa04f8d8..1be6d8f563a 100644 --- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java @@ -294,12 +294,12 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable { if (!(o instanceof MBeanOperationInfo)) return false; MBeanOperationInfo p = (MBeanOperationInfo) o; - return (p.getName().equals(getName()) && - p.getReturnType().equals(getReturnType()) && - p.getDescription().equals(getDescription()) && + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getReturnType(), getReturnType()) && + Objects.equals(p.getDescription(), getDescription()) && p.getImpact() == getImpact() && Arrays.equals(p.fastGetSignature(), fastGetSignature()) && - p.getDescriptor().equals(getDescriptor())); + Objects.equals(p.getDescriptor(), getDescriptor())); } /* We do not include everything in the hashcode. We assume that diff --git a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java index df3d59087df..81f2eff840d 100644 --- a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java +++ b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java @@ -27,6 +27,7 @@ package javax.management; import java.util.Objects; + /** * Describes an argument of an operation exposed by an MBean. * Instances of this class are immutable. Subclasses may be mutable @@ -137,10 +138,10 @@ public class MBeanParameterInfo extends MBeanFeatureInfo implements Cloneable { if (!(o instanceof MBeanParameterInfo)) return false; MBeanParameterInfo p = (MBeanParameterInfo) o; - return (p.getName().equals(getName()) && - p.getType().equals(getType()) && - p.getDescription().equals(getDescription()) && - p.getDescriptor().equals(getDescriptor())); + return (Objects.equals(p.getName(), getName()) && + Objects.equals(p.getType(), getType()) && + Objects.equals(p.getDescription(), getDescription()) && + Objects.equals(p.getDescriptor(), getDescriptor())); } public int hashCode() { diff --git a/jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java b/jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java new file mode 100644 index 00000000000..440878c37f3 --- /dev/null +++ b/jdk/test/javax/management/MBeanInfo/MBeanInfoEqualsNPETest.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanFeatureInfo; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.SimpleType; + +/* + * @test + * @bug 8023954 + * @summary Test that MBean*Info.equals do not throw NPE + * @author Shanliang JIANG + * @run clean MBeanInfoEqualsNPETest + * @run build MBeanInfoEqualsNPETest + * @run main MBeanInfoEqualsNPETest + */ +public class MBeanInfoEqualsNPETest { + private static int failed = 0; + + public static void main(String[] args) throws Exception { + System.out.println("---MBeanInfoEqualsNPETest-main ..."); + + // ---- + System.out.println("\n---Testing on MBeanAttributeInfo..."); + MBeanAttributeInfo mbeanAttributeInfo0 = new MBeanAttributeInfo( + "name", SimpleType.INTEGER.getClassName(), "description", true, true, false); + MBeanAttributeInfo mbeanAttributeInfo = new MBeanAttributeInfo( + null, SimpleType.INTEGER.getClassName(), "description", true, true, false); + test(mbeanAttributeInfo0, mbeanAttributeInfo, "class name"); + + mbeanAttributeInfo = new MBeanAttributeInfo( + "name", null, "description", true, true, false); + test(mbeanAttributeInfo0, mbeanAttributeInfo, "type"); + + mbeanAttributeInfo = new MBeanAttributeInfo( + "name", SimpleType.INTEGER.getClassName(), null, true, true, false); + test(mbeanAttributeInfo0, mbeanAttributeInfo, "description"); + + // ---- + System.out.println("\n---Testing on MBeanConstructorInfo..."); + MBeanConstructorInfo mbeanConstructorInfo0 = new MBeanConstructorInfo( + "", "", new MBeanParameterInfo[]{}, new DescriptorSupport()); + MBeanConstructorInfo mbeanConstructorInfo = new MBeanConstructorInfo( + null, "", new MBeanParameterInfo[]{}, new DescriptorSupport()); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "name"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", null, new MBeanParameterInfo[]{}, new DescriptorSupport()); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "description"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", "", null, new DescriptorSupport()); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "MBeanParameterInfo"); + + mbeanConstructorInfo = new MBeanConstructorInfo( + "", "", new MBeanParameterInfo[]{}, null); + test(mbeanConstructorInfo0, mbeanConstructorInfo, "descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanOperationInfo..."); + MBeanOperationInfo mbeanOperationInfo0 = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, "type", + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + + MBeanOperationInfo mbeanOperationInfo = new MBeanOperationInfo( + null, "description", new MBeanParameterInfo[]{}, "type", + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "name"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", null, new MBeanParameterInfo[]{}, "type", + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "description"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", null, "type", 1, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "MBeanParameterInfo"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, null, + MBeanOperationInfo.UNKNOWN, new DescriptorSupport()); + test(mbeanOperationInfo0, mbeanOperationInfo, "type"); + + mbeanOperationInfo = new MBeanOperationInfo( + "name", "description", new MBeanParameterInfo[]{}, null, + MBeanOperationInfo.UNKNOWN, null); + test(mbeanOperationInfo0, mbeanOperationInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanParameterInfo..."); + MBeanParameterInfo mbeanParameterInfo0 = new MBeanParameterInfo( + "name", "type", "description", new DescriptorSupport()); + MBeanParameterInfo mbeanParameterInfo = new MBeanParameterInfo( + null, "type", "description", new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "name"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", null, "description", new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "type"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", "type", null, new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "description"); + + mbeanParameterInfo = new MBeanParameterInfo( + "name", "type", "description", null); + test(mbeanParameterInfo0, mbeanParameterInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanFeatureInfo ..."); + MBeanFeatureInfo mbeanFeatureInfo0 = new MBeanFeatureInfo( + "name", "description", new DescriptorSupport()); + MBeanFeatureInfo mbeanFeatureInfo = new MBeanFeatureInfo( + null, "description", new DescriptorSupport()); + test(mbeanFeatureInfo0, mbeanFeatureInfo, "name"); + + mbeanFeatureInfo = new MBeanFeatureInfo( + "name", null, new DescriptorSupport()); + test(mbeanParameterInfo0, mbeanParameterInfo, "description"); + + mbeanFeatureInfo = new MBeanFeatureInfo( + "name", "description", null); + test(mbeanParameterInfo0, mbeanParameterInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on MBeanInfo..."); + String className = "toto"; + String description = "titi"; + MBeanAttributeInfo[] attrInfos = new MBeanAttributeInfo[]{}; + MBeanConstructorInfo[] constrInfos = new MBeanConstructorInfo[]{}; + MBeanOperationInfo[] operaInfos = new MBeanOperationInfo[]{}; + MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{}; + + MBeanInfo minfo0 = new MBeanInfo("toto", description, attrInfos, constrInfos, operaInfos, notifInfos); + MBeanInfo minfo = new MBeanInfo(null, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(minfo0, minfo, "class name"); + + minfo = new MBeanInfo(className, null, attrInfos, constrInfos, operaInfos, notifInfos); + test(minfo0, minfo, "description"); + + minfo = new MBeanInfo(className, description, null, constrInfos, operaInfos, notifInfos); + test(minfo0, minfo, "attrInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, null, operaInfos, notifInfos); + test(minfo0, minfo, "constrInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, constrInfos, null, notifInfos); + test(minfo0, minfo, "operaInfos"); + + minfo = new MBeanInfo(className, description, attrInfos, constrInfos, operaInfos, null); + test(minfo0, minfo, "notifInfos"); + + if (failed > 0) { + throw new RuntimeException("Test failed: "+failed); + } else { + System.out.println("---Test: PASSED"); + } + } + + private static void test(Object obj1, Object obj2, String param) { + try { + obj1.equals(obj2); + System.out.println("OK-1: "+obj1.getClass().getSimpleName()+".equals worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj1.getClass().getSimpleName()+".equals got NPE with a null paramer: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj2.equals(obj1); + System.out.println("OK-2: "+obj2.getClass().getSimpleName()+".equals worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-2!!! "+obj2.getClass().getSimpleName()+".equals got NPE with a null paramer: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj1.equals(null); + obj2.equals(null); + + System.out.println("OK-3: "+obj1.getClass().getSimpleName()+".equals worked with a null field."); + } catch (NullPointerException npe) { + System.out.println("--->KO-3!!! "+obj1.getClass().getSimpleName()+".equals got NPE with a null field."); + npe.printStackTrace(); + failed++; + } + } +} From 5ae304e238a2e80ff895f8118edd4e6e9394a612 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 18 Sep 2013 18:22:49 +0800 Subject: [PATCH 044/293] 8012615: Realm.getRealmsList returns realms list in wrong Reviewed-by: valeriep, xuelei --- .../classes/sun/security/krb5/Config.java | 34 +- .../classes/sun/security/krb5/Realm.java | 525 +++++------------- .../krb5/internal/CredentialsUtil.java | 20 +- jdk/test/sun/security/krb5/ParseCAPaths.java | 85 ++- jdk/test/sun/security/krb5/krb5-capaths.conf | 81 +-- 5 files changed, 264 insertions(+), 481 deletions(-) diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java index 5771886023c..c2640adbcda 100644 --- a/jdk/src/share/classes/sun/security/krb5/Config.java +++ b/jdk/src/share/classes/sun/security/krb5/Config.java @@ -225,19 +225,19 @@ public class Config { * and has no sub-key at all (given "forwardable" is defined, otherwise, * this method has no knowledge if it's a value name or a section name), */ - @SuppressWarnings("unchecked") public String get(String... keys) { - Vector v = get0(keys); + Vector v = getString0(keys); if (v == null) return null; return v.lastElement(); } /** * Gets all values for the specified keys. - * @see #get(java.lang.String[]) + * @throws IllegalArgumentException if any of the keys is illegal + * (See {@link #get}) */ public String getAll(String... keys) { - Vector v = get0(keys); + Vector v = getString0(keys); if (v == null) return null; StringBuilder sb = new StringBuilder(); boolean first = true; @@ -252,17 +252,37 @@ public class Config { return sb.toString(); } - // Internal method. Returns the vector of strings for keys. + /** + * Returns true if keys exists, can be either final string(s) or sub-stanza + * @throws IllegalArgumentException if any of the keys is illegal + * (See {@link #get}) + */ + public boolean exists(String... keys) { + return get0(keys) != null; + } + + // Returns final string value(s) for given keys. + @SuppressWarnings("unchecked") + private Vector getString0(String... keys) { + try { + return (Vector)get0(keys); + } catch (ClassCastException cce) { + throw new IllegalArgumentException(cce); + } + } + + // Internal method. Returns the value for keys, which can be a sub-stanza + // or final string value(s). // The only method (except for toString) that reads stanzaTable directly. @SuppressWarnings("unchecked") - private Vector get0(String... keys) { + private Object get0(String... keys) { Object current = stanzaTable; try { for (String key: keys) { current = ((Hashtable)current).get(key); if (current == null) return null; } - return (Vector)current; + return current; } catch (ClassCastException cce) { throw new IllegalArgumentException(cce); } diff --git a/jdk/src/share/classes/sun/security/krb5/Realm.java b/jdk/src/share/classes/sun/security/krb5/Realm.java index bc7705c4f0e..27bedc3ecf8 100644 --- a/jdk/src/share/classes/sun/security/krb5/Realm.java +++ b/jdk/src/share/classes/sun/security/krb5/Realm.java @@ -34,10 +34,8 @@ package sun.security.krb5; import sun.security.krb5.internal.Krb5; import sun.security.util.*; import java.io.IOException; -import java.util.StringTokenizer; -import java.util.Vector; -import java.util.Stack; -import java.util.EmptyStackException; +import java.util.*; + import sun.security.krb5.internal.util.KerberosString; /** @@ -50,7 +48,6 @@ import sun.security.krb5.internal.util.KerberosString; */ public class Realm implements Cloneable { private final String realm; // not null nor empty - private static boolean DEBUG = Krb5.DEBUG; public Realm(String name) throws RealmException { realm = parseRealm(name); @@ -233,90 +230,53 @@ public class Realm implements Cloneable { } } - /* - * First leg of realms parsing. Used by getRealmsList. - */ - private static String[] doInitialParse(String cRealm, String sRealm) - throws KrbException { - if (cRealm == null || sRealm == null){ - throw new KrbException(Krb5.API_INVALID_ARG); - } - if (DEBUG) { - System.out.println(">>> Realm doInitialParse: cRealm=[" - + cRealm + "], sRealm=[" +sRealm + "]"); - } - if (cRealm.equals(sRealm)) { - String[] retList = null; - retList = new String[1]; - retList[0] = new String(cRealm); - - if (DEBUG) { - System.out.println(">>> Realm doInitialParse: " - + retList[0]); - } - return retList; - } - return null; - } - /** * Returns an array of realms that may be traversed to obtain * a TGT from the initiating realm cRealm to the target realm * sRealm. *
- * There may be an arbitrary number of intermediate realms - * between cRealm and sRealm. The realms may be organized - * organized hierarchically, or the paths between them may be - * specified in the [capaths] stanza of the caller's - * Kerberos configuration file. The configuration file is consulted - * first. Then a hirarchical organization is assumed if no realms - * are found in the configuration file. + * This method would read [capaths] to create a path, or generate a + * hierarchical path if [capaths] does not contain a sub-stanza for cRealm + * or the sub-stanza does not contain a tag for sRealm. *
- * The returned list, if not null, contains cRealm as the first - * entry. sRealm is not included unless it is mistakenly listed - * in the configuration file as an intermediary realm. + * The returned list would never be null, and it always contains + * cRealm as the head entry. sRealm is not included as the tail. * - * @param cRealm the initiating realm - * @param sRealm the target realm - * @returns array of realms - * @thows KrbException + * @param cRealm the initiating realm, not null + * @param sRealm the target realm, not null, not equals to cRealm + * @returns array of realms including at least cRealm as the first + * element */ - public static String[] getRealmsList(String cRealm, String sRealm) - throws KrbException { - String[] retList = doInitialParse(cRealm, sRealm); - if (retList != null && retList.length != 0) { - return retList; - } - /* - * Try [capaths]. - */ - retList = parseCapaths(cRealm, sRealm); - if (retList != null && retList.length != 0) { - return retList; - } - /* - * Now assume the realms are organized hierarchically. - */ - retList = parseHierarchy(cRealm, sRealm); - return retList; + public static String[] getRealmsList(String cRealm, String sRealm) { + try { + // Try [capaths] + return parseCapaths(cRealm, sRealm); + } catch (KrbException ke) { + // Now assume the realms are organized hierarchically. + return parseHierarchy(cRealm, sRealm); } + } /** - * Parses the [capaths] stanza of the configuration file - * for a list of realms to traverse - * to obtain credentials from the initiating realm cRealm to - * the target realm sRealm. - * @param cRealm the initiating realm - * @param sRealm the target realm - * @returns array of realms - * @ throws KrbException - */ - - /* - * parseCapaths works for a capaths organized such that - * for a given client realm C there is a tag C that - * contains subtags Ci ... Cn that completely define intermediate - * realms from C to target T. For example: + * Parses the [capaths] stanza of the configuration file for a + * list of realms to traverse to obtain credentials from the + * initiating realm cRealm to the target realm sRealm. + * + * For a given client realm C there is a tag C in [capaths] whose + * subtag S has a value which is a (possibly partial) path from C + * to S. When the path is partial, it contains only the tail of the + * full path. Values of other subtags will be used to build the full + * path. The value "." means a direct path from C to S. If realm S + * does not appear as a subtag, there is no path defined here. + * + * The implementation ignores all values which equals to C or S, or + * a "." in multiple values, or any duplicated realm names. + * + * When a path value has more than two realms, they can be specified + * with multiple key-value pairs each having a single value, but the + * order must not change. + * + * For example: * * [capaths] * TIVOLI.COM = { @@ -325,357 +285,130 @@ public class Realm implements Cloneable { * LDAPCENTRAL.NET = . * } * - * The tag TIVOLI.COM contains subtags IBM.COM, IBM_LDAPCENTRAL.COM - * and LDAPCENTRAL.NET that completely define the path from TIVOLI.COM - * to IBM.COM (TIVOLI.COM->LADAPCENTRAL.NET->IBM_LDAPCENTRAL.COM->IBM - * or TIVOLI.COM->MOONLITE.ORG->IBM.COM). + * TIVOLI.COM has a direct path to LDAPCENTRAL.NET, which has a direct + * path to IBM_LDAPCENTRAL.COM. It also has a partial path to IBM.COM + * being "IBM_LDAPCENTRAL.COM MOONLITE.ORG". Merging these info together, + * a full path from TIVOLI.COM to IBM.COM will be * - * A direct path is assumed for an intermediary whose entry is not - * "closed" by a "." In the above example, TIVOLI.COM is assumed - * to have a direct path to MOONLITE.ORG and MOONLITE.COM - * in turn to IBM.COM. + * TIVOLI.COM -> LDAPCENTRAL.NET -> IBM_LDAPCENTRAL.COM + * -> IBM_LDAPCENTRAL.COM -> MOONLITE.ORG + * + * Please note the sRealm IBM.COM does not appear in the path. + * + * @param cRealm the initiating realm + * @param sRealm the target realm, not the same as cRealm + * @returns array of realms including at least cRealm as the first + * element + * @throws KrbException if the config does not contain a sub-stanza + * for cRealm in [capaths] or the sub-stanza does not contain + * sRealm as a tag */ + private static String[] parseCapaths(String cRealm, String sRealm) + throws KrbException { - private static String[] parseCapaths(String cRealm, String sRealm) throws KrbException { - String[] retList = null; + // This line could throw a KrbException + Config cfg = Config.getInstance(); - Config cfg = null; - try { - cfg = Config.getInstance(); - } catch (Exception exc) { - if (DEBUG) { - System.out.println ("Configuration information can not be " + - "obtained " + exc.getMessage()); - } - return null; + if (!cfg.exists("capaths", cRealm, sRealm)) { + throw new KrbException("No conf"); } - String intermediaries = cfg.getAll("capaths", cRealm, sRealm); + LinkedList path = new LinkedList<>(); - if (intermediaries == null) { - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: no cfg entry"); - } - return null; - } - - String tempTarget = null, tempRealm = null; - Stack iStack = new Stack<>(); - - /* - * The half-established reversed-path, starting from the final target - * (sRealm), each item can be connected to by the next one. - * Might contains wrong item, if found, a bad track is performed - */ - Vector tempList = new Vector<>(8, 8); - tempList.add(sRealm); - - int count = 0; // For debug only - tempTarget = sRealm; - - out: do { - if (DEBUG) { - count++; - System.out.println(">>> Realm parseCapaths: loop " + - count + ": target=" + tempTarget); - } - - if (intermediaries != null && - !intermediaries.equals(".") && - !intermediaries.equals(cRealm)) { - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + ": intermediaries=[" + - intermediaries + "]"); - } - - /* - * We have one or more space-separated intermediary realms. - * Stack them. A null is always added between intermedies of - * different targets. When this null is popped, it means none - * of the intermedies for this target is useful (because of - * infinite loop), the target is then removed from the partial - * tempList, and the next possible intermediary is tried. - */ - iStack.push(null); - String[] ints = intermediaries.split("\\s+"); - for (int i = ints.length-1; i>=0; i--) - { - tempRealm = ints[i]; - if (tempRealm.equals(PrincipalName.REALM_COMPONENT_SEPARATOR_STR)) { - break out; - } - if (!tempList.contains(tempRealm)) { - iStack.push(tempRealm); - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + - ": pushed realm on to stack: " + - tempRealm); - } - } else if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + - ": ignoring realm: [" + - tempRealm + "]"); - } - } - } else { - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + - count + - ": no intermediaries"); - } + String head = sRealm; + while (true) { + String value = cfg.getAll("capaths", cRealm, head); + if (value == null) { break; } - - /* - * Get next intermediary realm from the stack - */ - - try { - while ((tempTarget = iStack.pop()) == null) { - tempList.removeElementAt(tempList.size()-1); - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: backtrack, remove tail"); - } + String[] more = value.split("\\s+"); + boolean changed = false; + for (int i=more.length-1; i>=0; i--) { + if (path.contains(more[i]) + || more[i].equals(".") + || more[i].equals(cRealm) + || more[i].equals(sRealm) + || more[i].equals(head)) { + // Ignore invalid values + continue; } - } catch (EmptyStackException exc) { - tempTarget = null; + changed = true; + path.addFirst(more[i]); } - - if (tempTarget == null) { - /* - * No more intermediaries. We're done. - */ - break; - } - - tempList.add(tempTarget); - - if (DEBUG) { - System.out.println(">>> Realm parseCapaths: loop " + count + - ": added intermediary to list: " + - tempTarget); - } - - intermediaries = cfg.getAll("capaths", cRealm, tempTarget); - - } while (true); - - if (tempList.isEmpty()) { - return null; + if (!changed) break; + head = path.getFirst(); } - - // From (SREALM, T1, T2) to (CREALM, T2, T1) - retList = new String[tempList.size()]; - retList[0] = cRealm; - for (int i=1; i>> Realm parseCapaths [" + i + - "]=" + retList[i]); - } - } - - return retList; - } + path.addFirst(cRealm); + return path.toArray(new String[path.size()]); + } /** * Build a list of realm that can be traversed * to obtain credentials from the initiating realm cRealm * for a service in the target realm sRealm. * @param cRealm the initiating realm - * @param sRealm the target realm - * @returns array of realms - * @throws KrbException + * @param sRealm the target realm, not the same as cRealm + * @returns array of realms including cRealm as the first element */ - private static String[] parseHierarchy(String cRealm, String sRealm) - throws KrbException - { - String[] retList = null; + private static String[] parseHierarchy(String cRealm, String sRealm) { - // Parse the components and determine common part, if any. + String[] cComponents = cRealm.split("\\."); + String[] sComponents = sRealm.split("\\."); - String[] cComponents = null; - String[] sComponents = null; + int cPos = cComponents.length; + int sPos = sComponents.length; - StringTokenizer strTok = - new StringTokenizer(cRealm, - PrincipalName.REALM_COMPONENT_SEPARATOR_STR); - - // Parse cRealm - - int cCount = strTok.countTokens(); - cComponents = new String[cCount]; - - for (cCount = 0; strTok.hasMoreTokens(); cCount++) { - cComponents[cCount] = strTok.nextToken(); + boolean hasCommon = false; + for (sPos--, cPos--; sPos >=0 && cPos >= 0 && + sComponents[sPos].equals(cComponents[cPos]); + sPos--, cPos--) { + hasCommon = true; } - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy: cRealm has " + - cCount + " components:"); - int j = 0; - while (j < cCount) { - System.out.println(">>> Realm parseHierarchy: " + - "cComponents["+j+"]=" + cComponents[j++]); - } + // For those with common components: + // length pos + // SITES1.SALES.EXAMPLE.COM 4 1 + // EVERYWHERE.EXAMPLE.COM 3 0 + + // For those without common components: + // length pos + // DEVEL.EXAMPLE.COM 3 2 + // PROD.EXAMPLE.ORG 3 2 + + LinkedList path = new LinkedList<>(); + + // Un-common ones for client side + for (int i=0; i<=cPos; i++) { + path.addLast(subStringFrom(cComponents, i)); } - // Parse sRealm - - strTok = new StringTokenizer(sRealm, - PrincipalName.REALM_COMPONENT_SEPARATOR_STR); - - int sCount = strTok.countTokens(); - sComponents = new String[sCount]; - - for (sCount = 0; strTok.hasMoreTokens(); sCount++) { - sComponents[sCount] = strTok.nextToken(); + // Common one + if (hasCommon) { + path.addLast(subStringFrom(cComponents, cPos+1)); } - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy: sRealm has " + - sCount + " components:"); - int j = 0; - while (j < sCount) { - System.out.println(">>> Realm parseHierarchy: sComponents["+j+ - "]=" + sComponents[j++]); - } + // Un-common ones for server side + for (int i=sPos; i>=0; i--) { + path.addLast(subStringFrom(sComponents, i)); } - // Determine common components, if any. + // Remove sRealm from path. Note that it might be added at last loop + // or as a common component, if sRealm is a parent of cRealm + path.removeLast(); - int commonComponents = 0; - - //while (sCount > 0 && cCount > 0 && - // sComponents[--sCount].equals(cComponents[--cCount])) - - for (sCount--, cCount--; sCount >=0 && cCount >= 0 && - sComponents[sCount].equals(cComponents[cCount]); - sCount--, cCount--) { - commonComponents++; - } - - int cCommonStart = -1; - int sCommonStart = -1; - - int links = 0; - - if (commonComponents > 0) { - sCommonStart = sCount+1; - cCommonStart = cCount+1; - - // components from common to ancestors - links += sCommonStart; - links += cCommonStart; - } else { - links++; - } - - if (DEBUG) { - if (commonComponents > 0) { - System.out.println(">>> Realm parseHierarchy: " + - commonComponents + " common component" + - (commonComponents > 1 ? "s" : " ")); - - System.out.println(">>> Realm parseHierarchy: common part " - + - "in cRealm (starts at index " + - cCommonStart + ")"); - System.out.println(">>> Realm parseHierarchy: common part in sRealm (starts at index " + - sCommonStart + ")"); - - - String commonPart = substring(cRealm, cCommonStart); - System.out.println(">>> Realm parseHierarchy: common part in cRealm=" + - commonPart); - - commonPart = substring(sRealm, sCommonStart); - System.out.println(">>> Realm parseHierarchy: common part in sRealm=" + - commonPart); - - } else - System.out.println(">>> Realm parseHierarchy: no common part"); - } - - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy: total links=" + links); - } - - retList = new String[links]; - - retList[0] = new String(cRealm); - - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy A: retList[0]=" + - retList[0]); - } - - // For an initiator realm A.B.C.D.COM, - // build a list krbtgt/B.C.D.COM@A.B.C.D.COM up to the common part, - // ie the issuer realm is the immediate descendant - // of the target realm. - - String cTemp = null, sTemp = null; - int i; - for (i = 1, cCount = 0; i < links && cCount < cCommonStart; cCount++) { - sTemp = substring(cRealm, cCount+1); - //cTemp = substring(cRealm, cCount); - retList[i++] = new String(sTemp); - - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy B: retList[" + - (i-1) +"]="+retList[i-1]); - } - } - - - for (sCount = sCommonStart; i < links && sCount - 1 > 0; sCount--) { - sTemp = substring(sRealm, sCount-1); - //cTemp = substring(sRealm, sCount); - retList[i++] = new String(sTemp); - if (DEBUG) { - System.out.println(">>> Realm parseHierarchy D: retList[" + - (i-1) +"]="+retList[i-1]); - } - } - - return retList; + return path.toArray(new String[path.size()]); } - private static String substring(String realm, int componentIndex) - { - int i = 0 , j = 0, len = realm.length(); - - while(i < len && j != componentIndex) { - if (realm.charAt(i++) != PrincipalName.REALM_COMPONENT_SEPARATOR) - continue; - j++; + /** + * Creates a realm name using components from the given postion. + * For example, subStringFrom({"A", "B", "C"}, 1) is "B.C". + */ + private static String subStringFrom(String[] components, int from) { + StringBuilder sb = new StringBuilder(); + for (int i=from; i>> Credentials acquireServiceCreds: no realms list"); - } - return null; - } - int i = 0, k = 0; Credentials cTgt = null, newTgt = null, theTgt = null; PrincipalName tempService = null; @@ -206,16 +198,14 @@ public class CredentialsUtil { if (newTgt == null) { if (DEBUG) { System.out.println(">>> Credentials acquireServiceCreds: " - + "no tgt; searching backwards"); + + "no tgt; searching thru capath"); } /* - * No tgt found. Try to get one for a - * realm as close to the target as possible. - * That means traversing the realms list backwards. + * No tgt found. Let's go thru the realms list one by one. */ - for (newTgt = null, k = realms.length - 1; - newTgt == null && k > i; k--) { + for (newTgt = null, k = i+1; + newTgt == null && k < realms.length; k++) { tempService = PrincipalName.tgsService(realms[k], realms[i]); if (DEBUG) { System.out.println( diff --git a/jdk/test/sun/security/krb5/ParseCAPaths.java b/jdk/test/sun/security/krb5/ParseCAPaths.java index f8c30bd7b7d..18b43470842 100644 --- a/jdk/test/sun/security/krb5/ParseCAPaths.java +++ b/jdk/test/sun/security/krb5/ParseCAPaths.java @@ -22,7 +22,7 @@ */ /* * @test - * @bug 6789935 + * @bug 6789935 8012615 * @run main/othervm ParseCAPaths * @summary cross-realm capath search error */ @@ -35,37 +35,75 @@ public class ParseCAPaths { public static void main(String[] args) throws Exception { System.setProperty("java.security.krb5.conf", System.getProperty("test.src", ".") +"/krb5-capaths.conf"); - //System.setProperty("sun.security.krb5.debug", "true"); - // Standard example + // MIT check("ANL.GOV", "TEST.ANL.GOV", "ANL.GOV"); check("ANL.GOV", "ES.NET", "ANL.GOV"); check("ANL.GOV", "PNL.GOV", "ANL.GOV", "ES.NET"); check("ANL.GOV", "NERSC.GOV", "ANL.GOV", "ES.NET"); + check("NERSC.GOV", "TEST.ANL.GOV", "NERSC.GOV", "ES.NET", "ANL.GOV"); + + // RedHat + // 3.6.2.1. Configuring a Shared Hierarchy of Names + check("AA.EXAMPLE.COM", "BB.EXAMPLE.COM", + "AA.EXAMPLE.COM", "EXAMPLE.COM"); + check("SITE1.SALES.EXAMPLE.COM", "EVERYWHERE.EXAMPLE.COM", + "SITE1.SALES.EXAMPLE.COM", "SALES.EXAMPLE.COM", + "EXAMPLE.COM"); + check("DEVEL.EXAMPLE.COM", "PROD.EXAMPLE.ORG", + "DEVEL.EXAMPLE.COM", "EXAMPLE.COM", "COM", + "ORG", "EXAMPLE.ORG"); + // 3.6.2.2. Configuring Paths in krb5.conf + check("A.EXAMPLE.COM", "B.EXAMPLE.COM", "A.EXAMPLE.COM"); + check("A.EXAMPLE.COM", "C.EXAMPLE.COM", + "A.EXAMPLE.COM", "B.EXAMPLE.COM"); + check("A.EXAMPLE.COM", "D.EXAMPLE.COM", + "A.EXAMPLE.COM", "B.EXAMPLE.COM", "C.EXAMPLE.COM"); + + // The original JDK example + check("TIVOLI.COM", "IBM.COM", "TIVOLI.COM", "LDAPCENTRAL.NET", + "IBM_LDAPCENTRAL.COM", "MOONLITE.ORG"); + // Hierachical - check("N1.N.COM", "N2.N.COM", "N1.N.COM", "N.COM"); // 2 common - check("N1.N.COM", "N2.N3.COM", "N1.N.COM", "N.COM", // 1 common + check("N1.N.COM", "N2.N.COM", "N1.N.COM", "N.COM"); + check("N1.N.COM", "N2.N3.COM", "N1.N.COM", "N.COM", "COM", "N3.COM"); - check("N1.COM", "N2.COM", "N1.COM", "COM"); // 1 common - check("N1", "N2", "N1"); // 0 common - // Extra garbages - check("A1.COM", "A4.COM", "A1.COM", "A2.COM"); + check("N1.COM", "N2.COM", "N1.COM", "COM"); + check("N1", "N2", "N1"); + check("N1.COM", "N2.ORG", "N1.COM", "COM", "ORG"); + check("N1.N.COM", "N.COM", "N1.N.COM"); + check("X.N1.N.COM", "N.COM", "X.N1.N.COM", "N1.N.COM"); + check("N.COM", "N1.N.COM", "N.COM"); + check("N.COM", "X.N1.N.COM", "N.COM", "N1.N.COM"); + check("A.B.C", "D.E.F", "A.B.C", "B.C", "C", "F", "E.F"); + + // Full path + check("A1.COM", "A2.COM", "A1.COM"); + check("A1.COM", "A3.COM", "A1.COM", "A2.COM"); + check("A1.COM", "A4.COM", "A1.COM", "A2.COM", "A3.COM"); + + // Shortest path + check("B1.COM", "B2.COM", "B1.COM"); check("B1.COM", "B3.COM", "B1.COM", "B2.COM"); + check("B1.COM", "B4.COM", "B1.COM", "B2.COM", "B3.COM"); + // Missing is "." + check("C1.COM", "C2.COM", "C1.COM", "COM"); check("C1.COM", "C3.COM", "C1.COM", "C2.COM"); - // Multiple path - check("D1.COM", "D4.COM", "D1.COM", "D2.COM"); - check("E1.COM", "E4.COM", "E1.COM", "E2.COM"); - check("F1.COM", "F4.COM", "F1.COM", "F9.COM"); - // Infinite loop - check("G1.COM", "G3.COM", "G1.COM", "COM"); - check("H1.COM", "H3.COM", "H1.COM"); + + // cRealm = . + check("D1.COM", "D2.COM", "D1.COM"); + + // Bad cases + check("E1.COM", "E2.COM", "E1.COM"); + check("E1.COM", "E3.COM", "E1.COM", "E4.COM"); + check("G1.COM", "G3.COM", "G1.COM", "G2.COM"); check("I1.COM", "I4.COM", "I1.COM", "I5.COM"); - // J2=J1 is the same as J2=. - check("J1.COM", "J2.COM", "J1.COM"); + // 7019384 check("A9.PRAGUE.XXX.CZ", "SERVIS.XXX.CZ", "A9.PRAGUE.XXX.CZ", "PRAGUE.XXX.CZ", "ROOT.XXX.CZ"); + if (failed != null) { throw failed; } @@ -75,6 +113,7 @@ public class ParseCAPaths { try { check2(from, to, paths); } catch (Exception e) { + System.out.println(" " + e.getMessage()); failed = e; } } @@ -84,18 +123,14 @@ public class ParseCAPaths { System.out.println(from + " -> " + to); System.out.println(" expected: " + Arrays.toString(paths)); String[] result = Realm.getRealmsList(from, to); - System.out.println(" result: " + Arrays.toString(result)); - if (result == null) { - if (paths.length == 0) { - // OK - } else { - throw new Exception("Shouldn't have a valid path."); - } + if (result == null || result.length == 0) { + throw new Exception("There is always a valid path."); } else if(result.length != paths.length) { throw new Exception("Length of path not correct"); } else { for (int i=0; i Date: Wed, 18 Sep 2013 14:10:24 +0100 Subject: [PATCH 045/293] 8024883: (se) SelectableChannel.register throws NPE if fd >= 64k (lnx) Co-authored-by: Norman Maurer Reviewed-by: alanb, coffeys --- .../sun/nio/ch/DevPollArrayWrapper.java | 7 +++++-- .../classes/sun/nio/ch/EPollArrayWrapper.java | 18 +++++++++++++++--- .../classes/sun/nio/ch/EventPortWrapper.java | 12 +++++++++--- .../nio/channels/Selector/LotsOfChannels.java | 5 +++-- .../nio/channels/Selector/SelectorLimit.java | 3 ++- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java index df30e2924f2..6eeee2a7532 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java @@ -26,9 +26,11 @@ package sun.nio.ch; import java.io.IOException; +import java.security.AccessController; import java.util.BitSet; import java.util.Map; import java.util.HashMap; +import sun.security.action.GetIntegerAction; /** @@ -78,10 +80,11 @@ class DevPollArrayWrapper { static final int NUM_POLLFDS = Math.min(OPEN_MAX-1, 8192); // Initial size of arrays for fd registration changes - private final int INITIAL_PENDING_UPDATE_SIZE = 64; + private static final int INITIAL_PENDING_UPDATE_SIZE = 64; // maximum size of updatesLow - private final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // The pollfd array for results from devpoll driver private final AllocatedNativeObject pollArray; diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java index a73d3c2dff1..f64feb24c75 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java @@ -26,9 +26,11 @@ package sun.nio.ch; import java.io.IOException; +import java.security.AccessController; import java.util.BitSet; import java.util.HashMap; import java.util.Map; +import sun.security.action.GetIntegerAction; /** * Manipulates a native array of epoll_event structs on Linux: @@ -78,8 +80,8 @@ class EPollArrayWrapper { private static final int INITIAL_PENDING_UPDATE_SIZE = 64; // maximum size of updatesLow - private static final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); - + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // The fd of the epoll driver private final int epfd; @@ -163,6 +165,16 @@ class EPollArrayWrapper { return pollArray.getInt(offset); } + /** + * Returns {@code true} if updates for the given key (file + * descriptor) are killed. + */ + private boolean isEventsHighKilled(Integer key) { + assert key >= MAX_UPDATE_ARRAY_SIZE; + Byte value = eventsHigh.get(key); + return (value != null && value == KILLED); + } + /** * Sets the pending update events for the given file descriptor. This * method has no effect if the update events is already set to KILLED, @@ -175,7 +187,7 @@ class EPollArrayWrapper { } } else { Integer key = Integer.valueOf(fd); - if ((eventsHigh.get(key) != KILLED) || force) { + if (!isEventsHighKilled(key) || force) { eventsHigh.put(key, Byte.valueOf(events)); } } diff --git a/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java index bec37360642..d9383eb7ed0 100644 --- a/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java +++ b/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java @@ -25,9 +25,14 @@ package sun.nio.ch; -import sun.misc.Unsafe; import java.io.IOException; -import java.util.*; +import java.security.AccessController; +import java.util.BitSet; +import java.util.HashMap; +import java.util.Map; + +import sun.misc.Unsafe; +import sun.security.action.GetIntegerAction; import static sun.nio.ch.SolarisEventPort.*; /** @@ -49,7 +54,8 @@ class EventPortWrapper { private final int INITIAL_PENDING_UPDATE_SIZE = 256; // maximum size of updateArray - private final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024); + private static final int MAX_UPDATE_ARRAY_SIZE = AccessController.doPrivileged( + new GetIntegerAction("sun.nio.ch.maxUpdateArraySize", Math.min(OPEN_MAX, 64*1024))); // special update status to indicate that it should be ignored private static final byte IGNORE = -1; diff --git a/jdk/test/java/nio/channels/Selector/LotsOfChannels.java b/jdk/test/java/nio/channels/Selector/LotsOfChannels.java index d88655d807f..2db6366a7fd 100644 --- a/jdk/test/java/nio/channels/Selector/LotsOfChannels.java +++ b/jdk/test/java/nio/channels/Selector/LotsOfChannels.java @@ -22,9 +22,10 @@ */ /* @test - * @bug 4503092 + * @bug 4503092 8024883 * @summary Tests that Windows Selector can use more than 63 channels - * @run main/timeout=300 LotsOfChannels + * @run main LotsOfChannels + * @run main/othervm -Dsun.nio.ch.maxUpdateArraySize=64 LotsOfChannels * @author kladko */ diff --git a/jdk/test/java/nio/channels/Selector/SelectorLimit.java b/jdk/test/java/nio/channels/Selector/SelectorLimit.java index 27589e24665..69963db8e04 100644 --- a/jdk/test/java/nio/channels/Selector/SelectorLimit.java +++ b/jdk/test/java/nio/channels/Selector/SelectorLimit.java @@ -22,12 +22,13 @@ */ /* @test - * @bug 4777504 + * @bug 4777504 8024883 * @summary Ensure that a Selector can return at least 100 selected keys * @author Mark Reinhold * @library .. * @build SelectorLimit * @run main/othervm SelectorLimit + * @run main/othervm -Dsun.nio.ch.maxUpdateArraySize=128 SelectorLimit */ import java.io.*; From ac8db73a7c956bdcc3749a0262a2af5ffbe60d3a Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 18 Sep 2013 21:37:45 +0800 Subject: [PATCH 046/293] 8011402: Move blacklisting certificate logic from hard code to data Reviewed-by: erikj, mullan --- jdk/make/java/security/Makefile | 25 +- jdk/makefiles/CopyFiles.gmk | 19 + .../java/security/cert/Certificate.java | 19 +- .../security/util/UntrustedCertificates.java | 907 ++---------------- .../sun/security/x509/X509CertImpl.java | 42 + .../security/BlacklistedCertsConverter.java | 89 ++ jdk/src/share/lib/security/blacklisted.certs | 19 + .../share/lib/security/blacklisted.certs.pem | 721 ++++++++++++++ .../lib/security/CheckBlacklistedCerts.java | 131 +++ 9 files changed, 1118 insertions(+), 854 deletions(-) create mode 100644 jdk/src/share/lib/security/BlacklistedCertsConverter.java create mode 100644 jdk/src/share/lib/security/blacklisted.certs create mode 100644 jdk/src/share/lib/security/blacklisted.certs.pem create mode 100644 jdk/test/lib/security/CheckBlacklistedCerts.java diff --git a/jdk/make/java/security/Makefile b/jdk/make/java/security/Makefile index bbb0ca4f757..05b6b8a5664 100644 --- a/jdk/make/java/security/Makefile +++ b/jdk/make/java/security/Makefile @@ -70,9 +70,13 @@ POLICY_BUILD = $(LIBDIR)/security/java.policy CACERTS_SRC = $(CACERTS_FILE) CACERTS_BUILD = $(LIBDIR)/security/cacerts +BLACKLISTED_CERTS_SRC = $(TOPDIR)/src/share/lib/security/blacklisted.certs +BLACKLISTED_CERTS_BUILD = $(LIBDIR)/security/blacklisted.certs + ifndef OPENJDK BLACKLIST_SRC = $(CLOSED_SHARE_SRC)/lib/security/blacklist BLACKLIST_BUILD = $(LIBDIR)/security/blacklist + BLACKLISTED_CERTS_SRC += $(wildcard $(CLOSED_SHARE_SRC)/lib/security/blacklisted.certs) TRUSTEDLIBS_SRC = $(CLOSED_SHARE_SRC)/lib/security/trusted.libraries TRUSTEDLIBS_BUILD = $(LIBDIR)/security/trusted.libraries endif @@ -85,9 +89,9 @@ FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class) include $(BUILDDIR)/common/Rules.gmk ifdef OPENJDK -build: properties policy cacerts +build: properties policy cacerts blacklisted-certs else -build: properties policy cacerts blacklist trustedlibs +build: properties policy cacerts blacklist blacklisted-certs trustedlibs endif install: all @@ -100,6 +104,8 @@ cacerts: classes $(CACERTS_BUILD) blacklist: classes $(BLACKLIST_BUILD) +blacklisted-certs: classes $(BLACKLISTED_CERTS_BUILD) + trustedlibs: classes $(TRUSTEDLIBS_BUILD) $(PROPS_BUILD): $(PROPS_SRC) @@ -114,12 +120,25 @@ $(CACERTS_BUILD): $(CACERTS_SRC) $(BLACKLIST_BUILD): $(BLACKLIST_SRC) $(install-file) +$(BLACKLISTED_CERTS_BUILD): $(BLACKLISTED_CERTS_SRC) + $(MKDIR) -p $(@D) + $(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp + $(GREP) -i Algorithm $@.tmp > $@ + if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \ + $(ECHO) "Different algorithms defined in $^"; \ + $(RM) $@ $@.tmp; \ + false; \ + fi + $(GREP) -iv Algorithm $@.tmp >> $@ + $(RM) $@.tmp + $(TRUSTEDLIBS_BUILD): $(TRUSTEDLIBS_SRC) $(install-file) clean clobber:: .delete.classlist $(RM) -r $(CLASSBINDIR)/java/security - $(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) $(TRUSTEDLIBS_BUILD) + $(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) \ + $(BLACKLISTED_CERTS_BUILD) $(TRUSTEDLIBS_BUILD) # Additional Rule for building sun.security.util $(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java diff --git a/jdk/makefiles/CopyFiles.gmk b/jdk/makefiles/CopyFiles.gmk index 2b3cbf2e200..abdf3546a18 100644 --- a/jdk/makefiles/CopyFiles.gmk +++ b/jdk/makefiles/CopyFiles.gmk @@ -382,11 +382,16 @@ COPY_FILES += $(CACERTS_DST) ########################################################################################## +BLACKLISTED_CERTS_SRC := $(JDK_TOPDIR)/src/share/lib/security/blacklisted.certs +BLACKLISTED_CERTS_DST := $(JDK_OUTPUTDIR)/lib/security/blacklisted.certs + ifndef OPENJDK BLACKLIST_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/blacklist BLACKLIST_DST := $(JDK_OUTPUTDIR)/lib/security/blacklist +BLACKLISTED_CERTS_SRC += $(wildcard $(JDK_TOPDIR)/src/closed/share/lib/security/blacklisted.certs) + TRUSTEDLIBS_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/trusted.libraries TRUSTEDLIBS_DST := $(JDK_OUTPUTDIR)/lib/security/trusted.libraries @@ -402,6 +407,20 @@ COPY_FILES += $(TRUSTEDLIBS_DST) endif +$(BLACKLISTED_CERTS_DST): $(BLACKLISTED_CERTS_SRC) + $(MKDIR) -p $(@D) + $(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp + $(GREP) -i Algorithm $@.tmp > $@ + if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \ + $(ECHO) "Different algorithms defined in $^"; \ + $(RM) $@ $@.tmp; \ + false; \ + fi + $(GREP) -iv Algorithm $@.tmp >> $@ + $(RM) $@.tmp + +COPY_FILES += $(BLACKLISTED_CERTS_DST) + ########################################################################################## ifndef OPENJDK diff --git a/jdk/src/share/classes/java/security/cert/Certificate.java b/jdk/src/share/classes/java/security/cert/Certificate.java index 638a02e6f80..10544983d2c 100644 --- a/jdk/src/share/classes/java/security/cert/Certificate.java +++ b/jdk/src/share/classes/java/security/cert/Certificate.java @@ -66,6 +66,9 @@ public abstract class Certificate implements java.io.Serializable { // the certificate type private final String type; + /** Cache the hash code for the certiticate */ + private int hash = -1; // Default to -1 + /** * Creates a certificate of the specified type. * @@ -123,16 +126,16 @@ public abstract class Certificate implements java.io.Serializable { * @return the hashcode value. */ public int hashCode() { - int retval = 0; - try { - byte[] certData = X509CertImpl.getEncodedInternal(this); - for (int i = 1; i < certData.length; i++) { - retval += certData[i] * i; + int h = hash; + if (h == -1) { + try { + h = Arrays.hashCode(X509CertImpl.getEncodedInternal(this)); + } catch (CertificateException e) { + h = 0; } - return retval; - } catch (CertificateException e) { - return retval; + hash = h; } + return h; } /** diff --git a/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java b/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java index 73495df5bcc..e14229b3c9d 100644 --- a/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java +++ b/jdk/src/share/classes/sun/security/util/UntrustedCertificates.java @@ -24,13 +24,15 @@ */ package sun.security.util; -import java.io.IOException; -import java.io.ByteArrayInputStream; +import java.io.*; +import java.security.AccessController; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivilegedAction; import java.security.cert.X509Certificate; -import java.security.cert.CertificateFactory; import java.security.cert.CertificateException; -import java.util.Set; -import java.util.HashSet; +import java.util.*; +import sun.security.x509.X509CertImpl; /** * A utility class to check if a certificate is untrusted. This is an internal @@ -42,8 +44,50 @@ import java.util.HashSet; */ public final class UntrustedCertificates { - private final static Set untrustedCerts = new HashSet<>(); + private static final Debug debug = Debug.getInstance("certpath"); + private static final String ALGORITHM_KEY = "Algorithm"; + private static final Properties props = new Properties(); + private static final String algorithm; + + static { + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { + File f = new File(System.getProperty("java.home"), + "lib/security/blacklisted.certs"); + try (FileInputStream fin = new FileInputStream(f)) { + props.load(fin); + // It's said that the fingerprint could contain colons + for (Map.Entry e: props.entrySet()) { + e.setValue(stripColons(e.getValue())); + } + } catch (IOException fnfe) { + if (debug != null) { + debug.println("Error parsing blacklisted.certs"); + } + } + return null; + } + }); + algorithm = props.getProperty(ALGORITHM_KEY); + } + + private static String stripColons(Object input) { + String s = (String)input; + char[] letters = s.toCharArray(); + int pos = 0; + for (int i = 0; i < letters.length; i++) { + if (letters[i] != ':') { + if (i != pos) { + letters[pos] = letters[i]; + } + pos++; + } + } + if (pos == letters.length) return s; + else return new String(letters, 0, pos); + } /** * Checks if a certificate is untrusted. * @@ -51,844 +95,21 @@ public final class UntrustedCertificates { * @return true if the certificate is untrusted. */ public static boolean isUntrusted(X509Certificate cert) { - return untrustedCerts.contains(cert); - } - - private static void add(String alias, String pemCert) { - // generate certificate from PEM certificate - try (ByteArrayInputStream is = - new ByteArrayInputStream(pemCert.getBytes())) { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = (X509Certificate)cf.generateCertificate(is); - - if (!untrustedCerts.add(cert)) { - throw new RuntimeException("Duplicate untrusted certificate: " + - cert.getSubjectX500Principal()); - } - } catch (CertificateException | IOException e) { - throw new RuntimeException( - "Incorrect untrusted certificate: " + alias, e); + if (algorithm == null) { + return false; } + String key; + if (cert instanceof X509CertImpl) { + key = ((X509CertImpl)cert).getFingerprint(algorithm); + } else { + try { + key = new X509CertImpl(cert.getEncoded()).getFingerprint(algorithm); + } catch (CertificateException cee) { + return false; + } + } + return props.containsKey(key); } - static { - // ----------------------------------------------------------------- - // Compromised CAs of Digicert Malaysia - // - // Reported by Digicert in its announcement on November 05, 2011. - // - - // Digicert Malaysia intermediate, cross-signed by CyberTrust - // - // Subject: CN=Digisign Server ID (Enrich), - // OU=457608-K, - // O=Digicert Sdn. Bhd., - // C=MY - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120001705 (07:27:14:a9) - add("digicert-server-cross-to-cybertrust-4C0E636A", - "-----BEGIN CERTIFICATE-----\n" + - "MIIDyzCCAzSgAwIBAgIEBycUqTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA3MDcxNzE1MTc0OFoXDTEyMDcxNzE1MTY1NFowYzELMAkG\n" + - "A1UEBhMCTVkxGzAZBgNVBAoTEkRpZ2ljZXJ0IFNkbi4gQmhkLjERMA8GA1UECxMI\n" + - "NDU3NjA4LUsxJDAiBgNVBAMTG0RpZ2lzaWduIFNlcnZlciBJRCAoRW5yaWNoKTCB\n" + - "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArahkS02Hx4RZufuQRqCmicDx/tXa\n" + - "VII3DZkrRSYK6Fawf8qo9I5HhAGCKeOzarWR8/uVhbxyqGToCkCcxfRxrnt7agfq\n" + - "kBRPjYmvlKuyBtQCanuYH1m5Os1U+iDfsioK6bjdaZDAKdNO0JftZszFGUkGf/pe\n" + - "LHx7hRsyQt97lSUCAwEAAaOCAXgwggF0MBIGA1UdEwEB/wQIMAYBAf8CAQAwXAYD\n" + - "VR0gBFUwUzBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy\n" + - "dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMAcGBWCDSgEBMA4GA1Ud\n" + - "DwEB/wQEAwIB5jCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYTAlVTMRgwFgYD\n" + - "VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv\n" + - "bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv\n" + - "b3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVibGljLXRydXN0\n" + - "LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYDVR0OBBYEFMYWk04WF+wW\n" + - "royUdvOGbcV0boR3MA0GCSqGSIb3DQEBBQUAA4GBAHYAe6Z4K2Ydjl42xqSOBfIj\n" + - "knyTZ9P0wAp9iy3Z6tVvGvPhSilaIoRNUC9LDPL/hcJ7VdREgr5trGeOvLQfkpxR\n" + - "gBoU9m6rYYgLrRx/90tQUdZlG6ZHcRVesHHzNRTyN71jyNXwk1o0X9g96F33xR7A\n" + - "5c8fhiSpPAdmzcHSNmNZ\n" + - "-----END CERTIFICATE-----"); - - // Digicert Malaysia intermediate, cross-signed by Entrust - // - // Subject: CN=Digisign Server ID - (Enrich), - // OU=457608-K, - // O=Digicert Sdn. Bhd., - // C=MY - // Issuer: CN=Entrust.net Certification Authority (2048) - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), - // O=Entrust.net - // Serial: 1184644297 (4c:0e:63:6a) - add("digicert-server-cross-to-entrust-ca-4C0E636A", - "-----BEGIN CERTIFICATE-----\n" + - "MIIEzjCCA7agAwIBAgIETA5jajANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML\n" + - "RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp\n" + - "bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5\n" + - "IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp\n" + - "ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0xMDA3MTYxNzIzMzdaFw0xNTA3\n" + - "MTYxNzUzMzdaMGUxCzAJBgNVBAYTAk1ZMRswGQYDVQQKExJEaWdpY2VydCBTZG4u\n" + - "IEJoZC4xETAPBgNVBAsTCDQ1NzYwOC1LMSYwJAYDVQQDEx1EaWdpc2lnbiBTZXJ2\n" + - "ZXIgSUQgLSAoRW5yaWNoKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" + - "AMWJ5PQNBkCSWccaszXRDkwqM/n4r8qef+65p21g9FTob9Wb8xtjMQRoctE0Foy0\n" + - "FyyX3nPF2JAVoBor9cuzSIZE8B2ITM5BQhrv9Qze/kDaOSD3BlU6ap1GwdJvpbLI\n" + - "Vz4po5zg6YV3ZuiYpyR+vsBZIOVEb7ZX2L7OwmV3WMZhQdF0BMh/SULFcqlyFu6M\n" + - "3RJdtErU0a9Qt9iqdXZorT5dqjBtYairEFs+E78z4K9EnTgiW+9ML6ZxJhUmyiiM\n" + - "2fqOjqmiFDXimySItPR/hZ2DTwehthSQNsQ0HI0mYW0Tb3i+6I8nx0uElqOGaAwj\n" + - "vgvsjJQAqQSKE5D334VsDLECAwEAAaOCATQwggEwMA4GA1UdDwEB/wQEAwIBBjAS\n" + - "BgNVHRMBAf8ECDAGAQH/AgEAMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcD\n" + - "AgYIKwYBBQUHAwQwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8v\n" + - "b2NzcC5lbnRydXN0Lm5ldDBEBgNVHSAEPTA7MDkGBWCDSgEBMDAwLgYIKwYBBQUH\n" + - "AgEWImh0dHA6Ly93d3cuZGlnaWNlcnQuY29tLm15L2Nwcy5odG0wMgYDVR0fBCsw\n" + - "KTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3JsMBEGA1Ud\n" + - "DgQKBAhMTswlKAMpgTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDAN\n" + - "BgkqhkiG9w0BAQUFAAOCAQEAl0zvSjpJrHL8MCBrtClbp8WVBJD5MtXChWreA6E3\n" + - "+YkAsFqsVX7bQzX/yQH4Ub7MJsrIaqTEVD4mHucMo82XZ5TdpkLrXM2POXlrM3kh\n" + - "Bnn6gkQVmczBtznTRmJ8snDrb84gqj4Zt+l0gpy0pUtNYQA35IfS8hQ6ZHy4qXth\n" + - "4JMi59WfPkfmNnagU9gAAzoPtTP+lsrT0oI6Lt3XSOHkp2nMHOmZSufKcEXXCwcO\n" + - "mnUb0C+Sb/akB8O9HEumhLZ9qJqp0qcp8QtXaR6XVybsK0Os1EWDBQDp4/BGQAf6\n" + - "6rFRc5Mcpd1TETfIKqcVJx20qsx/qjEw/LhFn0gJ7RDixQ==\n" + - "-----END CERTIFICATE-----"); - - - // ----------------------------------------------------------------- - // - // No longer used certificates - // - - // Subject: CN=Java Media APIs, - // OU=Java Signed Extensions, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 6a:8b:99:91:37:59:4f:89:53:e2:97:18:9f:19:1e:4e - add("java-media-pretrusted-9F191E4E", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFdzCCBF+gAwIBAgIQaouZkTdZT4lT4pcYnxkeTjANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDUxMjAw\n" + - "MDAwMFoXDTEyMDUxMTIzNTk1OVowfTEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt\n" + - "cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE\n" + - "CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEYMBYGA1UEAxQPSmF2YSBNZWRpYSBB\n" + - "UElzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl5blzoKTVE8y4Hpz\n" + - "q6E15RZz1bF5HnYEyYqgHkZXnAKedmYCoMzm1XK8s+gQWShLEvGEAvs5yqarx9gE\n" + - "nnC21N28aEZgIJMa2/arKxCUkS4pxdGPYGexL9UzSRkUpoBShCZKEGdmX7gfJE2K\n" + - "/sd9MFvGV5/yZtWXrADzvm0Kd/9mg1KRv1gfrZIq0TJbupoXPYYqb73AkI9eT2ZD\n" + - "q9MdwD4E5+oojsDFXt8GU/D00fUhtXpYwuplU7D667WHYdJhIah0ST6JywyqcLXG\n" + - "XSuFTXOgITT2idSHluZVmx3dqJ72u9kPkO4JdJTMDfaK8zgNLaRkiU8Qcj+qhLYH\n" + - "ytaqcwIDAQABo4IB6jCCAeYwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwfwYD\n" + - "VR0fBHgwdjB0oHKgcIZuaHR0cDovL29uc2l0ZWNybC52ZXJpc2lnbi5jb20vU3Vu\n" + - "TWljcm9zeXN0ZW1zSW5jQ29ycG9yYXRlT2JqZWN0U2lnbmluZ0phdmFTaWduZWRF\n" + - "eHRlbnNpb25zQ2xhc3NCL0xhdGVzdENSTC5jcmwwHwYDVR0jBBgwFoAUs0crgn5T\n" + - "tHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFKS32mVx0gNWTeS4ProHEaeSpvvIMDsG\n" + - "CCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3NwLnZl\n" + - "cmlzaWduLmNvbTCBtQYDVR0gBIGtMIGqMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYB\n" + - "BQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwbQYLYIZIAYb3AIN9\n" + - "nD8wXjAnBggrBgEFBQcCARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDMG\n" + - "CCsGAQUFBwICMCcaJVZhbGlkYXRlZCBGb3IgU3VuIEJ1c2luZXNzIE9wZXJhdGlv\n" + - "bnMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQEFBQADggEBAAe6BO4W\n" + - "3TSNWfezyelJs6kE3HfulT6Bdyz4UUoh9ykXcV8nRwT+kh25I5MdyG2GfkJoADPR\n" + - "VhC5DYo13UFpIsTNVjq+hGYe2hML93bN7ad9SxCCyjHUo3yMz2qgBbHZI3VA9ZHA\n" + - "aWM4Tx0saMwbcnVvlbuGh+PXvStfypJqYT6lzcdFfjNVX4FI/QQNGhBswMY51tC8\n" + - "GTBCL2qhJon0gSCU4zaawDOf7+XxJWirLamYL1Aal1/h2z2sFrvA/1ftxtU3kZ6I\n" + - "7De8DyoHeZg7pYGdrj7g+lPhCga/WvEhN152I+aP08YbFcJHYmK05ngl/Ye4c6Bd\n" + - "cdrdfbw6QzEUIYY=\n" + - "-----END CERTIFICATE-----"); - - // Subject: CN=JavaFX 1.0 Runtime, - // OU=Java Signed Extensions, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 55:c0:e6:44:59:59:79:9e:d9:26:f1:b0:4a:1e:f0:27 - add("java-fx10-pretrusted-4A1EF027", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFezCCBGOgAwIBAgIQVcDmRFlZeZ7ZJvGwSh7wJzANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA4MTAwOTAw\n" + - "MDAwMFoXDTExMTAwOTIzNTk1OVowgYAxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl\n" + - "bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxHzAdBgNV\n" + - "BAsUFkphdmEgU2lnbmVkIEV4dGVuc2lvbnMxGzAZBgNVBAMUEkphdmFGWCAxLjAg\n" + - "UnVudGltZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM+WDc6+bu+4\n" + - "tmAcS/lBtUc02WOt9QZpVsXg9cG2pu/8bUtmDELa8iiYBVFpIs8DU58HLrGQtCUY\n" + - "SIAGOVPsOJoN29UKCDWfY9j5JeVhfhMGqk9DwrWhzgsjy4cpZ1pIp+k/fJ8zT8Ul\n" + - "aYLpow1vg3UNddsmwz02tN7cOrMw9WYIG4CRYnY1OrtJSfe2pYzheC4zyvR+aiVl\n" + - "nang2OtqikSQsNFOFHsLOJFxngy9LrO8evDSu25VTKI6zlWU6/bMeqtztJPN0VOn\n" + - "NyUrJZvkxZ207Jg0T693BGSxNC1n+ihztXogql8950M/pEuUbDjylv5FFvlp6DSB\n" + - "dDT2MkutmyMCAwEAAaOCAeowggHmMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeA\n" + - "MH8GA1UdHwR4MHYwdKByoHCGbmh0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29t\n" + - "L1N1bk1pY3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdKYXZhU2ln\n" + - "bmVkRXh0ZW5zaW9uc0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaAFLNH\n" + - "K4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBTjgufVi3XJ3gx1ewsA6Rr7BR4Z\n" + - "zjA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUtb2Nz\n" + - "cC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAqMCgG\n" + - "CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CGSAGG\n" + - "9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtpL2Nw\n" + - "czAzBggrBgEFBQcCAjAnGiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVy\n" + - "YXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IBAQAB\n" + - "YVJTTVe7rzyTO4jc3zajErOT/COkdQTfNo0eIX1QbNynFieJvwY/jRzUZwjktIFR\n" + - "2p4JtbpHGAtKtjOAOTieQ8xdDOoC1djzpE7/AbMvuvlTavtUKT+F7tPdhfXgWXJV\n" + - "6Wbt8jryKyk3zZGiEhauIwZUkfjRkEtffEmZWLUd8c8rURJjfC/XHH2oyurscoxc\n" + - "CjX29c9ynxSiS/VvQp1an0HvErGh69N48wj7cj8mtZ1yHzd2XCzSSR1OfTPfk0Pt\n" + - "yg51p7yJaFiH21PTZegEL6zyVNOYBTKwwIi2OzpwYalD3uvK6e3OKDrfFCOxu17u\n" + - "4PveESbrdyrmvLe7IVez\n" + - "-----END CERTIFICATE-----"); - - // Subject: CN=JavaFX Runtime, - // OU=Java Signed Extensions, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 47:f4:55:f1:da:4a:5e:f9:e3:f7:a8:03:62:17:c0:ff - add("javafx-runtime-pretrusted-6217C0FF", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFdjCCBF6gAwIBAgIQR/RV8dpKXvnj96gDYhfA/zANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDEyOTAw\n" + - "MDAwMFoXDTEyMDEyOTIzNTk1OVowfDEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt\n" + - "cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE\n" + - "CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEXMBUGA1UEAxQOSmF2YUZYIFJ1bnRp\n" + - "bWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIzd0fAk8mI9ONc6RJ\n" + - "aGieioK2FLdXEwj8zL3vdGDVmBwyR1zwYkaOIFFgF9IW/8qc4iAYA5sGUY+0g8q3\n" + - "5DuYAxfTzBB5KdaYvbuq6GGnoHIWmTirXY+1friFp8lyXSvtuEaGB1VHaBoZchEg\n" + - "k+UgeVDA43dHwcT1Ov3DePczJRUes8T/QHzLX+BxUDG43vjyncCEO/AjqLZxXEz2\n" + - "xrNbKLcH3lGMJK7hdbfssUfF5BjC38Hn71HauYlA43b2no+2y0Sjulwzez2YPbDC\n" + - "0GLR3TnKtA8dqOrnl5t3DniDbfOBNtBE3VOydJO0XW57Ng1HRXD023nm9ECPY2xp\n" + - "0N/pAgMBAAGjggHqMIIB5jAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDB/BgNV\n" + - "HR8EeDB2MHSgcqBwhm5odHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9TdW5N\n" + - "aWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nSmF2YVNpZ25lZEV4\n" + - "dGVuc2lvbnNDbGFzc0IvTGF0ZXN0Q1JMLmNybDAfBgNVHSMEGDAWgBSzRyuCflO0\n" + - "c8q4uxm3voFNB5XH7TAdBgNVHQ4EFgQUvOdd0cKPj+Yik/iOBwTdphh5A+gwOwYI\n" + - "KwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb25zaXRlLW9jc3AudmVy\n" + - "aXNpZ24uY29tMIG1BgNVHSAEga0wgaowOQYLYIZIAYb4RQEHFwIwKjAoBggrBgEF\n" + - "BQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTBtBgtghkgBhvcAg32c\n" + - "PzBeMCcGCCsGAQUFBwIBFhtodHRwczovL3d3dy5zdW4uY29tL3BraS9jcHMwMwYI\n" + - "KwYBBQUHAgIwJxolVmFsaWRhdGVkIEZvciBTdW4gQnVzaW5lc3MgT3BlcmF0aW9u\n" + - "czATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAbGcf2NjL\n" + - "AI93HG6ny2BbepaZA1a8xa/R6uUc7xV+Qw6MgLwFD4Q4i6LWUztQDvg9l68MM2/i\n" + - "Y9LEi1KM4lcNbK5+D+t9x98wXBiuojXhVdp5ZmC03EyEBbriopdBsmXVLDSu/Y3+\n" + - "zowOO5xwpMK3dbgsSDs2Vt0UosD3FTcRaD3GNfOhXMp+o1grHNiXF9YgkmdQbPPZ\n" + - "DQ2KBhFPCRJXBGvyKOqno/DTg0sQ3crGH/C4/4t7mnQXWldZotmJUZ0ONc9oD+Q1\n" + - "JAaguUKqIwn9yZ093ie+JWHbYNid9IIIPXYgtRxmf9a376WBhqhu56uJftBJ7x9g\n" + - "eQ7Lot6CSWCiFw==\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised Solaris INTERNAL DEVELOPMENT USE ONLY certificate - // - - // Subject: CN=Solaris INTERNAL DEVELOPMENT USE ONLY, - // OU=Solaris Cryptographic Framework, - // OU=Corporate Object Signing, - // O=Sun Microsystems Inc - // Issuer: CN=Object Signing CA, - // OU=Class 2 OnSite Subscriber CA, - // OU=VeriSign Trust Network, - // O=Sun Microsystems Inc - // Serial: 77:29:77:52:6a:19:7b:9a:a6:a2:c7:99:a0:e1:cd:8c - add("solaris-internal-dev-A0E1CD8C", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFHjCCBAagAwIBAgIQdyl3UmoZe5qmoseZoOHNjDANBgkqhkiG9w0BAQUFADCB\n" + - "gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT\n" + - "aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj\n" + - "cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA3MDEwNDAw\n" + - "MDAwMFoXDTEwMDEwMzIzNTk1OVowgZwxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl\n" + - "bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxKDAmBgNV\n" + - "BAsUH1NvbGFyaXMgQ3J5cHRvZ3JhcGhpYyBGcmFtZXdvcmsxLjAsBgNVBAMUJVNv\n" + - "bGFyaXMgSU5URVJOQUwgREVWRUxPUE1FTlQgVVNFIE9OTFkwgZ8wDQYJKoZIhvcN\n" + - "AQEBBQADgY0AMIGJAoGBALbNU4hf3mD5ArDI9pjgioAyvV3bjMPRQdCZniIeGJBp\n" + - "odFlSEH+Mh64W1DsY8coeZ7FvvGJkx9IpTMJW9k8w1oJK9UNqHyAQfaYjQyXi3xQ\n" + - "LJp62EvYdGfDlwOZejEcR/MbzZG+GOPMMvQj5+xyFDvLXNGfQNTnxw2qnBgCJXjj\n" + - "AgMBAAGjggH1MIIB8TAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDCBiQYDVR0f\n" + - "BIGBMH8wfaB7oHmGd2h0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29tL1N1bk1p\n" + - "Y3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdTb2xhcmlzQ3J5cHRv\n" + - "Z3JhcGhpY0ZyYW1ld29ya0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaA\n" + - "FLNHK4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBRpfiGYkehTnsIzuN2H6AFb\n" + - "VCZG8jA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUt\n" + - "b2NzcC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAq\n" + - "MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CG\n" + - "SAGG9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtp\n" + - "L2NwczAzBggrBgEFBQcCAjAnFiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBP\n" + - "cGVyYXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IB\n" + - "AQCG5soy3LFHTFbA8/5SzDRhQoJkHUnOP0t3b6nvX6vZYRp649fje7TQOPRm1pFd\n" + - "CZ17J+tggdZwgzTqY4aYpJ00jZaK6pV37q/vgFC/ia6jDs8Q+ly9cEcadBZ5loYg\n" + - "cmxp9p57W2MNWx8VA8oFdNtKfF0jUNXbLNtvwGHmgR6YcwLrGN1b6/9Lt9bO3ODl\n" + - "FO+ZDwkfQz5ClUVrTx2dGBvKRYFqSG5S8JAfsgYhPvcacUQkA7ExyKvfRXLWVrce\n" + - "ZiPpcElbx+819H2sAPvVvparVeAruZGMAtejHZp9NFoowKen5drJp9VxePS4eM49\n" + - "3DepB6lKRrNRw66LNQol4ZBz\n" + - "-----END CERTIFICATE-----"); - - - // ----------------------------------------------------------------- - // Compromised CAs of DigiNotar - // - // Reported by Fox-IT in its interim report on September 5, 2011, - // "DigiNotar Certificate Authority breach 'Operation Black Tulip'". - // - - // - // Compromised DigiNotar Cyber CA - // - - // DigiNotar intermediate, cross-signed by CyberTrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, CN=DigiNotar Cyber CA, - // O=DigiNotar, C=NL - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120000525 (07:27:10:0D) - add("info-at-diginotar-cyber-ca-cross-to-gte-cybertrust-0727100D", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFWjCCBMOgAwIBAgIEBycQDTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA2MTAwNDEwNTQxMVoXDTExMTAwNDEwNTMxMVowYDELMAkG\n" + - "A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy\n" + - "IEN5YmVyIENBMSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIw\n" + - "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANLOFQotqF6EZ639vu9Gx8i5z3P8\n" + - "9DS5+SxD52ATPXrjss87Z2yQrcC5P4RS8DVC3HTcKDu9UrSnrHJFF8bwieu0qiXy\n" + - "XUte0dmHutZ9fPXOMp8QM8WxSrtekTHC0OlBwpFkfglBO9uLCDdqqspS3rU5HsCI\n" + - "A6U/i5kTYUO1m4Kz7iBvz6FEouova0CfjytXraFTwoUiaZ2gP1HfC0GRDaXhqKpc\n" + - "SQhdvd5wQbEPyWNr0380dAIvNFp4dRxoeoFnivPaQPBgY/SSINcDpj2jHmfEhBtB\n" + - "pcmM5r3qSLYFFgizNxJa92E89zhvLpfgb1Y4VNMota0Ubi5LZLUnZbd1JQm2Bz2V\n" + - "VgIKgmCyc0XgMyZRdJq51FAc9k1bW1JSE1qmf6cO4ehBVGeYjIfVydNsy9NUkgYJ\n" + - "NEH3gW8/nsl8dVWw58Gzd+jDxAA1lUBwEEoF3iW7n1mlZLxHYL9g43aLE1Xd4XR6\n" + - "uc8kpmp/3mQiRFhogmoQ+T3lPhu5vfwi9GAEibtVbShV+t6OjRshFNc3izR7Tfay\n" + - "shDPM7F9HGKZSMsrbHaWVb8ZDR0fu2WqG46ZtcYokOWCLXhQIJr9eS8kf/CJKWn0\n" + - "fc1zvrPtTsHR7VJej/e4142HrbLZG1ES/1az4a80fVykeIgQnp0DxqWqoiRR90kU\n" + - "xbHuWUOV36toKDA/AgMBAAGjggGGMIIBgjASBgNVHRMBAf8ECDAGAQH/AgEBMFMG\n" + - "A1UdIARMMEowSAYJKwYBBAGxPgEAMDswOQYIKwYBBQUHAgEWLWh0dHA6Ly93d3cu\n" + - "cHVibGljLXRydXN0LmNvbS9DUFMvT21uaVJvb3QuaHRtbDAOBgNVHQ8BAf8EBAMC\n" + - "AQYwgaAGA1UdIwSBmDCBlYAUpgwdn2H/Bxe1vzhG20Mw1Y6wUgaheaR3MHUxCzAJ\n" + - "BgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdU\n" + - "RSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVy\n" + - "VHJ1c3QgR2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93\n" + - "d3cucHVibGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYD\n" + - "VR0OBBYEFKv5aN/PSjfXe0WMX3LeQETDZbvCMA0GCSqGSIb3DQEBBQUAA4GBAI9o\n" + - "a6VbB7pEZg4cqFwwezPkCiYE/O+eGjjWLqEf0JlHwnVkJP2eOyh2uSYoYZEMbSz4\n" + - "BJ98UAHV42mv7xXSRZskCSpmBU8lgcpdvqrBWSeuM46C9990sFWzjvjnN8huqlZE\n" + - "9r1TgSOWPbT6MopTZkQloiXGpjwljPDgKAYityZB\n" + - "-----END CERTIFICATE-----"); - - // DigiNotar intermediate, cross-signed by CyberTrust - // - // Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120000505 (07:27:0F:F9) - add("diginotar-cyber-ca-cross-to-gte-cybertrust-07270FF9", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFODCCBKGgAwIBAgIEBycP+TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA2MDkyMDA5NDUzMloXDTEzMDkyMDA5NDQwNlowPjELMAkG\n" + - "A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy\n" + - "IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o\n" + - "XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S\n" + - "tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7\n" + - "24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp\n" + - "naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj\n" + - "9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu\n" + - "LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU\n" + - "Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk\n" + - "vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6\n" + - "3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt\n" + - "eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4\n" + - "iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB\n" + - "/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC\n" + - "ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s\n" + - "MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV\n" + - "jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv\n" + - "bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD\n" + - "VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6\n" + - "oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw\n" + - "MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI\n" + - "hvcNAQEFBQADgYEACcpiD427SuDUejUrBi3RKGG2rAH7g0m8rtQvLYauGYOl1h0T\n" + - "4he+/jJ06XoUOMqUXvcpAWlxG5Ea/aO7qh3Ke+IW/aGjDvMMX7LhIDGUK16Sdu36\n" + - "6bUjpr8KOwOpb1JgVM1f6bcvfKIn/UGDdbYN+3gm87FF6TKVKho1IZXFonU=\n" + - "-----END CERTIFICATE-----"); - - // DigiNotar intermediate, cross-signed by CyberTrust - // - // Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL - // Issuer: CN=GTE CyberTrust Global Root, - // OU=GTE CyberTrust Solutions, Inc., - // O=GTE Corporation, - // C=US - // Serial: 120000515 (07:27:10:03) - add("diginotar-cyber-ca-cross-to-gte-cybertrust-07271003", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFODCCBKGgAwIBAgIEBycQAzANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV\n" + - "UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU\n" + - "cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds\n" + - "b2JhbCBSb290MB4XDTA2MDkyNzEwNTMzMloXDTExMDkyNzEwNTIzMFowPjELMAkG\n" + - "A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy\n" + - "IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o\n" + - "XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S\n" + - "tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7\n" + - "24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp\n" + - "naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj\n" + - "9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu\n" + - "LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU\n" + - "Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk\n" + - "vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6\n" + - "3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt\n" + - "eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4\n" + - "iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB\n" + - "/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC\n" + - "ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s\n" + - "MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV\n" + - "jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv\n" + - "bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD\n" + - "VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6\n" + - "oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw\n" + - "MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI\n" + - "hvcNAQEFBQADgYEAWcyGZhizJlRP1jjNupZey+yZG6oMDW4Z11boriMHbYPCndBE\n" + - "bVh07zmPbZsihOw9w/vm5KbVX5CgxUv4Rhzh/20Faixf3P3bpWg0qgzHVVusNVR/\n" + - "P50aKkpdK3hp+QLl56e+lWOddSAINIpmcuyDI1hyuzB+GJEASm9tNU/6rs8=\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar Root CA - // - - // DigiNotar intermediate, cross-signed by Entrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, - // CN=DigiNotar Root CA, - // O=DigiNotar, C=NL - // Issuer: CN=Entrust.net Secure Server Certification Authority - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS incorp. by ref. (limits liab.), - // O=Entrust.net, - // C=US, - // Serial: 1184644297 (46:9C:3C:C9) - add("info-at-diginotar-root-ca-cross-to-entrust-secure-server-469C3CC9", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFSDCCBLGgAwIBAgIERpw8yTANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" + - "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" + - "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" + - "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" + - "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA0\n" + - "MjYwNTAwMDBaFw0xMzA4MTQyMDEyMzZaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" + - "EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI\n" + - "hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n" + - "ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt\n" + - "OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx\n" + - "hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7\n" + - "gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D\n" + - "IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T\n" + - "BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs\n" + - "Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8\n" + - "5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf\n" + - "DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX\n" + - "9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e\n" + - "7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj\n" + - "ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB\n" + - "BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF\n" + - "BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD\n" + - "VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy\n" + - "bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G\n" + - "A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob\n" + - "BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAI979rBep8tu3TeLunapgsZ0jtXp\n" + - "GDFjKWSk87dj1jCyYi+q/GyDyZ6ZQZNRP0sF+6twscq05lClWNy3TROMp7QeuoLO\n" + - "G7Utw3OJaswUtp4YglANMRTHEe3g9ltifUXRH5tSuy7u6yi4LD4WTm5ULP6r/g6l\n" + - "0CnjXYb0+b1Fmz6U\n" + - "-----END CERTIFICATE-----"); - - // DigiNotar intermediate, cross-signed by Entrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, - // CN=DigiNotar Root CA, - // O=DigiNotar, C=NL - // Issuer: CN=Entrust.net Secure Server Certification Authority - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS incorp. by ref. (limits liab.), - // O=Entrust.net, - // C=US, - // Serial: 1184640175 (46:9C:2C:AF) - add("info-at-diginotar-root-ca-cross-to-entrust-secure-server-469C2CAF", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" + - "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" + - "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" + - "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" + - "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3\n" + - "MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" + - "EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI\n" + - "hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP\n" + - "ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt\n" + - "OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx\n" + - "hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7\n" + - "gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D\n" + - "IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T\n" + - "BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs\n" + - "Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8\n" + - "5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf\n" + - "DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX\n" + - "9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e\n" + - "7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj\n" + - "ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB\n" + - "BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF\n" + - "BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD\n" + - "VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy\n" + - "bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G\n" + - "A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob\n" + - "BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh\n" + - "xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd\n" + - "ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP\n" + - "ZFdYf+hthc3m6IcJ\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar PKIoverheid CA Organisatie - G2 - // - - // DigiNotar intermediate, cross-signed by the Dutch government - // - // Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2, - // O=DigiNotar B.V., - // C=NL - // Issuer: CN=Staat der Nederlanden Organisatie CA - G2, - // O=Staat der Nederlanden, - // C=NL - // Serial: 20001983 (01:31:34:bf) - add("diginotar-pkioverheid-organisatie-cross-to-nederlanden-013134BF", - "-----BEGIN CERTIFICATE-----\n" + - "MIIGnDCCBISgAwIBAgIEATE0vzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJO\n" + - "TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMTIwMAYDVQQDDClTdGFh\n" + - "dCBkZXIgTmVkZXJsYW5kZW4gT3JnYW5pc2F0aWUgQ0EgLSBHMjAeFw0xMDA1MTIw\n" + - "ODUxMzhaFw0yMDAzMjMwOTUwMDRaMFoxCzAJBgNVBAYTAk5MMRcwFQYDVQQKDA5E\n" + - "aWdpTm90YXIgQi5WLjEyMDAGA1UEAwwpRGlnaU5vdGFyIFBLSW92ZXJoZWlkIENB\n" + - "IE9yZ2FuaXNhdGllIC0gRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\n" + - "AQCxExkPJ+Zs1FWGS9DsiYpFkXisR71HK+T8RetPtCZzWzfTw3/2497Xo/gtaMUI\n" + - "PkuU1uSHJTZrhLUYdPMoWHMvm2rPvAQe9t7dr/xLqvXbZmIlASWC3vKXWhBu3V2p\n" + - "IrEEqSNzOvhxrR3PhETrR9Gvbch8KKvH8jd6dF9fxQIUiqNa4xtsAeNdjtlo1vQJ\n" + - "GzLckbUs9SDrjANtJkm4k8SFXdjSm69WaswFM8ygQp40VUSca6DUEtArVM23iQ3l\n" + - "9uvo+4UBM096a/GdcjOWDveyhKWlJ8Qn8VFzKXe6Z27+TNy04qGhgS85SY1DOBPO\n" + - "0KVcwoc6AGdlQiPxNlkKHaNRyLyjlCox3+M88p0aPASw77EKMBNzttfzo0wBdRSF\n" + - "eMDXijlYhVD6LubFvs+LP6+PNtQlCS3SD6xyk/K/i9RQs/kVUJuZ9RTZ+4uRozIm\n" + - "JqD43ztggYaDeVsr6xM9KTrBbd29no6H1kquNJcF7hSm9tw4fkrpJFQHPZdoN0Zr\n" + - "DceoIa8TVOQJavFNRgrJXfubT73e+7dUy7g4nKc5+2otwHuNq6WnV+xKkoozxeEg\n" + - "XHPYkJIrgNUPhhhpfDlPhIa890xb89W0yqDC8DciynlSH1PmqvOQsDvd8ij9rOvF\n" + - "BiSgydQvD1j9tZ7sD8+yWdCiBHo4aq5y+73wJWKUCacFCwIDAQABo4IBYTCCAV0w\n" + - "SAYDVR0gBEEwPzA9BgRVHSAAMDUwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cuZGln\n" + - "aW5vdGFyLm5sL2Nwcy9wa2lvdmVyaGVpZDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\n" + - "DwEB/wQEAwIBBjCBhQYDVR0jBH4wfIAUORCLSZJc22ESIM1JnRqO2pxnQLmhXqRc\n" + - "MFoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4x\n" + - "KzApBgNVBAMMIlN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBIC0gRzKCBACY\n" + - "lvQwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5wa2lvdmVyaGVpZC5ubC9E\n" + - "b21PcmdhbmlzYXRpZUxhdGVzdENSTC1HMi5jcmwwHQYDVR0OBBYEFLxdlDvZq3sD\n" + - "JXNhwtst7vyrj2WhMA0GCSqGSIb3DQEBCwUAA4ICAQCP/C1Mt9kt1R+978v0t2gX\n" + - "dZ1O1ffdnPEqJu2forYcA9VTs+wIzzTi48P0tRYvyMO+19NzqwA2+RpKftZj6V5G\n" + - "uqW2jhW3oyrYQx3vXcgfgYWzi/f/PPTZ9EYIP5y8HaDZqEzNJVJOCrEg9x/pQ9lU\n" + - "RoETmsBedGwqmDLq/He7DaWiMZgifnx859qkrey3LhoZcfhIUNpDjyyE3cFAJ+O1\n" + - "8BVOltT4XOOGKUYr1zsH6zh/yIZXl9PvKjPEF1DVZGlrK2tFXl0vF8paTs/D1zk8\n" + - "9TufRrmb5w5Jl53W1eMbD+qPAU6aE5RZCgIHSEsaYKt/T+0L2FUNaG9VnGllFULs\n" + - "wNzdbKzDFs4LHVabpMTE0i7gD+JEJytQaaTcYuiKISlCbMwAOpZ2m+9AwKRed4Qy\n" + - "bCYqOWauXeO5ubIsaB8empADOfCqs6TMSYsYNOk3yXspx4R8b0QVL+xhWQTJRcui\n" + - "1lKifH8pktZKxYtCqNT+6tjHhyMY5J16fXNAUpigrm7jBT8FD+Clxm1N7YM3iJzH\n" + - "89xCmmq21yFJNnfy7xhPxXDZnunetyuL9Lx+KN8NQMmFXK6dxTH/0FwOtah+8Okv\n" + - "uq+IruW10Vilr5xxpykBkINpN4IFuvwJwQhujHg7wzMCgD9EhQgd31VWCK0shS1d\n" + - "sQPhrqp0xaTzTro3mHuCuQ==\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar PKIoverheid CA Overheid en Bedrijven - // - - // DigiNotar intermediate, cross-signed by the Dutch government - // - // Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven, - // O=DigiNotar B.V., - // C=NL - // Issuer: CN=Staat der Nederlanden Overheid CA - // O=Staat der Nederlanden, - // C=NL - // Serial: 20015536 (01:31:69:b0) - add("diginotar-pkioverheid-overheid-enb-cross-to-nederlanden-013169B0", - "-----BEGIN CERTIFICATE-----\n" + - "MIIEiDCCA3CgAwIBAgIEATFpsDANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO\n" + - "TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh\n" + - "dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDcwNzA1MDg0MjA3WhcN\n" + - "MTUwNzI3MDgzOTQ2WjBfMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy\n" + - "IEIuVi4xNzA1BgNVBAMTLkRpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp\n" + - "ZCBlbiBCZWRyaWp2ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc\n" + - "vdKnTmoKuzuiheF/AK2+tDBomAfNoHrElM9x+Yo35FPrV3bMi+Zs/u6HVcg+uwQ5\n" + - "AKeAeKxbT370vbhUuHE7BzFJOZNUfCA7eSuPu2GQfbGs5h+QLp1FAalkLU3DL7nn\n" + - "UNVOKlyrdnY3Rtd57EKZ96LspIlw3Dgrh6aqJOadkiQbvvb91C8ZF3rmMgeUVAVT\n" + - "Q+lsvK9Hy7zL/b07RBKB8WtLu+20z6slTxjSzAL8o0+1QjPLWc0J3NNQ/aB2jKx+\n" + - "ZopC9q0ckvO2+xRG603XLzDgbe5bNr5EdLcgBVeFTegAGaL2DOauocBC36esgl3H\n" + - "aLcY5olLmmv6znn58yynAgMBAAGjggFQMIIBTDBIBgNVHSAEQTA/MD0GBFUdIAAw\n" + - "NTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5kaWdpbm90YXIubmwvY3BzL3BraW92\n" + - "ZXJoZWlkMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIGABgNVHSME\n" + - "eTB3gBQLhtYPd6NosftkCcOIblwEHFfpPaFZpFcwVTELMAkGA1UEBhMCTkwxHjAc\n" + - "BgNVBAoTFVN0YWF0IGRlciBOZWRlcmxhbmRlbjEmMCQGA1UEAxMdU3RhYXQgZGVy\n" + - "IE5lZGVybGFuZGVuIFJvb3QgQ0GCBACYmnkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0\n" + - "cDovL2NybC5wa2lvdmVyaGVpZC5ubC9Eb21PdkxhdGVzdENSTC5jcmwwHQYDVR0O\n" + - "BBYEFEwIyY128ZjHPt881y91DbF2eZfMMA0GCSqGSIb3DQEBBQUAA4IBAQAMlIca\n" + - "v03jheLu19hjeQ5Q38aEW9K72fUxCho1l3TfFPoqDz7toOMI9tVOW6+mriXiRWsi\n" + - "D7dUKH6S3o0UbNEc5W50BJy37zRERd/Jgx0ZH8Apad+J1T/CsFNt5U4X5HNhIxMm\n" + - "cUP9TFnLw98iqiEr2b+VERqKpOKrp11Lbyn1UtHk0hWxi/7wA8+nfemZhzizDXMU\n" + - "5HIs4c71rQZIZPrTKbmi2Lv01QulQERDjqC/zlqlUkxk0xcxYczopIro5Ij76eUv\n" + - "BjMzm5RmZrGrUDqhCYF0U1onuabSJc/Tw6f/ltAv6uAejVLpGBwgCkegllYOQJBR\n" + - "RKwa/fHuhR/3Qlpl\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar PKIoverheid CA Overheid - // - - // DigiNotar intermediate, cross-signed by the Dutch government - // - // Subject: CN=DigiNotar PKIoverheid CA Overheid - // O=DigiNotar B.V., - // C=NL - // Issuer: CN=Staat der Nederlanden Overheid CA - // O=Staat der Nederlanden, - // C=NL - // Serial: 20006006 (01:31:44:76) - add("diginotar-pkioverheid-overheid-cross-to-nederlanden-01314476", - "-----BEGIN CERTIFICATE-----\n" + - "MIIEezCCA2OgAwIBAgIEATFEdjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO\n" + - "TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh\n" + - "dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDQwNjI0MDgxOTMyWhcN\n" + - "MTAwNjIzMDgxNzM2WjBSMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy\n" + - "IEIuVi4xKjAoBgNVBAMTIURpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp\n" + - "ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANSlrubta5tlOjVCi/gb\n" + - "yLCvRqfBjxG8H594VcKHu0WAYc99SPZF9cycj5mw2GyfQvy/WIrGrL4iyNq1gSqR\n" + - "0QA/mTXKZIaPqzpDhdm+VvrKkmjrbZfaQxgMSs3ChtBsjcP9Lc0X1zXZ4Q8nBe3k\n" + - "BTp+zehINfmbjoEgXLxsMR5RQ6GxzKjuC04PQpbJQgTIakglKaqYcDDZbEscWgPV\n" + - "Hgj/2aoHlj6leW/ThHZ+O41jUguEmBLZA3mu3HrCfrHntb5dPt0ihzSx7GtD/SaX\n" + - "5HBLxnP189YuqMk5iRA95CtiSdKauvon/xRKRLNgG6XAz0ctSoY7xLDdiBVU5kJd\n" + - "FScCAwEAAaOCAVAwggFMMEgGA1UdIARBMD8wPQYEVR0gADA1MDMGCCsGAQUFBwIB\n" + - "FidodHRwOi8vd3d3LmRpZ2lub3Rhci5ubC9jcHMvcGtpb3ZlcmhlaWQwDwYDVR0T\n" + - "AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgYAGA1UdIwR5MHeAFAuG1g93o2ix\n" + - "+2QJw4huXAQcV+k9oVmkVzBVMQswCQYDVQQGEwJOTDEeMBwGA1UEChMVU3RhYXQg\n" + - "ZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g\n" + - "Um9vdCBDQYIEAJiaeTA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnBraW92\n" + - "ZXJoZWlkLm5sL0RvbU92TGF0ZXN0Q1JMLmNybDAdBgNVHQ4EFgQUvRaYQh2+kdE9\n" + - "wpcl4CjXWOC1f+IwDQYJKoZIhvcNAQEFBQADggEBAGhQsCWLiaN2EOhPAW+JQP6o\n" + - "XBOrLv5w6joahzBFVn1BiefzmlMKjibqKYxURRvMAsMkh82/MfL8V0w6ugxl81lu\n" + - "i42dcxl9cKSVXKMw4bbBzJ2VQI5HTIABwefeNuy/eX6idVwYdt3ajAH7fUA8Q9Cq\n" + - "vr6H8B+8mwoEqTVTEVlCSsC/EXsokYEUr06PPzRudKjDmijgj7zFaIioZNc8hk7g\n" + - "ufEgrs/tmcNGylrwRHgCXjCRBt2NHlZ08l7A1AGU8HcHlSbG9Un/2q9kVHUkps0D\n" + - "gtUaEK+x6jpAu/R8Ojezu/+ZEcwwjI/KOhG+84+ejFmtyEkrUdsAdEdLf/2dKsw=\n" + - "-----END CERTIFICATE-----"); - - // - // Compromised DigiNotar Services 1024 CA - // - - // DigiNotar intermediate, cross-signed by the Entrust - // - // Subject: EMAILADDRESS=info@diginotar.nl, - // CN=DigiNotar Services 1024 CA - // O=DigiNotar, C=NL - // Issuer: CN=Entrust.net Secure Server Certification Authority, - // OU=(c) 1999 Entrust.net Limited, - // OU=www.entrust.net/CPS incorp. by ref. (limits liab.), - // O=Entrust.net, - // C=US - // Serial: 1184640176 (46:9c:2c:b0) - add("diginotar-services-1024-ca-cross-to-entrust-469C2CB0", - "-----BEGIN CERTIFICATE-----\n" + - "MIIDzTCCAzagAwIBAgIERpwssDANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC\n" + - "VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u\n" + - "ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc\n" + - "KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u\n" + - "ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3\n" + - "MjYxNTU5MDBaFw0xMzA4MjYxNjI5MDBaMGgxCzAJBgNVBAYTAk5MMRIwEAYDVQQK\n" + - "EwlEaWdpTm90YXIxIzAhBgNVBAMTGkRpZ2lOb3RhciBTZXJ2aWNlcyAxMDI0IENB\n" + - "MSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCBnzANBgkqhkiG9w0B\n" + - "AQEFAAOBjQAwgYkCgYEA2ptNXTz50eKLxsYIIMXZHkjsZlhneWIrQWP0iY1o2q+4\n" + - "lDaLGSSkoJPSmQ+yrS01Tc0vauH5mxkrvAQafi09UmTN8T5nD4ku6PJPrqYIoYX+\n" + - "oakJ5sarPkP8r3oDkdqmOaZh7phPGKjTs69mgumfvN1y+QYEvRLZGCTnq5NTi1kC\n" + - "AwEAAaOCASYwggEiMBIGA1UdEwEB/wQIMAYBAf8CAQAwJwYDVR0lBCAwHgYIKwYB\n" + - "BQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDBDARBgNVHSAECjAIMAYGBFUdIAAwMwYI\n" + - "KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l\n" + - "dDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1c3QubmV0L3NlcnZl\n" + - "cjEuY3JsMB0GA1UdDgQWBBT+3JRJDG/vXH/G8RKZTxZJrfuCZTALBgNVHQ8EBAMC\n" + - "AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowGQYJKoZIhvZ9B0EA\n" + - "BAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEFBQADgYEAY3RqN6k/lpxmyFisCcnv\n" + - "9WWUf6MCxDgxvV0jh+zUVrLJsm7kBQb87PX6iHBZ1O7m3bV6oKNgLwIMq94SXa/w\n" + - "NUuqikeRGvWFLELHHe+VQ7NeuJWTpdrFKKqtci0xrZlrbP+MISevrZqRK8fdWMNu\n" + - "B8WfedLHjFW/TMcnXlEWKz4=\n" + - "-----END CERTIFICATE-----"); - - // - // Revoked DigiCert code signing certificates used to sign malware - // - - // Subject: CN=Buster Paper Comercial Ltda, - // O=Buster Paper Comercial Ltda, - // L=S?o Jos? Dos Campos, - // ST=S?o Paulo, - // C=BR - // Issuer: CN=DigiCert Assured ID Code Signing CA-1, - // OU=www.digicert.com, - // O=DigiCert Inc, - // C=US - // Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12 - add("buster-paper-comercial-ltda-72A67312", - "-----BEGIN CERTIFICATE-----\n" + - "MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv\n" + - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + - "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" + - "ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow\n" + - "gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT\n" + - "w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l\n" + - "cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh\n" + - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL\n" + - "HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn\n" + - "2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4\n" + - "tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi\n" + - "mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf\n" + - "Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx\n" + - "BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw\n" + - "HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT\n" + - "BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js\n" + - "My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6\n" + - "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud\n" + - "IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov\n" + - "L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG\n" + - "AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD\n" + - "AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh\n" + - "AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy\n" + - "AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn\n" + - "ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs\n" + - "AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp\n" + - "AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl\n" + - "AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho\n" + - "dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl\n" + - "cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et\n" + - "MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI\n" + - "hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft\n" + - "jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e\n" + - "gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44\n" + - "/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc\n" + - "BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj\n" + - "XMuKLxbh7g==\n" + - "-----END CERTIFICATE-----"); - - // Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, - // O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, - // L=S?o Paulo, - // ST=S?o Paulo, - // C=BR - // Issuer: CN=DigiCert Assured ID Code Signing CA-1, - // OU=www.digicert.com, - // O=DigiCert Inc, - // C=US - // Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f - add("buster-assistencia-tecnica-electronica-ltda-3FD74D2F", - "-----BEGIN CERTIFICATE-----\n" + - "MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv\n" + - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" + - "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" + - "ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow\n" + - "gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT\n" + - "w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF\n" + - "TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB\n" + - "IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA\n" + - "A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR\n" + - "4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V\n" + - "JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW\n" + - "kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb\n" + - "0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj\n" + - "NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV\n" + - "HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30\n" + - "o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD\n" + - "MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1\n" + - "cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" + - "L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB\n" + - "hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z\n" + - "c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A\n" + - "eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA\n" + - "ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA\n" + - "IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA\n" + - "YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA\n" + - "cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA\n" + - "aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA\n" + - "ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC\n" + - "BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0\n" + - "LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp\n" + - "Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA\n" + - "MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ\n" + - "A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE\n" + - "Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA\n" + - "XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9\n" + - "UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL\n" + - "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" + - "-----END CERTIFICATE-----"); - - // - // Revoked code signing certificate w/ a stolen key issued by GoDaddy - // used to sign malware - // - - // Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT, - // O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US - // Issuer: SERIALNUMBER=07969287, - // CN=Go Daddy Secure Certification Authority, - // OU=http://certificates.godaddy.com/repository, - // O="GoDaddy.com, Inc.", - // L=Scottsdale, - // ST=Arizona, - // C=US - // Serial: 2b:73:43:2a:a8:4f:44 - add("clearesult-consulting-inc-2AA84F44", - "-----BEGIN CERTIFICATE-----\n" + - "MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" + - "BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" + - "BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" + - "aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" + - "IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" + - "ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC\n" + - "VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS\n" + - "RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh\n" + - "BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B\n" + - "AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU\n" + - "IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277\n" + - "p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E\n" + - "jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV\n" + - "9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/\n" + - "U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw\n" + - "DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E\n" + - "BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n\n" + - "ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH\n" + - "AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w\n" + - "gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk\n" + - "eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku\n" + - "Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9\n" + - "rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB\n" + - "XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K\n" + - "v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC\n" + - "2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP\n" + - "4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR\n" + - "DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI\n" + - "LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU=\n" + - "-----END CERTIFICATE-----"); - } + private UntrustedCertificates() {} } diff --git a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java index bd59b62811a..b96674e2e1d 100644 --- a/jdk/src/share/classes/sun/security/x509/X509CertImpl.java +++ b/jdk/src/share/classes/sun/security/x509/X509CertImpl.java @@ -37,6 +37,7 @@ import java.security.*; import java.security.cert.*; import java.security.cert.Certificate; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import javax.security.auth.x500.X500Principal; @@ -1913,4 +1914,45 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { } return false; } + + private ConcurrentHashMap fingerprints = + new ConcurrentHashMap<>(2); + + public String getFingerprint(String algorithm) { + return fingerprints.computeIfAbsent(algorithm, + x -> getCertificateFingerPrint(x)); + } + + /** + * Gets the requested finger print of the certificate. The result + * only contains 0-9 and A-F. No small case, no colon. + */ + private String getCertificateFingerPrint(String mdAlg) { + String fingerPrint = ""; + try { + byte[] encCertInfo = getEncoded(); + MessageDigest md = MessageDigest.getInstance(mdAlg); + byte[] digest = md.digest(encCertInfo); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < digest.length; i++) { + byte2hex(digest[i], buf); + } + fingerPrint = buf.toString(); + } catch (NoSuchAlgorithmException | CertificateEncodingException e) { + // ignored + } + return fingerPrint; + } + + /** + * Converts a byte to hex digit and writes to the supplied buffer + */ + private static void byte2hex(byte b, StringBuffer buf) { + char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + int high = ((b & 0xf0) >> 4); + int low = (b & 0x0f); + buf.append(hexChars[high]); + buf.append(hexChars[low]); + } } diff --git a/jdk/src/share/lib/security/BlacklistedCertsConverter.java b/jdk/src/share/lib/security/BlacklistedCertsConverter.java new file mode 100644 index 00000000000..65a88f00a2e --- /dev/null +++ b/jdk/src/share/lib/security/BlacklistedCertsConverter.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Collection; + +/** + * This is the tool to convert blacklisted.certs.pem to blacklisted.certs. + * Every time a new blacklisted certs is added, please append the PEM format + * to the end of blacklisted.certs.pem (with proper comments) and then use + * this tool to generate an updated blacklisted.certs. Make sure to include + * changes to both in a changeset. + */ +public class BlacklistedCertsConverter { + public static void main(String[] args) throws Exception { + if (args.length == 0) { + System.out.println("Usage: java BlacklistedCertsConverter SHA-256" + + " < blacklisted.certs.pem > blacklisted.certs"); + System.exit(1); + } + String mdAlg = args[0]; + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Collection certs + = cf.generateCertificates(System.in); + System.out.println("Algorithm=" + mdAlg); + for (Certificate cert: certs) { + System.out.println( + getCertificateFingerPrint(mdAlg, (X509Certificate)cert)); + } + } + + /** + * Converts a byte to hex digit and writes to the supplied buffer + */ + private static void byte2hex(byte b, StringBuffer buf) { + char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + int high = ((b & 0xf0) >> 4); + int low = (b & 0x0f); + buf.append(hexChars[high]); + buf.append(hexChars[low]); + } + + /** + * Gets the requested finger print of the certificate. + */ + private static String getCertificateFingerPrint(String mdAlg, + X509Certificate cert) { + String fingerPrint = ""; + try { + byte[] encCertInfo = cert.getEncoded(); + MessageDigest md = MessageDigest.getInstance(mdAlg); + byte[] digest = md.digest(encCertInfo); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < digest.length; i++) { + byte2hex(digest[i], buf); + } + fingerPrint = buf.toString(); + } catch (NoSuchAlgorithmException | CertificateEncodingException e) { + // ignored + } + return fingerPrint; + } +} diff --git a/jdk/src/share/lib/security/blacklisted.certs b/jdk/src/share/lib/security/blacklisted.certs new file mode 100644 index 00000000000..cb1e4d59e38 --- /dev/null +++ b/jdk/src/share/lib/security/blacklisted.certs @@ -0,0 +1,19 @@ +Algorithm=SHA-256 +76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645 +4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE +D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F +14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD +D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967 +5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B +9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC +FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B +A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083 +4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176 +8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF +B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD +3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66 +31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133 +450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2 +FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD +DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE +F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7 diff --git a/jdk/src/share/lib/security/blacklisted.certs.pem b/jdk/src/share/lib/security/blacklisted.certs.pem new file mode 100644 index 00000000000..f44a6985352 --- /dev/null +++ b/jdk/src/share/lib/security/blacklisted.certs.pem @@ -0,0 +1,721 @@ +// Subject: CN=Digisign Server ID (Enrich), +// OU=457608-K, +// O=Digicert Sdn. Bhd., +// C=MY +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120001705 (07:27:14:a9) +-----BEGIN CERTIFICATE----- +MIIDyzCCAzSgAwIBAgIEBycUqTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA3MDcxNzE1MTc0OFoXDTEyMDcxNzE1MTY1NFowYzELMAkG +A1UEBhMCTVkxGzAZBgNVBAoTEkRpZ2ljZXJ0IFNkbi4gQmhkLjERMA8GA1UECxMI +NDU3NjA4LUsxJDAiBgNVBAMTG0RpZ2lzaWduIFNlcnZlciBJRCAoRW5yaWNoKTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArahkS02Hx4RZufuQRqCmicDx/tXa +VII3DZkrRSYK6Fawf8qo9I5HhAGCKeOzarWR8/uVhbxyqGToCkCcxfRxrnt7agfq +kBRPjYmvlKuyBtQCanuYH1m5Os1U+iDfsioK6bjdaZDAKdNO0JftZszFGUkGf/pe +LHx7hRsyQt97lSUCAwEAAaOCAXgwggF0MBIGA1UdEwEB/wQIMAYBAf8CAQAwXAYD +VR0gBFUwUzBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy +dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMAcGBWCDSgEBMA4GA1Ud +DwEB/wQEAwIB5jCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVibGljLXRydXN0 +LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYDVR0OBBYEFMYWk04WF+wW +royUdvOGbcV0boR3MA0GCSqGSIb3DQEBBQUAA4GBAHYAe6Z4K2Ydjl42xqSOBfIj +knyTZ9P0wAp9iy3Z6tVvGvPhSilaIoRNUC9LDPL/hcJ7VdREgr5trGeOvLQfkpxR +gBoU9m6rYYgLrRx/90tQUdZlG6ZHcRVesHHzNRTyN71jyNXwk1o0X9g96F33xR7A +5c8fhiSpPAdmzcHSNmNZ +-----END CERTIFICATE----- + +// Subject: CN=Digisign Server ID - (Enrich), +// OU=457608-K, +// O=Digicert Sdn. Bhd., +// C=MY +// Issuer: CN=Entrust.net Certification Authority (2048) +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), +// O=Entrust.net +// Serial: 1184644297 (4c:0e:63:6a) +-----BEGIN CERTIFICATE----- +MIIEzjCCA7agAwIBAgIETA5jajANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0xMDA3MTYxNzIzMzdaFw0xNTA3 +MTYxNzUzMzdaMGUxCzAJBgNVBAYTAk1ZMRswGQYDVQQKExJEaWdpY2VydCBTZG4u +IEJoZC4xETAPBgNVBAsTCDQ1NzYwOC1LMSYwJAYDVQQDEx1EaWdpc2lnbiBTZXJ2 +ZXIgSUQgLSAoRW5yaWNoKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AMWJ5PQNBkCSWccaszXRDkwqM/n4r8qef+65p21g9FTob9Wb8xtjMQRoctE0Foy0 +FyyX3nPF2JAVoBor9cuzSIZE8B2ITM5BQhrv9Qze/kDaOSD3BlU6ap1GwdJvpbLI +Vz4po5zg6YV3ZuiYpyR+vsBZIOVEb7ZX2L7OwmV3WMZhQdF0BMh/SULFcqlyFu6M +3RJdtErU0a9Qt9iqdXZorT5dqjBtYairEFs+E78z4K9EnTgiW+9ML6ZxJhUmyiiM +2fqOjqmiFDXimySItPR/hZ2DTwehthSQNsQ0HI0mYW0Tb3i+6I8nx0uElqOGaAwj +vgvsjJQAqQSKE5D334VsDLECAwEAAaOCATQwggEwMA4GA1UdDwEB/wQEAwIBBjAS +BgNVHRMBAf8ECDAGAQH/AgEAMCcGA1UdJQQgMB4GCCsGAQUFBwMBBggrBgEFBQcD +AgYIKwYBBQUHAwQwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8v +b2NzcC5lbnRydXN0Lm5ldDBEBgNVHSAEPTA7MDkGBWCDSgEBMDAwLgYIKwYBBQUH +AgEWImh0dHA6Ly93d3cuZGlnaWNlcnQuY29tLm15L2Nwcy5odG0wMgYDVR0fBCsw +KTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3JsMBEGA1Ud +DgQKBAhMTswlKAMpgTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDAN +BgkqhkiG9w0BAQUFAAOCAQEAl0zvSjpJrHL8MCBrtClbp8WVBJD5MtXChWreA6E3 ++YkAsFqsVX7bQzX/yQH4Ub7MJsrIaqTEVD4mHucMo82XZ5TdpkLrXM2POXlrM3kh +Bnn6gkQVmczBtznTRmJ8snDrb84gqj4Zt+l0gpy0pUtNYQA35IfS8hQ6ZHy4qXth +4JMi59WfPkfmNnagU9gAAzoPtTP+lsrT0oI6Lt3XSOHkp2nMHOmZSufKcEXXCwcO +mnUb0C+Sb/akB8O9HEumhLZ9qJqp0qcp8QtXaR6XVybsK0Os1EWDBQDp4/BGQAf6 +6rFRc5Mcpd1TETfIKqcVJx20qsx/qjEw/LhFn0gJ7RDixQ== +-----END CERTIFICATE----- + +// Subject: CN=Java Media APIs, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 6a:8b:99:91:37:59:4f:89:53:e2:97:18:9f:19:1e:4e +-----BEGIN CERTIFICATE----- +MIIFdzCCBF+gAwIBAgIQaouZkTdZT4lT4pcYnxkeTjANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDUxMjAw +MDAwMFoXDTEyMDUxMTIzNTk1OVowfTEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt +cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE +CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEYMBYGA1UEAxQPSmF2YSBNZWRpYSBB +UElzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl5blzoKTVE8y4Hpz +q6E15RZz1bF5HnYEyYqgHkZXnAKedmYCoMzm1XK8s+gQWShLEvGEAvs5yqarx9gE +nnC21N28aEZgIJMa2/arKxCUkS4pxdGPYGexL9UzSRkUpoBShCZKEGdmX7gfJE2K +/sd9MFvGV5/yZtWXrADzvm0Kd/9mg1KRv1gfrZIq0TJbupoXPYYqb73AkI9eT2ZD +q9MdwD4E5+oojsDFXt8GU/D00fUhtXpYwuplU7D667WHYdJhIah0ST6JywyqcLXG +XSuFTXOgITT2idSHluZVmx3dqJ72u9kPkO4JdJTMDfaK8zgNLaRkiU8Qcj+qhLYH +ytaqcwIDAQABo4IB6jCCAeYwCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwfwYD +VR0fBHgwdjB0oHKgcIZuaHR0cDovL29uc2l0ZWNybC52ZXJpc2lnbi5jb20vU3Vu +TWljcm9zeXN0ZW1zSW5jQ29ycG9yYXRlT2JqZWN0U2lnbmluZ0phdmFTaWduZWRF +eHRlbnNpb25zQ2xhc3NCL0xhdGVzdENSTC5jcmwwHwYDVR0jBBgwFoAUs0crgn5T +tHPKuLsZt76BTQeVx+0wHQYDVR0OBBYEFKS32mVx0gNWTeS4ProHEaeSpvvIMDsG +CCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL29uc2l0ZS1vY3NwLnZl +cmlzaWduLmNvbTCBtQYDVR0gBIGtMIGqMDkGC2CGSAGG+EUBBxcCMCowKAYIKwYB +BQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwbQYLYIZIAYb3AIN9 +nD8wXjAnBggrBgEFBQcCARYbaHR0cHM6Ly93d3cuc3VuLmNvbS9wa2kvY3BzMDMG +CCsGAQUFBwICMCcaJVZhbGlkYXRlZCBGb3IgU3VuIEJ1c2luZXNzIE9wZXJhdGlv +bnMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQEFBQADggEBAAe6BO4W +3TSNWfezyelJs6kE3HfulT6Bdyz4UUoh9ykXcV8nRwT+kh25I5MdyG2GfkJoADPR +VhC5DYo13UFpIsTNVjq+hGYe2hML93bN7ad9SxCCyjHUo3yMz2qgBbHZI3VA9ZHA +aWM4Tx0saMwbcnVvlbuGh+PXvStfypJqYT6lzcdFfjNVX4FI/QQNGhBswMY51tC8 +GTBCL2qhJon0gSCU4zaawDOf7+XxJWirLamYL1Aal1/h2z2sFrvA/1ftxtU3kZ6I +7De8DyoHeZg7pYGdrj7g+lPhCga/WvEhN152I+aP08YbFcJHYmK05ngl/Ye4c6Bd +cdrdfbw6QzEUIYY= +-----END CERTIFICATE----- + +// Subject: CN=JavaFX 1.0 Runtime, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 55:c0:e6:44:59:59:79:9e:d9:26:f1:b0:4a:1e:f0:27 +-----BEGIN CERTIFICATE----- +MIIFezCCBGOgAwIBAgIQVcDmRFlZeZ7ZJvGwSh7wJzANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA4MTAwOTAw +MDAwMFoXDTExMTAwOTIzNTk1OVowgYAxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl +bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxHzAdBgNV +BAsUFkphdmEgU2lnbmVkIEV4dGVuc2lvbnMxGzAZBgNVBAMUEkphdmFGWCAxLjAg +UnVudGltZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM+WDc6+bu+4 +tmAcS/lBtUc02WOt9QZpVsXg9cG2pu/8bUtmDELa8iiYBVFpIs8DU58HLrGQtCUY +SIAGOVPsOJoN29UKCDWfY9j5JeVhfhMGqk9DwrWhzgsjy4cpZ1pIp+k/fJ8zT8Ul +aYLpow1vg3UNddsmwz02tN7cOrMw9WYIG4CRYnY1OrtJSfe2pYzheC4zyvR+aiVl +nang2OtqikSQsNFOFHsLOJFxngy9LrO8evDSu25VTKI6zlWU6/bMeqtztJPN0VOn +NyUrJZvkxZ207Jg0T693BGSxNC1n+ihztXogql8950M/pEuUbDjylv5FFvlp6DSB +dDT2MkutmyMCAwEAAaOCAeowggHmMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgeA +MH8GA1UdHwR4MHYwdKByoHCGbmh0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29t +L1N1bk1pY3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdKYXZhU2ln +bmVkRXh0ZW5zaW9uc0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaAFLNH +K4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBTjgufVi3XJ3gx1ewsA6Rr7BR4Z +zjA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUtb2Nz +cC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAqMCgG +CCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CGSAGG +9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtpL2Nw +czAzBggrBgEFBQcCAjAnGiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBPcGVy +YXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IBAQAB +YVJTTVe7rzyTO4jc3zajErOT/COkdQTfNo0eIX1QbNynFieJvwY/jRzUZwjktIFR +2p4JtbpHGAtKtjOAOTieQ8xdDOoC1djzpE7/AbMvuvlTavtUKT+F7tPdhfXgWXJV +6Wbt8jryKyk3zZGiEhauIwZUkfjRkEtffEmZWLUd8c8rURJjfC/XHH2oyurscoxc +CjX29c9ynxSiS/VvQp1an0HvErGh69N48wj7cj8mtZ1yHzd2XCzSSR1OfTPfk0Pt +yg51p7yJaFiH21PTZegEL6zyVNOYBTKwwIi2OzpwYalD3uvK6e3OKDrfFCOxu17u +4PveESbrdyrmvLe7IVez +-----END CERTIFICATE----- + +// Subject: CN=JavaFX Runtime, +// OU=Java Signed Extensions, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 47:f4:55:f1:da:4a:5e:f9:e3:f7:a8:03:62:17:c0:ff +-----BEGIN CERTIFICATE----- +MIIFdjCCBF6gAwIBAgIQR/RV8dpKXvnj96gDYhfA/zANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA5MDEyOTAw +MDAwMFoXDTEyMDEyOTIzNTk1OVowfDEdMBsGA1UEChQUU3VuIE1pY3Jvc3lzdGVt +cyBJbmMxITAfBgNVBAsUGENvcnBvcmF0ZSBPYmplY3QgU2lnbmluZzEfMB0GA1UE +CxQWSmF2YSBTaWduZWQgRXh0ZW5zaW9uczEXMBUGA1UEAxQOSmF2YUZYIFJ1bnRp +bWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCIzd0fAk8mI9ONc6RJ +aGieioK2FLdXEwj8zL3vdGDVmBwyR1zwYkaOIFFgF9IW/8qc4iAYA5sGUY+0g8q3 +5DuYAxfTzBB5KdaYvbuq6GGnoHIWmTirXY+1friFp8lyXSvtuEaGB1VHaBoZchEg +k+UgeVDA43dHwcT1Ov3DePczJRUes8T/QHzLX+BxUDG43vjyncCEO/AjqLZxXEz2 +xrNbKLcH3lGMJK7hdbfssUfF5BjC38Hn71HauYlA43b2no+2y0Sjulwzez2YPbDC +0GLR3TnKtA8dqOrnl5t3DniDbfOBNtBE3VOydJO0XW57Ng1HRXD023nm9ECPY2xp +0N/pAgMBAAGjggHqMIIB5jAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDB/BgNV +HR8EeDB2MHSgcqBwhm5odHRwOi8vb25zaXRlY3JsLnZlcmlzaWduLmNvbS9TdW5N +aWNyb3N5c3RlbXNJbmNDb3Jwb3JhdGVPYmplY3RTaWduaW5nSmF2YVNpZ25lZEV4 +dGVuc2lvbnNDbGFzc0IvTGF0ZXN0Q1JMLmNybDAfBgNVHSMEGDAWgBSzRyuCflO0 +c8q4uxm3voFNB5XH7TAdBgNVHQ4EFgQUvOdd0cKPj+Yik/iOBwTdphh5A+gwOwYI +KwYBBQUHAQEELzAtMCsGCCsGAQUFBzABhh9odHRwOi8vb25zaXRlLW9jc3AudmVy +aXNpZ24uY29tMIG1BgNVHSAEga0wgaowOQYLYIZIAYb4RQEHFwIwKjAoBggrBgEF +BQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTBtBgtghkgBhvcAg32c +PzBeMCcGCCsGAQUFBwIBFhtodHRwczovL3d3dy5zdW4uY29tL3BraS9jcHMwMwYI +KwYBBQUHAgIwJxolVmFsaWRhdGVkIEZvciBTdW4gQnVzaW5lc3MgT3BlcmF0aW9u +czATBgNVHSUEDDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQUFAAOCAQEAbGcf2NjL +AI93HG6ny2BbepaZA1a8xa/R6uUc7xV+Qw6MgLwFD4Q4i6LWUztQDvg9l68MM2/i +Y9LEi1KM4lcNbK5+D+t9x98wXBiuojXhVdp5ZmC03EyEBbriopdBsmXVLDSu/Y3+ +zowOO5xwpMK3dbgsSDs2Vt0UosD3FTcRaD3GNfOhXMp+o1grHNiXF9YgkmdQbPPZ +DQ2KBhFPCRJXBGvyKOqno/DTg0sQ3crGH/C4/4t7mnQXWldZotmJUZ0ONc9oD+Q1 +JAaguUKqIwn9yZ093ie+JWHbYNid9IIIPXYgtRxmf9a376WBhqhu56uJftBJ7x9g +eQ7Lot6CSWCiFw== +-----END CERTIFICATE----- + +// Subject: CN=Solaris INTERNAL DEVELOPMENT USE ONLY, +// OU=Solaris Cryptographic Framework, +// OU=Corporate Object Signing, +// O=Sun Microsystems Inc +// Issuer: CN=Object Signing CA, +// OU=Class 2 OnSite Subscriber CA, +// OU=VeriSign Trust Network, +// O=Sun Microsystems Inc +// Serial: 77:29:77:52:6a:19:7b:9a:a6:a2:c7:99:a0:e1:cd:8c +-----BEGIN CERTIFICATE----- +MIIFHjCCBAagAwIBAgIQdyl3UmoZe5qmoseZoOHNjDANBgkqhkiG9w0BAQUFADCB +gzEdMBsGA1UEChMUU3VuIE1pY3Jvc3lzdGVtcyBJbmMxHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxJTAjBgNVBAsTHENsYXNzIDIgT25TaXRlIFN1YnNj +cmliZXIgQ0ExGjAYBgNVBAMTEU9iamVjdCBTaWduaW5nIENBMB4XDTA3MDEwNDAw +MDAwMFoXDTEwMDEwMzIzNTk1OVowgZwxHTAbBgNVBAoUFFN1biBNaWNyb3N5c3Rl +bXMgSW5jMSEwHwYDVQQLFBhDb3Jwb3JhdGUgT2JqZWN0IFNpZ25pbmcxKDAmBgNV +BAsUH1NvbGFyaXMgQ3J5cHRvZ3JhcGhpYyBGcmFtZXdvcmsxLjAsBgNVBAMUJVNv +bGFyaXMgSU5URVJOQUwgREVWRUxPUE1FTlQgVVNFIE9OTFkwgZ8wDQYJKoZIhvcN +AQEBBQADgY0AMIGJAoGBALbNU4hf3mD5ArDI9pjgioAyvV3bjMPRQdCZniIeGJBp +odFlSEH+Mh64W1DsY8coeZ7FvvGJkx9IpTMJW9k8w1oJK9UNqHyAQfaYjQyXi3xQ +LJp62EvYdGfDlwOZejEcR/MbzZG+GOPMMvQj5+xyFDvLXNGfQNTnxw2qnBgCJXjj +AgMBAAGjggH1MIIB8TAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIHgDCBiQYDVR0f +BIGBMH8wfaB7oHmGd2h0dHA6Ly9vbnNpdGVjcmwudmVyaXNpZ24uY29tL1N1bk1p +Y3Jvc3lzdGVtc0luY0NvcnBvcmF0ZU9iamVjdFNpZ25pbmdTb2xhcmlzQ3J5cHRv +Z3JhcGhpY0ZyYW1ld29ya0NsYXNzQi9MYXRlc3RDUkwuY3JsMB8GA1UdIwQYMBaA +FLNHK4J+U7Rzyri7Gbe+gU0HlcftMB0GA1UdDgQWBBRpfiGYkehTnsIzuN2H6AFb +VCZG8jA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAGGH2h0dHA6Ly9vbnNpdGUt +b2NzcC52ZXJpc2lnbi5jb20wgbUGA1UdIASBrTCBqjA5BgtghkgBhvhFAQcXAjAq +MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMG0GC2CG +SAGG9wCDfZw/MF4wJwYIKwYBBQUHAgEWG2h0dHBzOi8vd3d3LnN1bi5jb20vcGtp +L2NwczAzBggrBgEFBQcCAjAnFiVWYWxpZGF0ZWQgRm9yIFN1biBCdXNpbmVzcyBP +cGVyYXRpb25zMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBBQUAA4IB +AQCG5soy3LFHTFbA8/5SzDRhQoJkHUnOP0t3b6nvX6vZYRp649fje7TQOPRm1pFd +CZ17J+tggdZwgzTqY4aYpJ00jZaK6pV37q/vgFC/ia6jDs8Q+ly9cEcadBZ5loYg +cmxp9p57W2MNWx8VA8oFdNtKfF0jUNXbLNtvwGHmgR6YcwLrGN1b6/9Lt9bO3ODl +FO+ZDwkfQz5ClUVrTx2dGBvKRYFqSG5S8JAfsgYhPvcacUQkA7ExyKvfRXLWVrce +ZiPpcElbx+819H2sAPvVvparVeAruZGMAtejHZp9NFoowKen5drJp9VxePS4eM49 +3DepB6lKRrNRw66LNQol4ZBz +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, CN=DigiNotar Cyber CA, +// O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000525 (07:27:10:0D) +-----BEGIN CERTIFICATE----- +MIIFWjCCBMOgAwIBAgIEBycQDTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MTAwNDEwNTQxMVoXDTExMTAwNDEwNTMxMVowYDELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANLOFQotqF6EZ639vu9Gx8i5z3P8 +9DS5+SxD52ATPXrjss87Z2yQrcC5P4RS8DVC3HTcKDu9UrSnrHJFF8bwieu0qiXy +XUte0dmHutZ9fPXOMp8QM8WxSrtekTHC0OlBwpFkfglBO9uLCDdqqspS3rU5HsCI +A6U/i5kTYUO1m4Kz7iBvz6FEouova0CfjytXraFTwoUiaZ2gP1HfC0GRDaXhqKpc +SQhdvd5wQbEPyWNr0380dAIvNFp4dRxoeoFnivPaQPBgY/SSINcDpj2jHmfEhBtB +pcmM5r3qSLYFFgizNxJa92E89zhvLpfgb1Y4VNMota0Ubi5LZLUnZbd1JQm2Bz2V +VgIKgmCyc0XgMyZRdJq51FAc9k1bW1JSE1qmf6cO4ehBVGeYjIfVydNsy9NUkgYJ +NEH3gW8/nsl8dVWw58Gzd+jDxAA1lUBwEEoF3iW7n1mlZLxHYL9g43aLE1Xd4XR6 +uc8kpmp/3mQiRFhogmoQ+T3lPhu5vfwi9GAEibtVbShV+t6OjRshFNc3izR7Tfay +shDPM7F9HGKZSMsrbHaWVb8ZDR0fu2WqG46ZtcYokOWCLXhQIJr9eS8kf/CJKWn0 +fc1zvrPtTsHR7VJej/e4142HrbLZG1ES/1az4a80fVykeIgQnp0DxqWqoiRR90kU +xbHuWUOV36toKDA/AgMBAAGjggGGMIIBgjASBgNVHRMBAf8ECDAGAQH/AgEBMFMG +A1UdIARMMEowSAYJKwYBBAGxPgEAMDswOQYIKwYBBQUHAgEWLWh0dHA6Ly93d3cu +cHVibGljLXRydXN0LmNvbS9DUFMvT21uaVJvb3QuaHRtbDAOBgNVHQ8BAf8EBAMC +AQYwgaAGA1UdIwSBmDCBlYAUpgwdn2H/Bxe1vzhG20Mw1Y6wUgaheaR3MHUxCzAJ +BgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdU +RSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVy +VHJ1c3QgR2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93 +d3cucHVibGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwHQYD +VR0OBBYEFKv5aN/PSjfXe0WMX3LeQETDZbvCMA0GCSqGSIb3DQEBBQUAA4GBAI9o +a6VbB7pEZg4cqFwwezPkCiYE/O+eGjjWLqEf0JlHwnVkJP2eOyh2uSYoYZEMbSz4 +BJ98UAHV42mv7xXSRZskCSpmBU8lgcpdvqrBWSeuM46C9990sFWzjvjnN8huqlZE +9r1TgSOWPbT6MopTZkQloiXGpjwljPDgKAYityZB +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000505 (07:27:0F:F9) +-----BEGIN CERTIFICATE----- +MIIFODCCBKGgAwIBAgIEBycP+TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MDkyMDA5NDUzMloXDTEzMDkyMDA5NDQwNlowPjELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o +XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S +tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 +24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp +naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj +9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu +LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU +Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk +vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 +3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt +eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 +iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB +/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC +ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s +MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV +jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv +bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD +VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 +oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw +MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI +hvcNAQEFBQADgYEACcpiD427SuDUejUrBi3RKGG2rAH7g0m8rtQvLYauGYOl1h0T +4he+/jJ06XoUOMqUXvcpAWlxG5Ea/aO7qh3Ke+IW/aGjDvMMX7LhIDGUK16Sdu36 +6bUjpr8KOwOpb1JgVM1f6bcvfKIn/UGDdbYN+3gm87FF6TKVKho1IZXFonU= +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar Cyber CA, O=DigiNotar, C=NL +// Issuer: CN=GTE CyberTrust Global Root, +// OU=GTE CyberTrust Solutions, Inc., +// O=GTE Corporation, +// C=US +// Serial: 120000515 (07:27:10:03) +-----BEGIN CERTIFICATE----- +MIIFODCCBKGgAwIBAgIEBycQAzANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA2MDkyNzEwNTMzMloXDTExMDkyNzEwNTIzMFowPjELMAkG +A1UEBhMCTkwxEjAQBgNVBAoTCURpZ2lOb3RhcjEbMBkGA1UEAxMSRGlnaU5vdGFy +IEN5YmVyIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0s4VCi2o +XoRnrf2+70bHyLnPc/z0NLn5LEPnYBM9euOyzztnbJCtwLk/hFLwNULcdNwoO71S +tKesckUXxvCJ67SqJfJdS17R2Ye61n189c4ynxAzxbFKu16RMcLQ6UHCkWR+CUE7 +24sIN2qqylLetTkewIgDpT+LmRNhQ7WbgrPuIG/PoUSi6i9rQJ+PK1etoVPChSJp +naA/Ud8LQZENpeGoqlxJCF293nBBsQ/JY2vTfzR0Ai80Wnh1HGh6gWeK89pA8GBj +9JIg1wOmPaMeZ8SEG0GlyYzmvepItgUWCLM3Elr3YTz3OG8ul+BvVjhU0yi1rRRu +LktktSdlt3UlCbYHPZVWAgqCYLJzReAzJlF0mrnUUBz2TVtbUlITWqZ/pw7h6EFU +Z5iMh9XJ02zL01SSBgk0QfeBbz+eyXx1VbDnwbN36MPEADWVQHAQSgXeJbufWaVk +vEdgv2DjdosTVd3hdHq5zySman/eZCJEWGiCahD5PeU+G7m9/CL0YASJu1VtKFX6 +3o6NGyEU1zeLNHtN9rKyEM8zsX0cYplIyytsdpZVvxkNHR+7Zaobjpm1xiiQ5YIt +eFAgmv15LyR/8IkpafR9zXO+s+1OwdHtUl6P97jXjYetstkbURL/VrPhrzR9XKR4 +iBCenQPGpaqiJFH3SRTFse5ZQ5Xfq2goMD8CAwEAAaOCAYYwggGCMBIGA1UdEwEB +/wQIMAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcC +ARYtaHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL0NQUy9PbW5pUm9vdC5odG1s +MA4GA1UdDwEB/wQEAwIBBjCBoAYDVR0jBIGYMIGVgBSmDB2fYf8HF7W/OEbbQzDV +jrBSBqF5pHcwdTELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0dURSBDb3Jwb3JhdGlv +bjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3QgU29sdXRpb25zLCBJbmMuMSMwIQYD +VQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwgUm9vdIICAaUwRQYDVR0fBD4wPDA6 +oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1c3QuY29tL2NnaS1iaW4vQ1JMLzIw +MTgvY2RwLmNybDAdBgNVHQ4EFgQUq/lo389KN9d7RYxfct5ARMNlu8IwDQYJKoZI +hvcNAQEFBQADgYEAWcyGZhizJlRP1jjNupZey+yZG6oMDW4Z11boriMHbYPCndBE +bVh07zmPbZsihOw9w/vm5KbVX5CgxUv4Rhzh/20Faixf3P3bpWg0qgzHVVusNVR/ +P50aKkpdK3hp+QLl56e+lWOddSAINIpmcuyDI1hyuzB+GJEASm9tNU/6rs8= +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Root CA, +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US, +// Serial: 1184644297 (46:9C:3C:C9) +-----BEGIN CERTIFICATE----- +MIIFSDCCBLGgAwIBAgIERpw8yTANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA0 +MjYwNTAwMDBaFw0xMzA4MTQyMDEyMzZaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI +hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt +OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx +hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 +gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D +IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T +BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs +Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 +5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf +DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX +9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e +7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj +ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB +BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF +BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD +VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy +bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G +A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob +BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAI979rBep8tu3TeLunapgsZ0jtXp +GDFjKWSk87dj1jCyYi+q/GyDyZ6ZQZNRP0sF+6twscq05lClWNy3TROMp7QeuoLO +G7Utw3OJaswUtp4YglANMRTHEe3g9ltifUXRH5tSuy7u6yi4LD4WTm5ULP6r/g6l +0CnjXYb0+b1Fmz6U +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Root CA, +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US, +// Serial: 1184640175 (46:9C:2C:AF) +-----BEGIN CERTIFICATE----- +MIIFSDCCBLGgAwIBAgIERpwsrzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 +MjYxNTU3MzlaFw0xMzA4MjYxNjI3MzlaMF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxGjAYBgNVBAMTEURpZ2lOb3RhciBSb290IENBMSAwHgYJKoZI +hvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKywWMEAvdghCAsrmv5uVjAFnxt3kBBBXMMNhxF3joHxynzpjGrt +OHQ1u9rf+bvACTe0lnOBfTMamDn3k2+Vfz25sXWHulFI6ItwPpUExdi2wxbZiLCx +hx1w2oa0DxSLes8Q0XQ2ohJ7d4ZKeeZ73wIRaKVOhq40WJskE3hWIiUeAYtLUXH7 +gsxZlmmIWmhTxbkNAjfLS7xmSpB+KgsFB+0WX1WQddhGyRuD4gi+8SPMmR3WKg+D +IBVYJ4Iu+uIiwkmxuQGBap1tnUB3aHZOISpthECFTnaZfILz87cCWdQmARuO361T +BtGuGN3isjrL14g4jqxbKbkZ05j5GAPPSIKGZgsbaQ/J6ziIeiYaBUyS1yTUlvKs +Ui2jR9VS9j/+zoQGcKaqPqLytlY0GFei5IFt58rwatPHkWsCg0F8Fe9rmmRe49A8 +5bHre12G+8vmd0nNo2Xc97mcuOQLX5PPzDAaMhzOHGOVpfnq4XSLnukrqTB7oBgf +DhgL5Vup09FsHgdnj5FLqYq80maqkwGIspH6MVzVpsFSCAnNCmOi0yKm6KHZOQaX +9W6NApCMFHs/gM0bnLrEWHIjr7ZWn8Z6QjMpBz+CyeYfBQ3NTCg2i9PIPhzGiO9e +7olk6R3r2ol+MqZp0d3MiJ/R0MlmIdwGZ8WUepptYkx9zOBkgLKeR46jAgMBAAGj +ggEmMIIBIjASBgNVHRMBAf8ECDAGAQH/AgEBMCcGA1UdJQQgMB4GCCsGAQUFBwMB +BggrBgEFBQcDAgYIKwYBBQUHAwQwEQYDVR0gBAowCDAGBgRVHSAAMDMGCCsGAQUF +BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYD +VR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9zZXJ2ZXIxLmNy +bDAdBgNVHQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wCwYDVR0PBAQDAgEGMB8G +A1UdIwQYMBaAFPAXYhNVPbP/CgBr+1CEl/PtYtAaMBkGCSqGSIb2fQdBAAQMMAob +BFY3LjEDAgCBMA0GCSqGSIb3DQEBBQUAA4GBAEa6RcDNcEIGUlkDJUY/pWTds4zh +xbVkp3wSmpwPFhx5fxTyF4HD2L60jl3aqjTB7gPpsL2Pk5QZlNsi3t4UkCV70UOd +ueJRN3o/LOtk4+bjXY2lC0qTHbN80VMLqPjmaf9ghSA9hwhskdtMgRsgfd90q5QP +ZFdYf+hthc3m6IcJ +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Organisatie - G2, +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Organisatie CA - G2, +// O=Staat der Nederlanden, +// C=NL +// Serial: 20001983 (01:31:34:bf) +-----BEGIN CERTIFICATE----- +MIIGnDCCBISgAwIBAgIEATE0vzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMTIwMAYDVQQDDClTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3JnYW5pc2F0aWUgQ0EgLSBHMjAeFw0xMDA1MTIw +ODUxMzhaFw0yMDAzMjMwOTUwMDRaMFoxCzAJBgNVBAYTAk5MMRcwFQYDVQQKDA5E +aWdpTm90YXIgQi5WLjEyMDAGA1UEAwwpRGlnaU5vdGFyIFBLSW92ZXJoZWlkIENB +IE9yZ2FuaXNhdGllIC0gRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCxExkPJ+Zs1FWGS9DsiYpFkXisR71HK+T8RetPtCZzWzfTw3/2497Xo/gtaMUI +PkuU1uSHJTZrhLUYdPMoWHMvm2rPvAQe9t7dr/xLqvXbZmIlASWC3vKXWhBu3V2p +IrEEqSNzOvhxrR3PhETrR9Gvbch8KKvH8jd6dF9fxQIUiqNa4xtsAeNdjtlo1vQJ +GzLckbUs9SDrjANtJkm4k8SFXdjSm69WaswFM8ygQp40VUSca6DUEtArVM23iQ3l +9uvo+4UBM096a/GdcjOWDveyhKWlJ8Qn8VFzKXe6Z27+TNy04qGhgS85SY1DOBPO +0KVcwoc6AGdlQiPxNlkKHaNRyLyjlCox3+M88p0aPASw77EKMBNzttfzo0wBdRSF +eMDXijlYhVD6LubFvs+LP6+PNtQlCS3SD6xyk/K/i9RQs/kVUJuZ9RTZ+4uRozIm +JqD43ztggYaDeVsr6xM9KTrBbd29no6H1kquNJcF7hSm9tw4fkrpJFQHPZdoN0Zr +DceoIa8TVOQJavFNRgrJXfubT73e+7dUy7g4nKc5+2otwHuNq6WnV+xKkoozxeEg +XHPYkJIrgNUPhhhpfDlPhIa890xb89W0yqDC8DciynlSH1PmqvOQsDvd8ij9rOvF +BiSgydQvD1j9tZ7sD8+yWdCiBHo4aq5y+73wJWKUCacFCwIDAQABo4IBYTCCAV0w +SAYDVR0gBEEwPzA9BgRVHSAAMDUwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cuZGln +aW5vdGFyLm5sL2Nwcy9wa2lvdmVyaGVpZDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjCBhQYDVR0jBH4wfIAUORCLSZJc22ESIM1JnRqO2pxnQLmhXqRc +MFoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4x +KzApBgNVBAMMIlN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENBIC0gRzKCBACY +lvQwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5wa2lvdmVyaGVpZC5ubC9E +b21PcmdhbmlzYXRpZUxhdGVzdENSTC1HMi5jcmwwHQYDVR0OBBYEFLxdlDvZq3sD +JXNhwtst7vyrj2WhMA0GCSqGSIb3DQEBCwUAA4ICAQCP/C1Mt9kt1R+978v0t2gX +dZ1O1ffdnPEqJu2forYcA9VTs+wIzzTi48P0tRYvyMO+19NzqwA2+RpKftZj6V5G +uqW2jhW3oyrYQx3vXcgfgYWzi/f/PPTZ9EYIP5y8HaDZqEzNJVJOCrEg9x/pQ9lU +RoETmsBedGwqmDLq/He7DaWiMZgifnx859qkrey3LhoZcfhIUNpDjyyE3cFAJ+O1 +8BVOltT4XOOGKUYr1zsH6zh/yIZXl9PvKjPEF1DVZGlrK2tFXl0vF8paTs/D1zk8 +9TufRrmb5w5Jl53W1eMbD+qPAU6aE5RZCgIHSEsaYKt/T+0L2FUNaG9VnGllFULs +wNzdbKzDFs4LHVabpMTE0i7gD+JEJytQaaTcYuiKISlCbMwAOpZ2m+9AwKRed4Qy +bCYqOWauXeO5ubIsaB8empADOfCqs6TMSYsYNOk3yXspx4R8b0QVL+xhWQTJRcui +1lKifH8pktZKxYtCqNT+6tjHhyMY5J16fXNAUpigrm7jBT8FD+Clxm1N7YM3iJzH +89xCmmq21yFJNnfy7xhPxXDZnunetyuL9Lx+KN8NQMmFXK6dxTH/0FwOtah+8Okv +uq+IruW10Vilr5xxpykBkINpN4IFuvwJwQhujHg7wzMCgD9EhQgd31VWCK0shS1d +sQPhrqp0xaTzTro3mHuCuQ== +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Overheid en Bedrijven, +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Overheid CA +// O=Staat der Nederlanden, +// C=NL +// Serial: 20015536 (01:31:69:b0) +-----BEGIN CERTIFICATE----- +MIIEiDCCA3CgAwIBAgIEATFpsDANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDcwNzA1MDg0MjA3WhcN +MTUwNzI3MDgzOTQ2WjBfMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy +IEIuVi4xNzA1BgNVBAMTLkRpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp +ZCBlbiBCZWRyaWp2ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc +vdKnTmoKuzuiheF/AK2+tDBomAfNoHrElM9x+Yo35FPrV3bMi+Zs/u6HVcg+uwQ5 +AKeAeKxbT370vbhUuHE7BzFJOZNUfCA7eSuPu2GQfbGs5h+QLp1FAalkLU3DL7nn +UNVOKlyrdnY3Rtd57EKZ96LspIlw3Dgrh6aqJOadkiQbvvb91C8ZF3rmMgeUVAVT +Q+lsvK9Hy7zL/b07RBKB8WtLu+20z6slTxjSzAL8o0+1QjPLWc0J3NNQ/aB2jKx+ +ZopC9q0ckvO2+xRG603XLzDgbe5bNr5EdLcgBVeFTegAGaL2DOauocBC36esgl3H +aLcY5olLmmv6znn58yynAgMBAAGjggFQMIIBTDBIBgNVHSAEQTA/MD0GBFUdIAAw +NTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5kaWdpbm90YXIubmwvY3BzL3BraW92 +ZXJoZWlkMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIGABgNVHSME +eTB3gBQLhtYPd6NosftkCcOIblwEHFfpPaFZpFcwVTELMAkGA1UEBhMCTkwxHjAc +BgNVBAoTFVN0YWF0IGRlciBOZWRlcmxhbmRlbjEmMCQGA1UEAxMdU3RhYXQgZGVy +IE5lZGVybGFuZGVuIFJvb3QgQ0GCBACYmnkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0 +cDovL2NybC5wa2lvdmVyaGVpZC5ubC9Eb21PdkxhdGVzdENSTC5jcmwwHQYDVR0O +BBYEFEwIyY128ZjHPt881y91DbF2eZfMMA0GCSqGSIb3DQEBBQUAA4IBAQAMlIca +v03jheLu19hjeQ5Q38aEW9K72fUxCho1l3TfFPoqDz7toOMI9tVOW6+mriXiRWsi +D7dUKH6S3o0UbNEc5W50BJy37zRERd/Jgx0ZH8Apad+J1T/CsFNt5U4X5HNhIxMm +cUP9TFnLw98iqiEr2b+VERqKpOKrp11Lbyn1UtHk0hWxi/7wA8+nfemZhzizDXMU +5HIs4c71rQZIZPrTKbmi2Lv01QulQERDjqC/zlqlUkxk0xcxYczopIro5Ij76eUv +BjMzm5RmZrGrUDqhCYF0U1onuabSJc/Tw6f/ltAv6uAejVLpGBwgCkegllYOQJBR +RKwa/fHuhR/3Qlpl +-----END CERTIFICATE----- + +// Subject: CN=DigiNotar PKIoverheid CA Overheid +// O=DigiNotar B.V., +// C=NL +// Issuer: CN=Staat der Nederlanden Overheid CA +// O=Staat der Nederlanden, +// C=NL +// Serial: 20006006 (01:31:44:76) +-----BEGIN CERTIFICATE----- +MIIEezCCA2OgAwIBAgIEATFEdjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDQwNjI0MDgxOTMyWhcN +MTAwNjIzMDgxNzM2WjBSMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy +IEIuVi4xKjAoBgNVBAMTIURpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp +ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANSlrubta5tlOjVCi/gb +yLCvRqfBjxG8H594VcKHu0WAYc99SPZF9cycj5mw2GyfQvy/WIrGrL4iyNq1gSqR +0QA/mTXKZIaPqzpDhdm+VvrKkmjrbZfaQxgMSs3ChtBsjcP9Lc0X1zXZ4Q8nBe3k +BTp+zehINfmbjoEgXLxsMR5RQ6GxzKjuC04PQpbJQgTIakglKaqYcDDZbEscWgPV +Hgj/2aoHlj6leW/ThHZ+O41jUguEmBLZA3mu3HrCfrHntb5dPt0ihzSx7GtD/SaX +5HBLxnP189YuqMk5iRA95CtiSdKauvon/xRKRLNgG6XAz0ctSoY7xLDdiBVU5kJd +FScCAwEAAaOCAVAwggFMMEgGA1UdIARBMD8wPQYEVR0gADA1MDMGCCsGAQUFBwIB +FidodHRwOi8vd3d3LmRpZ2lub3Rhci5ubC9jcHMvcGtpb3ZlcmhlaWQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgYAGA1UdIwR5MHeAFAuG1g93o2ix ++2QJw4huXAQcV+k9oVmkVzBVMQswCQYDVQQGEwJOTDEeMBwGA1UEChMVU3RhYXQg +ZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQYIEAJiaeTA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnBraW92 +ZXJoZWlkLm5sL0RvbU92TGF0ZXN0Q1JMLmNybDAdBgNVHQ4EFgQUvRaYQh2+kdE9 +wpcl4CjXWOC1f+IwDQYJKoZIhvcNAQEFBQADggEBAGhQsCWLiaN2EOhPAW+JQP6o +XBOrLv5w6joahzBFVn1BiefzmlMKjibqKYxURRvMAsMkh82/MfL8V0w6ugxl81lu +i42dcxl9cKSVXKMw4bbBzJ2VQI5HTIABwefeNuy/eX6idVwYdt3ajAH7fUA8Q9Cq +vr6H8B+8mwoEqTVTEVlCSsC/EXsokYEUr06PPzRudKjDmijgj7zFaIioZNc8hk7g +ufEgrs/tmcNGylrwRHgCXjCRBt2NHlZ08l7A1AGU8HcHlSbG9Un/2q9kVHUkps0D +gtUaEK+x6jpAu/R8Ojezu/+ZEcwwjI/KOhG+84+ejFmtyEkrUdsAdEdLf/2dKsw= +-----END CERTIFICATE----- + +// Subject: EMAILADDRESS=info@diginotar.nl, +// CN=DigiNotar Services 1024 CA +// O=DigiNotar, C=NL +// Issuer: CN=Entrust.net Secure Server Certification Authority, +// OU=(c) 1999 Entrust.net Limited, +// OU=www.entrust.net/CPS incorp. by ref. (limits liab.), +// O=Entrust.net, +// C=US +// Serial: 1184640176 (46:9c:2c:b0) +-----BEGIN CERTIFICATE----- +MIIDzTCCAzagAwIBAgIERpwssDANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNzA3 +MjYxNTU5MDBaFw0xMzA4MjYxNjI5MDBaMGgxCzAJBgNVBAYTAk5MMRIwEAYDVQQK +EwlEaWdpTm90YXIxIzAhBgNVBAMTGkRpZ2lOb3RhciBTZXJ2aWNlcyAxMDI0IENB +MSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5ubDCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA2ptNXTz50eKLxsYIIMXZHkjsZlhneWIrQWP0iY1o2q+4 +lDaLGSSkoJPSmQ+yrS01Tc0vauH5mxkrvAQafi09UmTN8T5nD4ku6PJPrqYIoYX+ +oakJ5sarPkP8r3oDkdqmOaZh7phPGKjTs69mgumfvN1y+QYEvRLZGCTnq5NTi1kC +AwEAAaOCASYwggEiMBIGA1UdEwEB/wQIMAYBAf8CAQAwJwYDVR0lBCAwHgYIKwYB +BQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDBDARBgNVHSAECjAIMAYGBFUdIAAwMwYI +KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l +dDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1c3QubmV0L3NlcnZl +cjEuY3JsMB0GA1UdDgQWBBT+3JRJDG/vXH/G8RKZTxZJrfuCZTALBgNVHQ8EBAMC +AQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0BowGQYJKoZIhvZ9B0EA +BAwwChsEVjcuMQMCAIEwDQYJKoZIhvcNAQEFBQADgYEAY3RqN6k/lpxmyFisCcnv +9WWUf6MCxDgxvV0jh+zUVrLJsm7kBQb87PX6iHBZ1O7m3bV6oKNgLwIMq94SXa/w +NUuqikeRGvWFLELHHe+VQ7NeuJWTpdrFKKqtci0xrZlrbP+MISevrZqRK8fdWMNu +B8WfedLHjFW/TMcnXlEWKz4= +-----END CERTIFICATE----- + +// Subject: CN=Buster Paper Comercial Ltda, +// O=Buster Paper Comercial Ltda, +// L=S?o Jos? Dos Campos, +// ST=S?o Paulo, +// C=BR +// Issuer: CN=DigiCert Assured ID Code Signing CA-1, +// OU=www.digicert.com, +// O=DigiCert Inc, +// C=US +// Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12 +-----BEGIN CERTIFICATE----- +MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv +ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow +gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT +w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l +cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL +HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn +2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4 +tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi +mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf +Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx +BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw +HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT +BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js +My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6 +Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud +IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov +L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG +AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD +AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh +AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy +AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn +ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs +AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp +AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl +AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho +dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl +cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et +MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI +hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft +jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e +gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44 +/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc +BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj +XMuKLxbh7g== +-----END CERTIFICATE----- + +// Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, +// O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME, +// L=S?o Paulo, +// ST=S?o Paulo, +// C=BR +// Issuer: CN=DigiCert Assured ID Code Signing CA-1, +// OU=www.digicert.com, +// O=DigiCert Inc, +// C=US +// Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f +-----BEGIN CERTIFICATE----- +MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv +ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow +gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT +w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF +TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB +IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR +4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V +JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW +kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb +0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj +NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV +HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30 +o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD +MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1 +cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t +L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB +hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z +c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A +eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA +ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA +IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA +YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA +cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA +aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA +ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC +BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 +LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp +Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA +MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ +A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE +Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA +XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9 +UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL +zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc +-----END CERTIFICATE----- + +// Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT, +// O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US +// Issuer: SERIALNUMBER=07969287, +// CN=Go Daddy Secure Certification Authority, +// OU=http://certificates.godaddy.com/repository, +// O="GoDaddy.com, Inc.", +// L=Scottsdale, +// ST=Arizona, +// C=US +// Serial: 2b:73:43:2a:a8:4f:44 +-----BEGIN CERTIFICATE----- +MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY +BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm +aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5 +IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky +ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC +VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS +RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh +BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU +IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277 +p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E +jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV +9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/ +U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw +DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E +BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n +ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH +AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w +gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk +eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku +Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9 +rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB +XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K +v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC +2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP +4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR +DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI +LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU= +-----END CERTIFICATE----- diff --git a/jdk/test/lib/security/CheckBlacklistedCerts.java b/jdk/test/lib/security/CheckBlacklistedCerts.java new file mode 100644 index 00000000000..1f162b3e499 --- /dev/null +++ b/jdk/test/lib/security/CheckBlacklistedCerts.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8011402 + * @summary Move blacklisting certificate logic from hard code to data + */ + +import sun.security.util.UntrustedCertificates; + +import java.io.*; +import java.security.KeyStore; +import java.security.cert.*; +import java.util.*; + +public class CheckBlacklistedCerts { + public static void main(String[] args) throws Exception { + + String home = System.getProperty("java.home"); + boolean failed = false; + + // Root CAs should always be trusted + File file = new File(home, "lib/security/cacerts"); + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + try (FileInputStream fis = new FileInputStream(file)) { + ks.load(new FileInputStream(file), null); + } + System.out.println("Check for cacerts: " + ks.size()); + for (String alias: Collections.list(ks.aliases())) { + X509Certificate cert = (X509Certificate)ks.getCertificate(alias); + if (UntrustedCertificates.isUntrusted(cert)) { + System.out.print(alias + " is untrusted"); + failed = true; + } + } + + // All certs in the pem files + Set blacklisted = new HashSet<>(); + + // Hopefully src comes with test, but it might be missing if doing + // a -testonly JPRT job. + File[] blacklists = { + new File(System.getProperty("test.src"), + "../../../src/share/lib/security/blacklisted.certs.pem"), + new File(System.getProperty("test.src"), + "../../../src/closed/share/lib/security/blacklisted.certs.pem") + }; + + // Is this an OPENJDK build? + if (!new File(home, "lib/security/local_policy.jar").exists()) { + blacklists = Arrays.copyOf(blacklists, 1); + } + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + for (File blacklist: blacklists) { + System.out.print("Check for " + blacklist + ": "); + if (!blacklist.exists()) { + System.out.println("does not exist"); + } else { + try (FileInputStream fis = new FileInputStream(blacklist)) { + Collection certs + = cf.generateCertificates(fis); + System.out.println(certs.size()); + for (Certificate c: certs) { + blacklisted.add(c); + X509Certificate cert = ((X509Certificate)c); + if (!UntrustedCertificates.isUntrusted(cert)) { + System.out.println(cert.getSubjectDN() + " is trusted"); + failed = true; + } + } + } + } + } + + // Check the blacklisted.certs file itself + file = new File(home, "lib/security/blacklisted.certs"); + System.out.print("Check for " + file + ": "); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(new FileInputStream(file)))) { + int acount = 0; + int ccount = 0; + while (true) { + String line = reader.readLine(); + if (line == null) break; + if (line.startsWith("Algorithm")) { + acount++; + } else if (!line.isEmpty() && !line.startsWith("#")) { + ccount++; + } + } + System.out.println(acount + " algs, " + ccount + " certs" ); + if (acount != 1) { + System.out.println("There are " + acount + " algorithms"); + failed = true; + } + if (ccount != blacklisted.size() + && !blacklisted.isEmpty()) { + System.out.println("Wrong blacklisted.certs size: " + + ccount + " fingerprints, " + + blacklisted.size() + " certs"); + failed = true; + } + } + + if (failed) { + throw new Exception("Failed"); + } + } +} From 8290ada96c02e38f2d718a9060eeb3a0acdeb3ac Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Wed, 18 Sep 2013 15:13:10 +0100 Subject: [PATCH 047/293] 8015762: TEST_BUG: java/nio/channels/DatagramChannel/AdaptDatagramSocket.java failing intermittently [win] Reviewed-by: chegar, alanb --- .../java/nio/channels/DatagramChannel/AdaptDatagramSocket.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java index 1763ef3a11e..dbeb491acfe 100644 --- a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java +++ b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java @@ -136,7 +136,7 @@ public class AdaptDatagramSocket { echoServer.getPort()); test(address, 0, false, false); test(address, 0, false, true); - test(address, 5000, false, false); + test(address, 15000, false, false); } try (TestServers.UdpDiscardServer discardServer = TestServers.UdpDiscardServer.startNewServer()) { From 100b98aafa33e503f453a52cd41be3cbf4548be4 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Thu, 19 Sep 2013 17:04:45 +0400 Subject: [PATCH 048/293] 8017248: Compiler Diacritics Issue Reviewed-by: naoto --- .../classes/sun/launcher/LauncherHelper.java | 15 ++++++++++++++- jdk/test/tools/launcher/8017248/ClassAÌ.java | 5 +++++ jdk/test/tools/launcher/8017248/test.sh | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 jdk/test/tools/launcher/8017248/ClassAÌ.java create mode 100644 jdk/test/tools/launcher/8017248/test.sh diff --git a/jdk/src/share/classes/sun/launcher/LauncherHelper.java b/jdk/src/share/classes/sun/launcher/LauncherHelper.java index 5a6f40442ed..dc6a10bfac2 100644 --- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java +++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java @@ -51,6 +51,7 @@ import java.nio.charset.Charset; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; +import java.text.Normalizer; import java.util.ResourceBundle; import java.text.MessageFormat; import java.util.ArrayList; @@ -493,7 +494,19 @@ public enum LauncherHelper { try { mainClass = scloader.loadClass(cn); } catch (NoClassDefFoundError | ClassNotFoundException cnfe) { - abort(cnfe, "java.launcher.cls.error1", cn); + if (System.getProperty("os.name", "").contains("OS X") + && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) { + try { + // On Mac OS X since all names with diacretic symbols are given as decomposed it + // is possible that main class name comes incorrectly from the command line + // and we have to re-compose it + mainClass = scloader.loadClass(Normalizer.normalize(cn, Normalizer.Form.NFC)); + } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) { + abort(cnfe, "java.launcher.cls.error1", cn); + } + } else { + abort(cnfe, "java.launcher.cls.error1", cn); + } } // set to mainClass appClass = mainClass; diff --git a/jdk/test/tools/launcher/8017248/ClassAÌ.java b/jdk/test/tools/launcher/8017248/ClassAÌ.java new file mode 100644 index 00000000000..2e264990c74 --- /dev/null +++ b/jdk/test/tools/launcher/8017248/ClassAÌ.java @@ -0,0 +1,5 @@ +public class Classà { + public static void main(String args[]) { + System.out.println("Succes!"); + } +} diff --git a/jdk/test/tools/launcher/8017248/test.sh b/jdk/test/tools/launcher/8017248/test.sh new file mode 100644 index 00000000000..7a96f46c223 --- /dev/null +++ b/jdk/test/tools/launcher/8017248/test.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# @test test.sh +# @bug 8017248 +# @summary Compiler Diacritics Issue +# @run shell test.sh + +OSNAME=`uname -s` +if [ "$OSNAME" == "Darwin" ] +then + rm *.class + ${TESTJAVA}/bin/javac *.java + ${TESTJAVA}/bin/java `echo *.class | cut -d. -f1` +else + echo Test is specific to Mac OS X, skipping. + exit 0 +fi From c7759dc643ac3768e1e05733f82583eed29040d2 Mon Sep 17 00:00:00 2001 From: Peter Levart Date: Thu, 19 Sep 2013 16:14:13 +0200 Subject: [PATCH 049/293] 8011940: java.lang.Class.getAnnotations() always enters synchronized method Reviewed-by: jfranck, chegar, psandoz, shade --- jdk/src/share/classes/java/lang/Class.java | 113 +++++++--- ...tionsInheritanceOrderRedefinitionTest.java | 210 ++++++++++++++++++ 2 files changed, 286 insertions(+), 37 deletions(-) create mode 100644 jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index f884f2efe03..a09aa2c86a4 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -48,6 +48,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Set; import java.util.Map; @@ -2370,11 +2371,14 @@ public final class Class implements java.io.Serializable, private static final long reflectionDataOffset; // offset of Class.annotationType instance field private static final long annotationTypeOffset; + // offset of Class.annotationData instance field + private static final long annotationDataOffset; static { Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches reflectionDataOffset = objectFieldOffset(fields, "reflectionData"); annotationTypeOffset = objectFieldOffset(fields, "annotationType"); + annotationDataOffset = objectFieldOffset(fields, "annotationData"); } private static long objectFieldOffset(Field[] fields, String fieldName) { @@ -2396,6 +2400,12 @@ public final class Class implements java.io.Serializable, AnnotationType newType) { return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType); } + + static boolean casAnnotationData(Class clazz, + AnnotationData oldData, + AnnotationData newData) { + return unsafe.compareAndSwapObject(clazz, annotationDataOffset, oldData, newData); + } } /** @@ -2406,7 +2416,7 @@ public final class Class implements java.io.Serializable, private static boolean useCaches = true; // reflection data that might get invalidated when JVM TI RedefineClasses() is called - static class ReflectionData { + private static class ReflectionData { volatile Field[] declaredFields; volatile Field[] publicFields; volatile Method[] declaredMethods; @@ -3253,8 +3263,7 @@ public final class Class implements java.io.Serializable, public A getAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return (A) annotations.get(annotationClass); + return (A) annotationData().annotations.get(annotationClass); } /** @@ -3275,16 +3284,14 @@ public final class Class implements java.io.Serializable, public A[] getAnnotationsByType(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return AnnotationSupport.getMultipleAnnotations(annotations, annotationClass); + return AnnotationSupport.getMultipleAnnotations(annotationData().annotations, annotationClass); } /** * @since 1.5 */ public Annotation[] getAnnotations() { - initAnnotationsIfNecessary(); - return AnnotationParser.toArray(annotations); + return AnnotationParser.toArray(annotationData().annotations); } /** @@ -3296,8 +3303,7 @@ public final class Class implements java.io.Serializable, public A getDeclaredAnnotation(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return (A) declaredAnnotations.get(annotationClass); + return (A) annotationData().declaredAnnotations.get(annotationClass); } /** @@ -3308,52 +3314,85 @@ public final class Class implements java.io.Serializable, public A[] getDeclaredAnnotationsByType(Class annotationClass) { Objects.requireNonNull(annotationClass); - initAnnotationsIfNecessary(); - return AnnotationSupport.getMultipleAnnotations(declaredAnnotations, annotationClass); + return AnnotationSupport.getMultipleAnnotations(annotationData().declaredAnnotations, annotationClass); } /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { - initAnnotationsIfNecessary(); - return AnnotationParser.toArray(declaredAnnotations); + return AnnotationParser.toArray(annotationData().declaredAnnotations); + } + + // annotation data that might get invalidated when JVM TI RedefineClasses() is called + private static class AnnotationData { + final Map, Annotation> annotations; + final Map, Annotation> declaredAnnotations; + + // Value of classRedefinedCount when we created this AnnotationData instance + final int redefinedCount; + + AnnotationData(Map, Annotation> annotations, + Map, Annotation> declaredAnnotations, + int redefinedCount) { + this.annotations = annotations; + this.declaredAnnotations = declaredAnnotations; + this.redefinedCount = redefinedCount; + } } // Annotations cache - private transient Map, Annotation> annotations; - private transient Map, Annotation> declaredAnnotations; - // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields - private transient int lastAnnotationsRedefinedCount = 0; + @SuppressWarnings("UnusedDeclaration") + private volatile transient AnnotationData annotationData; - // Clears cached values that might possibly have been obsoleted by - // a class redefinition. - private void clearAnnotationCachesOnClassRedefinition() { - if (lastAnnotationsRedefinedCount != classRedefinedCount) { - annotations = declaredAnnotations = null; - lastAnnotationsRedefinedCount = classRedefinedCount; + private AnnotationData annotationData() { + while (true) { // retry loop + AnnotationData annotationData = this.annotationData; + int classRedefinedCount = this.classRedefinedCount; + if (annotationData != null && + annotationData.redefinedCount == classRedefinedCount) { + return annotationData; + } + // null or stale annotationData -> optimistically create new instance + AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount); + // try to install it + if (Atomic.casAnnotationData(this, annotationData, newAnnotationData)) { + // successfully installed new AnnotationData + return newAnnotationData; + } } } - private synchronized void initAnnotationsIfNecessary() { - clearAnnotationCachesOnClassRedefinition(); - if (annotations != null) - return; - declaredAnnotations = AnnotationParser.parseAnnotations( - getRawAnnotations(), getConstantPool(), this); + private AnnotationData createAnnotationData(int classRedefinedCount) { + Map, Annotation> declaredAnnotations = + AnnotationParser.parseAnnotations(getRawAnnotations(), getConstantPool(), this); Class superClass = getSuperclass(); - if (superClass == null) { + Map, Annotation> annotations = null; + if (superClass != null) { + Map, Annotation> superAnnotations = + superClass.annotationData().annotations; + for (Map.Entry, Annotation> e : superAnnotations.entrySet()) { + Class annotationClass = e.getKey(); + if (AnnotationType.getInstance(annotationClass).isInherited()) { + if (annotations == null) { // lazy construction + annotations = new LinkedHashMap<>((Math.max( + declaredAnnotations.size(), + Math.min(12, declaredAnnotations.size() + superAnnotations.size()) + ) * 4 + 2) / 3 + ); + } + annotations.put(annotationClass, e.getValue()); + } + } + } + if (annotations == null) { + // no inherited annotations -> share the Map with declaredAnnotations annotations = declaredAnnotations; } else { - annotations = new HashMap<>(); - superClass.initAnnotationsIfNecessary(); - for (Map.Entry, Annotation> e : superClass.annotations.entrySet()) { - Class annotationClass = e.getKey(); - if (AnnotationType.getInstance(annotationClass).isInherited()) - annotations.put(annotationClass, e.getValue()); - } + // at least one inherited annotation -> declared may override inherited annotations.putAll(declaredAnnotations); } + return new AnnotationData(annotations, declaredAnnotations, classRedefinedCount); } // Annotation types cache their internal (AnnotationType) form diff --git a/jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java b/jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java new file mode 100644 index 00000000000..909154a7c1e --- /dev/null +++ b/jdk/test/java/lang/annotation/AnnotationsInheritanceOrderRedefinitionTest.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8011940 + * @summary Test inheritance, order and class redefinition behaviour of RUNTIME + * class annotations + * @author plevart + */ + +import sun.reflect.annotation.AnnotationParser; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.StringJoiner; + +public class AnnotationsInheritanceOrderRedefinitionTest { + + @Retention(RetentionPolicy.RUNTIME) + @Inherited + @interface Ann1 { + String value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Inherited + @interface Ann2 { + String value(); + } + + @Retention(RetentionPolicy.RUNTIME) + @Inherited + @interface Ann3 { + String value(); + } + + @Ann1("A") + @Ann2("A") + static class A {} + + @Ann3("B") + static class B extends A {} + + @Ann1("C") + @Ann3("C") + static class C extends B {} + + public static void main(String[] args) { + + StringBuilder msgs = new StringBuilder(); + boolean ok = true; + + ok &= annotationsEqual(msgs, A.class, true, + ann(Ann1.class, "A"), ann(Ann2.class, "A")); + ok &= annotationsEqual(msgs, A.class, false, + ann(Ann1.class, "A"), ann(Ann2.class, "A")); + ok &= annotationsEqual(msgs, B.class, true, + ann(Ann3.class, "B")); + ok &= annotationsEqual(msgs, B.class, false, + ann(Ann1.class, "A"), ann(Ann2.class, "A"), ann(Ann3.class, "B")); + ok &= annotationsEqual(msgs, C.class, true, + ann(Ann1.class, "C"), ann(Ann3.class, "C")); + ok &= annotationsEqual(msgs, C.class, false, + ann(Ann1.class, "C"), ann(Ann2.class, "A"), ann(Ann3.class, "C")); + + Annotation[] declaredAnnotatiosA = A.class.getDeclaredAnnotations(); + Annotation[] annotationsA = A.class.getAnnotations(); + Annotation[] declaredAnnotatiosB = B.class.getDeclaredAnnotations(); + Annotation[] annotationsB = B.class.getAnnotations(); + Annotation[] declaredAnnotatiosC = C.class.getDeclaredAnnotations(); + Annotation[] annotationsC = C.class.getAnnotations(); + + incrementClassRedefinedCount(A.class); + incrementClassRedefinedCount(B.class); + incrementClassRedefinedCount(C.class); + + ok &= annotationsEqualButNotSame(msgs, A.class, true, declaredAnnotatiosA); + ok &= annotationsEqualButNotSame(msgs, A.class, false, annotationsA); + ok &= annotationsEqualButNotSame(msgs, B.class, true, declaredAnnotatiosB); + ok &= annotationsEqualButNotSame(msgs, B.class, false, annotationsB); + ok &= annotationsEqualButNotSame(msgs, C.class, true, declaredAnnotatiosC); + ok &= annotationsEqualButNotSame(msgs, C.class, false, annotationsC); + + if (!ok) { + throw new RuntimeException("test failure\n" + msgs); + } + } + + // utility methods + + private static boolean annotationsEqualButNotSame(StringBuilder msgs, + Class declaringClass, boolean declaredOnly, Annotation[] oldAnns) { + if (!annotationsEqual(msgs, declaringClass, declaredOnly, oldAnns)) { + return false; + } + Annotation[] anns = declaredOnly + ? declaringClass.getDeclaredAnnotations() + : declaringClass.getAnnotations(); + List sameAnns = new ArrayList<>(); + for (int i = 0; i < anns.length; i++) { + if (anns[i] == oldAnns[i]) { + sameAnns.add(anns[i]); + } + } + if (!sameAnns.isEmpty()) { + msgs.append(declaredOnly ? "declared " : "").append("annotations for ") + .append(declaringClass.getSimpleName()) + .append(" not re-parsed after class redefinition: ") + .append(toSimpleString(sameAnns)).append("\n"); + return false; + } else { + return true; + } + } + + private static boolean annotationsEqual(StringBuilder msgs, + Class declaringClass, boolean declaredOnly, Annotation... expectedAnns) { + Annotation[] anns = declaredOnly + ? declaringClass.getDeclaredAnnotations() + : declaringClass.getAnnotations(); + if (!Arrays.equals(anns, expectedAnns)) { + msgs.append(declaredOnly ? "declared " : "").append("annotations for ") + .append(declaringClass.getSimpleName()).append(" are: ") + .append(toSimpleString(anns)).append(", expected: ") + .append(toSimpleString(expectedAnns)).append("\n"); + return false; + } else { + return true; + } + } + + private static Annotation ann(Class annotationType, + Object value) { + return AnnotationParser.annotationForMap(annotationType, + Collections.singletonMap("value", value)); + } + + private static String toSimpleString(List anns) { + return toSimpleString(anns.toArray(new Annotation[anns.size()])); + } + + private static String toSimpleString(Annotation[] anns) { + StringJoiner joiner = new StringJoiner(", "); + for (Annotation ann : anns) { + joiner.add(toSimpleString(ann)); + } + return joiner.toString(); + } + + private static String toSimpleString(Annotation ann) { + Class annotationType = ann.annotationType(); + Object value; + try { + value = annotationType.getDeclaredMethod("value").invoke(ann); + } catch (IllegalAccessException | InvocationTargetException + | NoSuchMethodException e) { + throw new RuntimeException(e); + } + return "@" + annotationType.getSimpleName() + "(" + value + ")"; + } + + private static final Field classRedefinedCountField; + + static { + try { + classRedefinedCountField = Class.class.getDeclaredField("classRedefinedCount"); + classRedefinedCountField.setAccessible(true); + } catch (NoSuchFieldException e) { + throw new Error(e); + } + } + + private static void incrementClassRedefinedCount(Class clazz) { + try { + classRedefinedCountField.set(clazz, + ((Integer) classRedefinedCountField.get(clazz)) + 1); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} From 6ea068de3a75428cfdf9b19b5f59b4537fd9c0a5 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Thu, 19 Sep 2013 10:06:30 -0700 Subject: [PATCH 050/293] 8023113: tools/jar/ChangeDir.java fails if /tmp/a exists Updated the test case Reviewed-by: alanb --- jdk/test/tools/jar/ChangeDir.java | 65 ++++++++++++++++--------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/jdk/test/tools/jar/ChangeDir.java b/jdk/test/tools/jar/ChangeDir.java index f811618af46..6f65fa8542e 100644 --- a/jdk/test/tools/jar/ChangeDir.java +++ b/jdk/test/tools/jar/ChangeDir.java @@ -23,13 +23,15 @@ /** * @test - * @bug 4806786 + * @bug 4806786 8023113 * @summary jar -C doesn't ignore multiple // in path */ import java.io.*; +import java.nio.file.*; import java.util.*; import java.util.jar.*; +import java.util.stream.Stream; import sun.tools.jar.Main; public class ChangeDir { @@ -37,13 +39,16 @@ public class ChangeDir { private final static String fileName = "hello.txt"; /** Remove dirs & files needed for test. */ - private static void cleanup(File dir) throws Throwable { - if (dir != null && dir.exists()) { - for (File ff : dir.listFiles()) { - check(ff.delete()); + private static void cleanup(Path dir) { + try { + if (Files.isDirectory(dir)) { + try (Stream s = Files.list(dir)) { + s.forEach( p -> cleanup(p)); + } } - check(dir.delete()); - check(new File(jarName).delete()); + Files.delete(dir); + } catch (IOException x) { + fail(x.toString()); } } @@ -62,19 +67,16 @@ public class ChangeDir { } static void doTest(String sep) throws Throwable { - File testDir = null; - JarFile jf = null; + Path topDir = Files.createTempDirectory("delete"); try { + Files.deleteIfExists(Paths.get(jarName)); + // Create a subdirectory "a/b" - File f = File.createTempFile("delete", ".me"); - String dirName = f.getParent(); - testDir = new File(dirName + sep + "a" + sep + "b"); - cleanup(testDir); - check(testDir.mkdirs()); + Path testDir = Files.createDirectories(topDir.resolve("a").resolve("b")); // Create file in that subdirectory - File testFile = new File(testDir, fileName); - check(testFile.createNewFile()); + Path testFile = testDir.resolve(fileName); + Files.createFile(testFile); // Create a jar file from that subdirectory, but with a // in the // path name. @@ -82,33 +84,32 @@ public class ChangeDir { argList.add("cf"); argList.add(jarName); argList.add("-C"); - argList.add(dirName + sep + "a" + sep + sep + "b"); // Note double 'sep' is intentional + argList.add(topDir.toString() + sep + "a" + sep + sep + "b"); // Note double 'sep' is intentional argList.add(fileName); - String jarArgs[] = new String[argList.size()]; - jarArgs = argList.toArray(jarArgs); Main jarTool = new Main(System.out, System.err, "jar"); - if (!jarTool.run(jarArgs)) { + if (!jarTool.run(argList.toArray(new String[argList.size()]))) { fail("Could not create jar file."); } // Check that the entry for hello.txt does *not* have a pathname. - jf = new JarFile(jarName); - for (Enumeration i = jf.entries(); i.hasMoreElements();) { - JarEntry je = i.nextElement(); - String name = je.getName(); - if (name.indexOf(fileName) != -1) { - if (name.indexOf(fileName) != 0) { - fail(String.format( - "Expected '%s' but got '%s'%n", fileName, name)); + try (JarFile jf = new JarFile(jarName)) { + for (Enumeration i = jf.entries(); i.hasMoreElements();) { + JarEntry je = i.nextElement(); + String name = je.getName(); + if (name.indexOf(fileName) != -1) { + if (name.indexOf(fileName) != 0) { + fail(String.format( + "Expected '%s' but got '%s'%n", fileName, name)); + } else { + pass(); + } } } } } finally { - if (jf != null) { - jf.close(); - } - cleanup(testDir); + cleanup(topDir); + Files.deleteIfExists(Paths.get(jarName)); } } From 3a559a7ea0774035bf3545735e49264f755da292 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Wed, 18 Sep 2013 10:49:34 -0700 Subject: [PATCH 051/293] 8025002: "".codePoints().sorted().iterator().hasNext() causes NegativeArraySizeException Reviewed-by: henryjen, alanb --- jdk/src/share/classes/java/lang/CharSequence.java | 2 +- jdk/test/java/lang/CharSequence/DefaultTest.java | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/lang/CharSequence.java b/jdk/src/share/classes/java/lang/CharSequence.java index ac80b22f066..a74a9d0d424 100644 --- a/jdk/src/share/classes/java/lang/CharSequence.java +++ b/jdk/src/share/classes/java/lang/CharSequence.java @@ -228,7 +228,7 @@ public interface CharSequence { Spliterators.spliteratorUnknownSize( new CodePointIterator(), Spliterator.ORDERED), - Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED, + Spliterator.ORDERED, false); } } diff --git a/jdk/test/java/lang/CharSequence/DefaultTest.java b/jdk/test/java/lang/CharSequence/DefaultTest.java index dd51ce64122..856b980ff00 100644 --- a/jdk/test/java/lang/CharSequence/DefaultTest.java +++ b/jdk/test/java/lang/CharSequence/DefaultTest.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; import java.util.PrimitiveIterator; +import java.util.Spliterator; import java.util.stream.Collectors; import org.testng.annotations.Test; @@ -34,7 +35,7 @@ import static org.testng.Assert.*; /* * @test * @summary Unit test for CharSequence default methods - * @bug 8012665 + * @bug 8012665 8025002 * @run testng DefaultTest */ @@ -53,6 +54,12 @@ public class DefaultTest { assertEquals(list, Arrays.asList((int) 'a', (int) 'b', (int) 'c')); } + public void testCodePointsCharacteristics() { + Spliterator.OfInt s = "".codePoints().spliterator(); + assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED)); + assertTrue(s.hasCharacteristics(Spliterator.ORDERED)); + } + @Test(expectedExceptions = NoSuchElementException.class) public void testEmptyCodePoints() { PrimitiveIterator.OfInt s = "".codePoints().iterator(); From 0f59d418d8115e4106c8d81071995d5f4f4352d0 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Thu, 19 Sep 2013 20:41:54 -0700 Subject: [PATCH 052/293] 8024405: Spliterators.spliterator should support CONCURRENT characteristic Reviewed-by: martin --- .../share/classes/java/util/Spliterator.java | 2 +- .../share/classes/java/util/Spliterators.java | 78 +++++----- .../SpliteratorCharacteristics.java | 142 +++++++++++++++++- ...SpliteratorTraversingAndSplittingTest.java | 11 +- 4 files changed, 194 insertions(+), 39 deletions(-) diff --git a/jdk/src/share/classes/java/util/Spliterator.java b/jdk/src/share/classes/java/util/Spliterator.java index 542aec76cde..08d8f1522ca 100644 --- a/jdk/src/share/classes/java/util/Spliterator.java +++ b/jdk/src/share/classes/java/util/Spliterator.java @@ -539,7 +539,7 @@ public interface Spliterator { * Spliterator is expected to have a documented policy concerning the impact * of modifications during traversal. * - *

A top-level Spliterator should not report {@code CONCURRENT} and + *

A top-level Spliterator should not report both {@code CONCURRENT} and * {@code SIZED}, since the finite size, if known, may change if the source * is concurrently modified during traversal. Such a Spliterator is * inconsistent and no guarantees can be made about any computation using diff --git a/jdk/src/share/classes/java/util/Spliterators.java b/jdk/src/share/classes/java/util/Spliterators.java index afa2fd379cc..3f97a833a68 100644 --- a/jdk/src/share/classes/java/util/Spliterators.java +++ b/jdk/src/share/classes/java/util/Spliterators.java @@ -409,16 +409,16 @@ public final class Spliterators { * * @param Type of elements * @param c The collection - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given collection is {@code null} */ public static Spliterator spliterator(Collection c, - int additionalCharacteristics) { + int characteristics) { return new IteratorSpliterator<>(Objects.requireNonNull(c), - additionalCharacteristics); + characteristics); } /** @@ -439,17 +439,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize} - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator spliterator(Iterator iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new IteratorSpliterator<>(Objects.requireNonNull(iterator), size, - additionalCharacteristics); + characteristics); } /** @@ -467,7 +467,7 @@ public final class Spliterators { * * @param Type of elements * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -496,17 +496,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize}. - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator.OfInt spliterator(PrimitiveIterator.OfInt iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new IntIteratorSpliterator(Objects.requireNonNull(iterator), - size, additionalCharacteristics); + size, characteristics); } /** @@ -524,7 +524,7 @@ public final class Spliterators { * operated on after the spliterator is returned. * * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -553,17 +553,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize}. - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator.OfLong spliterator(PrimitiveIterator.OfLong iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new LongIteratorSpliterator(Objects.requireNonNull(iterator), - size, additionalCharacteristics); + size, characteristics); } /** @@ -581,7 +581,7 @@ public final class Spliterators { * operated on after the spliterator is returned. * * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -610,17 +610,17 @@ public final class Spliterators { * @param iterator The iterator for the source * @param size The number of elements in the source, to be reported as * initial {@code estimateSize} - * @param additionalCharacteristics Additional spliterator characteristics - * of this spliterator's source or elements beyond {@code SIZED} and - * {@code SUBSIZED} which are are always reported + * @param characteristics Characteristics of this spliterator's source or + * elements. The characteristics {@code SIZED} and {@code SUBSIZED} + * are additionally reported unless {@code CONCURRENT} is supplied. * @return A spliterator from an iterator * @throws NullPointerException if the given iterator is {@code null} */ public static Spliterator.OfDouble spliterator(PrimitiveIterator.OfDouble iterator, long size, - int additionalCharacteristics) { + int characteristics) { return new DoubleIteratorSpliterator(Objects.requireNonNull(iterator), - size, additionalCharacteristics); + size, characteristics); } /** @@ -638,7 +638,7 @@ public final class Spliterators { * operated on after the spliterator is returned. * * @param iterator The iterator for the source - * @param characteristics Properties of this spliterator's source + * @param characteristics Characteristics of this spliterator's source * or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are * ignored and are not reported.) * @return A spliterator from an iterator @@ -1710,7 +1710,9 @@ public final class Spliterators { public IteratorSpliterator(Collection collection, int characteristics) { this.collection = collection; this.it = null; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -1727,7 +1729,9 @@ public final class Spliterators { this.collection = null; this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -1857,7 +1861,9 @@ public final class Spliterators { public IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics) { this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -1949,7 +1955,9 @@ public final class Spliterators { public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics) { this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** @@ -2041,7 +2049,9 @@ public final class Spliterators { public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics) { this.it = iterator; this.est = size; - this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED; + this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0 + ? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED + : characteristics; } /** diff --git a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java index 3c74ce29dc1..37fbcc769d0 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java +++ b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8020156 8020009 8022326 8012913 + * @bug 8020156 8020009 8022326 8012913 8024405 * @run testng SpliteratorCharacteristics */ @@ -36,21 +36,150 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; +import java.util.PrimitiveIterator; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.Spliterator; +import java.util.Spliterators; import java.util.TreeMap; import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; +import java.util.function.Supplier; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; import static org.testng.Assert.*; @Test public class SpliteratorCharacteristics { + public void testSpliteratorFromCollection() { + List l = Arrays.asList(1, 2, 3, 4); + + { + Spliterator s = Spliterators.spliterator(l, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(l, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(l.iterator( ), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(l.iterator( ), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(l.iterator( ), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + l.iterator(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + public void testSpliteratorOfIntFromIterator() { + Supplier si = () -> IntStream.of(1, 2, 3, 4).iterator(); + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(si.get(), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + public void testSpliteratorOfLongFromIterator() { + Supplier si = () -> LongStream.of(1, 2, 3, 4).iterator(); + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(si.get(), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + public void testSpliteratorOfDoubleFromIterator() { + Supplier si = () -> DoubleStream.of(1, 2, 3, 4).iterator(); + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, 0); + assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + assertCharacteristics(s, Spliterator.CONCURRENT); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize(si.get(), 0); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + + { + Spliterator s = Spliterators.spliteratorUnknownSize( + si.get(), Spliterator.SIZED | Spliterator.SUBSIZED); + assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED); + } + } + + // + public void testHashMap() { assertMapCharacteristics(new HashMap<>(), Spliterator.SIZED | Spliterator.DISTINCT); @@ -199,10 +328,19 @@ public class SpliteratorCharacteristics { } void assertCharacteristics(Collection c, int expectedCharacteristics) { - assertTrue(c.spliterator().hasCharacteristics(expectedCharacteristics), + assertCharacteristics(c.spliterator(), expectedCharacteristics); + } + + void assertCharacteristics(Spliterator s, int expectedCharacteristics) { + assertTrue(s.hasCharacteristics(expectedCharacteristics), "Spliterator characteristics"); } + void assertHasNotCharacteristics(Spliterator s, int expectedCharacteristics) { + assertFalse(s.hasCharacteristics(expectedCharacteristics), + "Spliterator characteristics"); + } + void assertNullComparator(Collection c) { assertNull(c.spliterator().getComparator(), "Comparator of Spliterator of Collection"); diff --git a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java index a84cbbeaebe..69c7cf57436 100644 --- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java +++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java @@ -1159,7 +1159,7 @@ public class SpliteratorTraversingAndSplittingTest { List dest = new ArrayList<>(); spliterator = supplier.get(); - assertSpliterator(spliterator); + assertRootSpliterator(spliterator); // verify splitting with forEach visit(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false); @@ -1234,7 +1234,7 @@ public class SpliteratorTraversingAndSplittingTest { UnaryOperator> boxingAdapter) { Spliterator s = supplier.get(); boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED); - assertSpliterator(s); + assertRootSpliterator(s); List splits = new ArrayList<>(); Consumer c = boxingAdapter.apply(splits::add); @@ -1326,6 +1326,13 @@ public class SpliteratorTraversingAndSplittingTest { } } + private static void assertRootSpliterator(Spliterator s) { + assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.CONCURRENT), + "Root spliterator should not be SIZED and CONCURRENT"); + + assertSpliterator(s); + } + private static void assertSpliterator(Spliterator s, int rootCharacteristics) { if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) { assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED), From 6de8695342b7af00f6079f6560e3e871da5b2e42 Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 20 Sep 2013 10:14:35 +0200 Subject: [PATCH 053/293] 8024985: com/sun/jdi/StepTest.java failed since jdk8b107 Reviewed-by: dcubed --- jdk/test/com/sun/jdi/ExceptionEvents.java | 4 ++++ jdk/test/com/sun/jdi/FilterNoMatch.java | 10 +++++++--- jdk/test/com/sun/jdi/JDIScaffold.java | 4 ++++ jdk/test/com/sun/jdi/PopAndStepTest.java | 4 ++++ jdk/test/com/sun/jdi/RepStep.java | 4 ++++ jdk/test/com/sun/jdi/TestScaffold.java | 7 ++++++- 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/jdk/test/com/sun/jdi/ExceptionEvents.java b/jdk/test/com/sun/jdi/ExceptionEvents.java index 88633b6fcde..42a532e4c44 100644 --- a/jdk/test/com/sun/jdi/ExceptionEvents.java +++ b/jdk/test/com/sun/jdi/ExceptionEvents.java @@ -417,8 +417,12 @@ public class ExceptionEvents extends TestScaffold { request = eventRequestManager().createExceptionRequest(exceptionClass, caught, uncaught); request.addClassExclusionFilter("java.*"); + request.addClassExclusionFilter("javax.*"); request.addClassExclusionFilter("sun.*"); request.addClassExclusionFilter("com.sun.*"); + request.addClassExclusionFilter("com.oracle.*"); + request.addClassExclusionFilter("oracle.*"); + request.addClassExclusionFilter("jdk.internal.*"); request.setSuspendPolicy(suspendPolicy); request.enable(); diff --git a/jdk/test/com/sun/jdi/FilterNoMatch.java b/jdk/test/com/sun/jdi/FilterNoMatch.java index 1feb8992f3a..3a8ecd2abdb 100644 --- a/jdk/test/com/sun/jdi/FilterNoMatch.java +++ b/jdk/test/com/sun/jdi/FilterNoMatch.java @@ -121,9 +121,13 @@ public class FilterNoMatch extends JDIScaffold { // We have to filter out all these so that they don't cause the // listener to be called. - request1.addClassExclusionFilter( "java.*"); - request1.addClassExclusionFilter( "com.*"); - request1.addClassExclusionFilter( "sun.*"); + request1.addClassExclusionFilter("java.*"); + request1.addClassExclusionFilter("javax.*"); + request1.addClassExclusionFilter("sun.*"); + request1.addClassExclusionFilter("com.sun.*"); + request1.addClassExclusionFilter("com.oracle.*"); + request1.addClassExclusionFilter("oracle.*"); + request1.addClassExclusionFilter("jdk.internal.*"); // We want our listener to be called if a pattern does not match. // So, here we want patterns that do not match HelloWorld. diff --git a/jdk/test/com/sun/jdi/JDIScaffold.java b/jdk/test/com/sun/jdi/JDIScaffold.java index e0a95dfbe09..0c60c0767dd 100644 --- a/jdk/test/com/sun/jdi/JDIScaffold.java +++ b/jdk/test/com/sun/jdi/JDIScaffold.java @@ -450,8 +450,12 @@ abstract public class JDIScaffold { requestManager.createStepRequest(thread, gran, depth); sr.addClassExclusionFilter("java.*"); + sr.addClassExclusionFilter("javax.*"); sr.addClassExclusionFilter("sun.*"); sr.addClassExclusionFilter("com.sun.*"); + sr.addClassExclusionFilter("com.oracle.*"); + sr.addClassExclusionFilter("oracle.*"); + sr.addClassExclusionFilter("jdk.internal.*"); sr.addCountFilter(1); sr.enable(); StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr); diff --git a/jdk/test/com/sun/jdi/PopAndStepTest.java b/jdk/test/com/sun/jdi/PopAndStepTest.java index c5487fe787d..76dc0f5038c 100644 --- a/jdk/test/com/sun/jdi/PopAndStepTest.java +++ b/jdk/test/com/sun/jdi/PopAndStepTest.java @@ -130,8 +130,12 @@ public class PopAndStepTest extends TestScaffold { StepRequest srInto = erm.createStepRequest(mainThread, StepRequest.STEP_LINE, StepRequest.STEP_INTO); srInto.addClassExclusionFilter("java.*"); + srInto.addClassExclusionFilter("javax.*"); srInto.addClassExclusionFilter("sun.*"); srInto.addClassExclusionFilter("com.sun.*"); + srInto.addClassExclusionFilter("com.oracle.*"); + srInto.addClassExclusionFilter("oracle.*"); + srInto.addClassExclusionFilter("jdk.internal.*"); srInto.addCountFilter(1); srInto.enable(); // This fails mainThread.popFrames(frameFor("A")); diff --git a/jdk/test/com/sun/jdi/RepStep.java b/jdk/test/com/sun/jdi/RepStep.java index 665dfb79845..80ce449b304 100644 --- a/jdk/test/com/sun/jdi/RepStep.java +++ b/jdk/test/com/sun/jdi/RepStep.java @@ -75,8 +75,12 @@ public class RepStep { DEPTH); sr.addClassExclusionFilter("java.*"); + sr.addClassExclusionFilter("javax.*"); sr.addClassExclusionFilter("sun.*"); sr.addClassExclusionFilter("com.sun.*"); + sr.addClassExclusionFilter("com.oracle.*"); + sr.addClassExclusionFilter("oracle.*"); + sr.addClassExclusionFilter("jdk.internal.*"); sr.enable(); } diff --git a/jdk/test/com/sun/jdi/TestScaffold.java b/jdk/test/com/sun/jdi/TestScaffold.java index 61f8e053eaf..5dc5640f91f 100644 --- a/jdk/test/com/sun/jdi/TestScaffold.java +++ b/jdk/test/com/sun/jdi/TestScaffold.java @@ -746,8 +746,12 @@ abstract public class TestScaffold extends TargetAdapter { requestManager.createStepRequest(thread, gran, depth); sr.addClassExclusionFilter("java.*"); + sr.addClassExclusionFilter("javax.*"); sr.addClassExclusionFilter("sun.*"); sr.addClassExclusionFilter("com.sun.*"); + sr.addClassExclusionFilter("com.oracle.*"); + sr.addClassExclusionFilter("oracle.*"); + sr.addClassExclusionFilter("jdk.internal.*"); sr.addCountFilter(1); sr.enable(); StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr); @@ -829,7 +833,8 @@ abstract public class TestScaffold extends TargetAdapter { Method method = findMethod(rt, methodName, methodSignature); if (method == null) { - throw new IllegalArgumentException("Bad method name/signature"); + throw new IllegalArgumentException("Bad method name/signature: " + + clsName + "." + methodName + ":" + methodSignature); } return resumeTo(method.location()); From a066da5d4d48d6f2eac8fe31f920a7a7f45fb1ce Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 20 Sep 2013 10:15:02 +0200 Subject: [PATCH 054/293] 8024416: TESTBUG: com/sun/jdi/MethodEntryExitEvents.java: method entry count mismatch Reviewed-by: dcubed --- jdk/test/com/sun/jdi/MethodEntryExitEvents.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/com/sun/jdi/MethodEntryExitEvents.java b/jdk/test/com/sun/jdi/MethodEntryExitEvents.java index a1c67cbfdd4..a14a63e3491 100644 --- a/jdk/test/com/sun/jdi/MethodEntryExitEvents.java +++ b/jdk/test/com/sun/jdi/MethodEntryExitEvents.java @@ -115,7 +115,7 @@ public class MethodEntryExitEvents extends TestScaffold { */ private String[] excludes = {"java.*", "javax.*", "sun.*", "com.sun.*", "com.oracle.*", - "oracle.*"}; + "oracle.*", "jdk.internal.*"}; MethodEntryExitEvents (String args[]) { super(args); From e5fa00ffb59d2297c73848997cd66cc519b4f10a Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Fri, 20 Sep 2013 17:56:54 +0400 Subject: [PATCH 055/293] 8025076: Fix for JDK-8017248 breaks jprt submission for non-unicode locales Reviewed-by: naoto, ksrini --- jdk/test/tools/launcher/8017248/ClassAÌ.java | 5 -- jdk/test/tools/launcher/8017248/test.sh | 16 ----- jdk/test/tools/launcher/DiacriticTest.java | 76 +++++++++++++++++++++ 3 files changed, 76 insertions(+), 21 deletions(-) delete mode 100644 jdk/test/tools/launcher/8017248/ClassAÌ.java delete mode 100644 jdk/test/tools/launcher/8017248/test.sh create mode 100644 jdk/test/tools/launcher/DiacriticTest.java diff --git a/jdk/test/tools/launcher/8017248/ClassAÌ.java b/jdk/test/tools/launcher/8017248/ClassAÌ.java deleted file mode 100644 index 2e264990c74..00000000000 --- a/jdk/test/tools/launcher/8017248/ClassAÌ.java +++ /dev/null @@ -1,5 +0,0 @@ -public class Classà { - public static void main(String args[]) { - System.out.println("Succes!"); - } -} diff --git a/jdk/test/tools/launcher/8017248/test.sh b/jdk/test/tools/launcher/8017248/test.sh deleted file mode 100644 index 7a96f46c223..00000000000 --- a/jdk/test/tools/launcher/8017248/test.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# @test test.sh -# @bug 8017248 -# @summary Compiler Diacritics Issue -# @run shell test.sh - -OSNAME=`uname -s` -if [ "$OSNAME" == "Darwin" ] -then - rm *.class - ${TESTJAVA}/bin/javac *.java - ${TESTJAVA}/bin/java `echo *.class | cut -d. -f1` -else - echo Test is specific to Mac OS X, skipping. - exit 0 -fi diff --git a/jdk/test/tools/launcher/DiacriticTest.java b/jdk/test/tools/launcher/DiacriticTest.java new file mode 100644 index 00000000000..44107bae42f --- /dev/null +++ b/jdk/test/tools/launcher/DiacriticTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8017248 + * @summary Compiler Diacritics Issue + * @run main DiacriticTest + */ + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +public class DiacriticTest extends TestHelper { + + // NFD-normalized form of the class name + static String NAME_NFD="ClassA\u0301"; + // NFC-normalized form of the same class name + static String NAME_NFC="Class\u00C1"; + + public static void main(String[] args) throws IOException { + if (!isMacOSX) { + System.out.println("This test is for Mac OS X only. Passing."); + return; + } + + File sourceFile = new File(NAME_NFC + ".java"); + String source = "public class " + NAME_NFC + " { " + + " public static void main(String args[]) {\n" + + " System.out.println(\"Success!\");\n" + + " }\n" + + "}\n"; + ArrayList content = new ArrayList<>(); + content.add(source); + createFile(sourceFile, content); + + HashMap env = new HashMap<>(); + env.put("LC_CTYPE", "UTF-8"); + + TestResult tr; + tr = doExec(env, javacCmd, NAME_NFD + ".java"); + System.out.println(tr.testOutput); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Compilation failed"); + } + tr = doExec(env, javaCmd, "-cp", ".", NAME_NFD); + System.out.println(tr.testOutput); + if (!tr.isOK()) { + System.out.println(tr); + throw new RuntimeException("Test execution failed"); + } + } +} From fdef74ade2c76938a587ba4fe2ca713843a3d117 Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 20 Sep 2013 16:40:32 +0200 Subject: [PATCH 056/293] 7200277: [parfait] potential buffer overflow in npt/utf.c Reviewed-by: dsamersoff, dcubed --- jdk/src/share/npt/utf.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/npt/utf.c b/jdk/src/share/npt/utf.c index 9c88ca0583d..55ddd210d57 100644 --- a/jdk/src/share/npt/utf.c +++ b/jdk/src/share/npt/utf.c @@ -105,18 +105,24 @@ utf16ToUtf8m(struct UtfInst *ui, unsigned short *utf16, int len, jbyte *output, code = utf16[i]; if ( code >= 0x0001 && code <= 0x007F ) { + if ( outputLen + 1 >= outputMaxLen ) { + return -1; + } output[outputLen++] = code; } else if ( code == 0 || ( code >= 0x0080 && code <= 0x07FF ) ) { + if ( outputLen + 2 >= outputMaxLen ) { + return -1; + } output[outputLen++] = ((code>>6) & 0x1F) | 0xC0; output[outputLen++] = (code & 0x3F) | 0x80; } else if ( code >= 0x0800 && code <= 0xFFFF ) { + if ( outputLen + 3 >= outputMaxLen ) { + return -1; + } output[outputLen++] = ((code>>12) & 0x0F) | 0xE0; output[outputLen++] = ((code>>6) & 0x3F) | 0x80; output[outputLen++] = (code & 0x3F) | 0x80; } - if ( outputLen > outputMaxLen ) { - return -1; - } } output[outputLen] = 0; return outputLen; @@ -412,12 +418,15 @@ bytesToPrintable(struct UtfInst *ui, char *bytes, int len, char *output, int out unsigned byte; byte = bytes[i]; - if ( outputLen >= outputMaxLen ) { - return -1; - } if ( byte <= 0x7f && isprint(byte) && !iscntrl(byte) ) { + if ( outputLen + 1 >= outputMaxLen ) { + return -1; + } output[outputLen++] = (char)byte; } else { + if ( outputLen + 4 >= outputMaxLen ) { + return -1; + } (void)sprintf(output+outputLen,"\\x%02x",byte); outputLen += 4; } From 851fd0447ee2e0ee042d4025663d6f9b6ee69fa7 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Fri, 20 Sep 2013 11:07:06 -0700 Subject: [PATCH 057/293] 8024253: ThreadLocal random can use SecureRandom for the initial seed Co-authored-by: Peter Levart Co-authored-by: Guy Steele Reviewed-by: psandoz, chegar, alanb --- .../classes/java/util/SplittableRandom.java | 31 +++++++++-- .../util/concurrent/ThreadLocalRandom.java | 53 +++++++++++++++++-- .../ThreadLocalRandomTest.java | 2 + 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/util/SplittableRandom.java b/jdk/src/share/classes/java/util/SplittableRandom.java index 5a990f4d215..c3f5c0b4234 100644 --- a/jdk/src/share/classes/java/util/SplittableRandom.java +++ b/jdk/src/share/classes/java/util/SplittableRandom.java @@ -25,8 +25,7 @@ package java.util; -import java.security.SecureRandom; -import java.net.InetAddress; +import java.net.NetworkInterface; import java.util.concurrent.atomic.AtomicLong; import java.util.function.IntConsumer; import java.util.function.LongConsumer; @@ -242,12 +241,34 @@ public final class SplittableRandom { s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); return s; } - int hh = 0; // hashed host address + long h = 0L; try { - hh = InetAddress.getLocalHost().hashCode(); + Enumeration ifcs = + NetworkInterface.getNetworkInterfaces(); + boolean retry = false; // retry once if getHardwareAddress is null + while (ifcs.hasMoreElements()) { + NetworkInterface ifc = ifcs.nextElement(); + if (!ifc.isVirtual()) { // skip fake addresses + byte[] bs = ifc.getHardwareAddress(); + if (bs != null) { + int n = bs.length; + int m = Math.min(n >>> 1, 4); + for (int i = 0; i < m; ++i) + h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i]; + if (m < 4) + h = (h << 8) ^ bs[n-1-m]; + h = mix64(h); + break; + } + else if (!retry) + retry = true; + else + break; + } + } } catch (Exception ignore) { } - return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^ + return (h ^ mix64(System.currentTimeMillis()) ^ mix64(System.nanoTime())); } diff --git a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java index 297f88cd5a3..2cd2b0094bf 100644 --- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -36,6 +36,8 @@ package java.util.concurrent; import java.io.ObjectStreamField; +import java.net.NetworkInterface; +import java.util.Enumeration; import java.util.Random; import java.util.Spliterator; import java.util.concurrent.atomic.AtomicInteger; @@ -71,7 +73,10 @@ import java.util.stream.StreamSupport; * *

Instances of {@code ThreadLocalRandom} are not cryptographically * secure. Consider instead using {@link java.security.SecureRandom} - * in security-sensitive applications. + * in security-sensitive applications. Additionally, + * default-constructed instances do not use a cryptographically random + * seed unless the {@linkplain System#getProperty system property} + * {@code java.util.secureRandomSeed} is set to {@code true}. * * @since 1.7 * @author Doug Lea @@ -129,9 +134,49 @@ public class ThreadLocalRandom extends Random { /** * The next seed for default constructors. */ - private static final AtomicLong seeder = - new AtomicLong(mix64(System.currentTimeMillis()) ^ - mix64(System.nanoTime())); + private static final AtomicLong seeder = new AtomicLong(initialSeed()); + + private static long initialSeed() { + String pp = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "java.util.secureRandomSeed")); + if (pp != null && pp.equalsIgnoreCase("true")) { + byte[] seedBytes = java.security.SecureRandom.getSeed(8); + long s = (long)(seedBytes[0]) & 0xffL; + for (int i = 1; i < 8; ++i) + s = (s << 8) | ((long)(seedBytes[i]) & 0xffL); + return s; + } + long h = 0L; + try { + Enumeration ifcs = + NetworkInterface.getNetworkInterfaces(); + boolean retry = false; // retry once if getHardwareAddress is null + while (ifcs.hasMoreElements()) { + NetworkInterface ifc = ifcs.nextElement(); + if (!ifc.isVirtual()) { // skip fake addresses + byte[] bs = ifc.getHardwareAddress(); + if (bs != null) { + int n = bs.length; + int m = Math.min(n >>> 1, 4); + for (int i = 0; i < m; ++i) + h = (h << 16) ^ (bs[i] << 8) ^ bs[n-1-i]; + if (m < 4) + h = (h << 8) ^ bs[n-1-m]; + h = mix64(h); + break; + } + else if (!retry) + retry = true; + else + break; + } + } + } catch (Exception ignore) { + } + return (h ^ mix64(System.currentTimeMillis()) ^ + mix64(System.nanoTime())); + } /** * The seed increment diff --git a/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java b/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java index e4e91f597bb..f159b67d348 100644 --- a/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java +++ b/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java @@ -33,7 +33,9 @@ import static org.testng.Assert.*; /** * @test + * @bug 8024253 * @run testng ThreadLocalRandomTest + * @run testng/othervm -Djava.util.secureRandomSeed=true ThreadLocalRandomTest * @summary test methods on ThreadLocalRandom */ @Test From ca9e74c63d031db3f4bba330411831d01013d020 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 20 Sep 2013 15:12:05 -0700 Subject: [PATCH 058/293] 8024331: j.u.Map.computeIfPresent() default/nondefault implementations don't throw NPE if the remappingFunction is null and the key is absent Explicitly check for null remappingFunction parameter. Reviewed-by: mduigou, forax, psandoz --- jdk/src/share/classes/java/util/HashMap.java | 2 + jdk/src/share/classes/java/util/Map.java | 4 ++ jdk/test/java/util/Map/Defaults.java | 61 +++++++++++++++++++- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index a6a7d152b5f..16880663f24 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -1132,6 +1132,8 @@ public class HashMap extends AbstractMap public V computeIfPresent(K key, BiFunction remappingFunction) { + if (remappingFunction == null) + throw new NullPointerException(); Node e; V oldValue; int hash = hash(key); if ((e = getNode(hash, key)) != null && diff --git a/jdk/src/share/classes/java/util/Map.java b/jdk/src/share/classes/java/util/Map.java index 4340e6d9c8f..bf1ba8391c8 100644 --- a/jdk/src/share/classes/java/util/Map.java +++ b/jdk/src/share/classes/java/util/Map.java @@ -934,6 +934,7 @@ public interface Map { */ default V computeIfAbsent(K key, Function mappingFunction) { + Objects.requireNonNull(mappingFunction); V v, newValue; return ((v = get(key)) == null && (newValue = mappingFunction.apply(key)) != null && @@ -992,6 +993,7 @@ public interface Map { */ default V computeIfPresent(K key, BiFunction remappingFunction) { + Objects.requireNonNull(remappingFunction); V oldValue; while ((oldValue = get(key)) != null) { V newValue = remappingFunction.apply(key, oldValue); @@ -1068,6 +1070,7 @@ public interface Map { */ default V compute(K key, BiFunction remappingFunction) { + Objects.requireNonNull(remappingFunction); V oldValue = get(key); for (;;) { V newValue = remappingFunction.apply(key, oldValue); @@ -1174,6 +1177,7 @@ public interface Map { */ default V merge(K key, V value, BiFunction remappingFunction) { + Objects.requireNonNull(remappingFunction); V oldValue = get(key); for (;;) { if (oldValue != null) { diff --git a/jdk/test/java/util/Map/Defaults.java b/jdk/test/java/util/Map/Defaults.java index 82470019048..f14cd8aaa4b 100644 --- a/jdk/test/java/util/Map/Defaults.java +++ b/jdk/test/java/util/Map/Defaults.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8010122 8004518 + * @bug 8010122 8004518 8024331 * @summary Test Map default methods * @author Mike Duigou * @run testng Defaults @@ -288,6 +288,21 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfAbsentNPEHashMap() { + Object value = new HashMap().computeIfAbsent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfAbsentNPEHashtable() { + Object value = new Hashtable().computeIfAbsent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfAbsentNPETreeMap() { + Object value = new TreeMap().computeIfAbsent(KEYS[1], null); + } + @Test(dataProvider = "Map rw=true keys=withNull values=withNull") public void testComputeIfPresentNulls(String description, Map map) { assertTrue(map.containsKey(null), description + ": null key absent"); @@ -328,6 +343,21 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), null); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfPresentNPEHashMap() { + Object value = new HashMap().computeIfPresent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfPresentNPEHashtable() { + Object value = new Hashtable().computeIfPresent(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeIfPresentNPETreeMap() { + Object value = new TreeMap().computeIfPresent(KEYS[1], null); + } + @Test(dataProvider = "Map rw=true keys=withNull values=withNull") public void testComputeNulls(String description, Map map) { assertTrue(map.containsKey(null), "null key absent"); @@ -414,6 +444,20 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeNPEHashMap() { + Object value = new HashMap().compute(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeNPEHashtable() { + Object value = new Hashtable().compute(KEYS[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testComputeNPETreeMap() { + Object value = new TreeMap().compute(KEYS[1], null); + } @Test(dataProvider = "Map rw=true keys=withNull values=withNull") public void testMergeNulls(String description, Map map) { @@ -456,6 +500,21 @@ public class Defaults { assertSame(map.get(EXTRA_KEY), EXTRA_VALUE); } + @Test(expectedExceptions = {NullPointerException.class}) + public void testMergeNPEHashMap() { + Object value = new HashMap().merge(KEYS[1], VALUES[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testMergeNPEHashtable() { + Object value = new Hashtable().merge(KEYS[1], VALUES[1], null); + } + + @Test(expectedExceptions = {NullPointerException.class}) + public void testMergeNPETreeMap() { + Object value = new TreeMap().merge(KEYS[1], VALUES[1], null); + } + enum IntegerEnum { e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, From 57f84d86371845457d3b3c0b700c8cca120e30f4 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Fri, 20 Sep 2013 17:11:32 -0700 Subject: [PATCH 059/293] 8024341: j.u.regex.Pattern.splitAsStream() doesn't correspond to split() method if using an example from the spec Reviewed-by: alanb --- .../classes/java/util/regex/Pattern.java | 43 ++++++++++++++----- ...atternTest.java => PatternStreamTest.java} | 37 +++++++++++++++- 2 files changed, 68 insertions(+), 12 deletions(-) rename jdk/test/java/util/regex/{PatternTest.java => PatternStreamTest.java} (82%) diff --git a/jdk/src/share/classes/java/util/regex/Pattern.java b/jdk/src/share/classes/java/util/regex/Pattern.java index 1dc72c10cd3..81ea7145a78 100644 --- a/jdk/src/share/classes/java/util/regex/Pattern.java +++ b/jdk/src/share/classes/java/util/regex/Pattern.java @@ -5755,7 +5755,8 @@ NEXT: while (i <= last) { * input sequence that is terminated by another subsequence that matches * this pattern or is terminated by the end of the input sequence. The * substrings in the stream are in the order in which they occur in the - * input. + * input. Trailing empty strings will be discarded and not encountered in + * the stream. * *

If this pattern does not match any subsequence of the input then * the resulting stream has just one element, namely the input sequence in @@ -5781,6 +5782,8 @@ NEXT: while (i <= last) { private int current; // null if the next element, if any, needs to obtained private String nextElement; + // > 0 if there are N next empty elements + private int emptyElementCount; MatcherIterator() { this.matcher = matcher(input); @@ -5790,26 +5793,46 @@ NEXT: while (i <= last) { if (!hasNext()) throw new NoSuchElementException(); - String n = nextElement; - nextElement = null; - return n; + if (emptyElementCount == 0) { + String n = nextElement; + nextElement = null; + return n; + } else { + emptyElementCount--; + return ""; + } } public boolean hasNext() { - if (nextElement != null) + if (nextElement != null || emptyElementCount > 0) return true; if (current == input.length()) return false; - if (matcher.find()) { + // Consume the next matching element + // Count sequence of matching empty elements + while (matcher.find()) { nextElement = input.subSequence(current, matcher.start()).toString(); current = matcher.end(); - } else { - nextElement = input.subSequence(current, input.length()).toString(); - current = input.length(); + if (!nextElement.isEmpty()) { + return true; + } else { + emptyElementCount++; + } + } + + // Consume last matching element + nextElement = input.subSequence(current, input.length()).toString(); + current = input.length(); + if (!nextElement.isEmpty()) { + return true; + } else { + // Ignore a terminal sequence of matching empty elements + emptyElementCount = 0; + nextElement = null; + return false; } - return true; } } return StreamSupport.stream(Spliterators.spliteratorUnknownSize( diff --git a/jdk/test/java/util/regex/PatternTest.java b/jdk/test/java/util/regex/PatternStreamTest.java similarity index 82% rename from jdk/test/java/util/regex/PatternTest.java rename to jdk/test/java/util/regex/PatternStreamTest.java index aab17319ae4..374b62378e9 100644 --- a/jdk/test/java/util/regex/PatternTest.java +++ b/jdk/test/java/util/regex/PatternStreamTest.java @@ -23,10 +23,11 @@ /** * @test + * @bug 8016846 8024341 * @summary Unit tests for wrapping classes should delegate to default methods * @library ../stream/bootlib * @build java.util.stream.OpTestCase - * @run testng/othervm PatternTest + * @run testng/othervm PatternStreamTest */ import org.testng.annotations.DataProvider; @@ -42,7 +43,7 @@ import java.util.stream.Stream; import java.util.stream.TestData; @Test -public class PatternTest extends OpTestCase { +public class PatternStreamTest extends OpTestCase { @DataProvider(name = "Stream") public static Object[][] makeStreamTestData() { @@ -132,6 +133,38 @@ public class PatternTest extends OpTestCase { expected.add("different"); expected.add("separators"); + + description = "Repeated separators within and at end"; + input = "boo:and:foo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(":and:f"); + + + description = "Many repeated separators within and at end"; + input = "booooo:and:fooooo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":and:f"); + + description = "Many repeated separators before last match"; + input = "fooooo:"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("f"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":"); + data.add(new Object[] {description, input, pattern, expected}); return data.toArray(new Object[0][]); } From 06571ae86244a9690f8cf213a85edb651adcebcc Mon Sep 17 00:00:00 2001 From: Ivan Gerasimov Date: Mon, 23 Sep 2013 04:05:42 +0100 Subject: [PATCH 060/293] 8023130: (process) ProcessBuilder#inheritIO does not work on Windows Reviewed-by: alanb, martin --- .../windows/native/java/lang/ProcessImpl_md.c | 6 +- jdk/test/java/lang/ProcessBuilder/Basic.java | 12 ++- .../ProcessBuilder/InheritIO/InheritIO.java | 47 +++++++++++ .../ProcessBuilder/InheritIO/InheritIO.sh | 81 +++++++++++++++++++ 4 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java create mode 100644 jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c index 1806fb8193c..da7d00b081a 100644 --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c @@ -308,7 +308,11 @@ static jlong processCreate( if (success) { PROCESS_INFORMATION pi; - DWORD processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; + DWORD processFlag = CREATE_UNICODE_ENVIRONMENT; + + /* Suppress popping-up of a console window for non-console applications */ + if (GetConsoleWindow() == NULL) + processFlag |= CREATE_NO_WINDOW; si.dwFlags = STARTF_USESTDHANDLES; if (!CreateProcessW( diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java index ebccabdd9c4..5a55cb6f0f4 100644 --- a/jdk/test/java/lang/ProcessBuilder/Basic.java +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java @@ -298,11 +298,15 @@ public class Basic { System.exit(5); System.err.print("standard error"); System.out.print("standard output"); - } else if (action.equals("testInheritIO")) { + } else if (action.equals("testInheritIO") + || action.equals("testRedirectInherit")) { List childArgs = new ArrayList(javaChildArgs); childArgs.add("testIO"); ProcessBuilder pb = new ProcessBuilder(childArgs); - pb.inheritIO(); + if (action.equals("testInheritIO")) + pb.inheritIO(); + else + redirectIO(pb, INHERIT, INHERIT, INHERIT); ProcessResults r = run(pb); if (! r.out().equals("")) System.exit(7); @@ -1019,10 +1023,10 @@ public class Basic { // Note that this requires __FOUR__ nested JVMs involved in one test, // if you count the harness JVM. //---------------------------------------------------------------- - { + for (String testName : new String[] { "testInheritIO", "testRedirectInherit" } ) { redirectIO(pb, PIPE, PIPE, PIPE); List command = pb.command(); - command.set(command.size() - 1, "testInheritIO"); + command.set(command.size() - 1, testName); Process p = pb.start(); new PrintStream(p.getOutputStream()).print("standard input"); p.getOutputStream().close(); diff --git a/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java new file mode 100644 index 00000000000..83bb23d840c --- /dev/null +++ b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static java.lang.ProcessBuilder.Redirect.*; + +class InheritIO { + + public static class TestInheritIO { + public static void main(String args[]) throws Throwable { + int err = new ProcessBuilder(args).inheritIO().start().waitFor(); + System.err.print("exit value: " + err); + System.exit(err); + } + } + + public static class TestRedirectInherit { + public static void main(String args[]) throws Throwable { + int err = new ProcessBuilder(args) + .redirectInput(INHERIT) + .redirectOutput(INHERIT) + .redirectError(INHERIT) + .start().waitFor(); + System.err.print("exit value: " + err); + System.exit(err); + } + } +} diff --git a/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh new file mode 100644 index 00000000000..2b33a037296 --- /dev/null +++ b/jdk/test/java/lang/ProcessBuilder/InheritIO/InheritIO.sh @@ -0,0 +1,81 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 8023130 +# @summary (process) ProcessBuilder#inheritIO does not work on Windows +# @run shell InheritIO.sh + +if [ "x${TESTSRC}" = "x" ]; then + echo "TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "x${TESTJAVA}" = "x" ]; then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi + + +JAVA="${TESTJAVA}/bin/java" +JAVAC="${TESTJAVA}/bin/javac" + +cp -f ${TESTSRC}/InheritIO.java . + +# compile the class ourselves, so this can run as a standalone test + +${JAVAC} InheritIO.java +RES="$?" +if [ ${RES} != 0 ]; then + echo 'FAIL: Cannot compile InheritIO.java' + exit ${RES} +fi + + +for TEST_NAME in TestInheritIO TestRedirectInherit +do + ${JAVA} ${TESTVMOPTS} -classpath . \ + 'InheritIO$'${TEST_NAME} printf message > stdout.txt 2> stderr.txt + + RES="$?" + if [ ${RES} != 0 ]; then + echo 'FAIL: InheritIO$'${TEST_NAME}' failed with '${RES} + exit ${RES} + fi + + OUT_EXPECTED='message' + OUT_RECEIVED=`cat stdout.txt` + if [ "x${OUT_RECEIVED}" != "x${OUT_EXPECTED}" ]; then + echo "FAIL: unexpected '${OUT_RECEIVED}' in stdout" + exit 1 + fi + + ERR_EXPECTED='exit value: 0' + ERR_RECEIVED=`cat stderr.txt` + if [ "x${ERR_RECEIVED}" != "x${ERR_EXPECTED}" ]; then + echo "FAIL: unexpected '${ERR_RECEIVED}' in stderr" + exit 1 + fi +done + +echo 'PASS: InheritIO works as expected' From ef64db06e24efd1f08aa5e3e5a327d3e38b5734b Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Thu, 29 Aug 2013 11:08:42 +0200 Subject: [PATCH 061/293] 8014659: NPG: performance counters for compressed klass space Reviewed-by: jmasa, sla --- .../sun/tools/jstat/resources/jstat_options | 96 +++++++++++++++++++ .../sun/tools/jstat/gcCapacityOutput1.awk | 8 +- jdk/test/sun/tools/jstat/gcCauseOutput1.awk | 8 +- .../sun/tools/jstat/gcMetaCapacityOutput1.awk | 8 +- jdk/test/sun/tools/jstat/gcOldOutput1.awk | 8 +- jdk/test/sun/tools/jstat/gcOutput1.awk | 8 +- jdk/test/sun/tools/jstat/lineCounts1.awk | 16 ++-- jdk/test/sun/tools/jstat/lineCounts2.awk | 8 +- jdk/test/sun/tools/jstat/lineCounts3.awk | 26 ++--- jdk/test/sun/tools/jstat/lineCounts4.awk | 30 +++--- jdk/test/sun/tools/jstat/timeStamp1.awk | 8 +- .../sun/tools/jstatd/jstatGcutilOutput1.awk | 16 ++-- 12 files changed, 168 insertions(+), 72 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options b/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options index bead54260fd..a629a3c6206 100644 --- a/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options +++ b/jdk/src/share/classes/sun/tools/jstat/resources/jstat_options @@ -207,6 +207,22 @@ option gc { scale K format "0.0" } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + align center + width 6 + scale K + format "0.0" + } + column { + header "^CCSU^" /* Compressed Class Space Used */ + data sun.gc.compressedclassspace.used + align center + width 6 + scale K + format "0.0" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -353,6 +369,30 @@ option gccapacity { width 8 format "0.0" } + column { + header "^CCSMN^" /* Compressed Class Space Capacity - Minimum */ + data sun.gc.compressedclassspace.minCapacity + scale K + align right + width 8 + format "0.0" + } + column { + header "^CCSMX^" /* Compressed Class Space Capacity - Maximum */ + data sun.gc.compressedclassspace.maxCapacity + scale K + align right + width 8 + format "0.0" + } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + scale K + align right + width 8 + format "0.0" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -411,6 +451,14 @@ option gccause { scale raw format "0.00" } + column { + header "^CCS^" /* Compressed Class Space - Percent Used */ + data (1-((sun.gc.compressedclassspace.capacity - sun.gc.compressedclassspace.used)/sun.gc.compressedclassspace.capacity)) * 100 + align right + width 6 + scale raw + format "0.00" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -661,6 +709,22 @@ option gcold { scale K format "0.0" } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + width 8 + align right + scale K + format "0.0" + } + column { + header "^CCSU^" /* Compressed Class Space Used */ + data sun.gc.compressedclassspace.used + width 8 + align right + scale K + format "0.0" + } column { header "^OC^" /* Old Space Capacity - Current */ data sun.gc.generation.1.space.0.capacity @@ -801,6 +865,30 @@ option gcmetacapacity { width 10 format "0.0" } + column { + header "^CCSMN^" /* Compressed Class Space Capacity - Minimum */ + data sun.gc.compressedclassspace.minCapacity + scale K + align right + width 10 + format "0.0" + } + column { + header "^CCSMX^" /* Compressed Class Space Capacity - Maximum */ + data sun.gc.compressedclassspace.maxCapacity + scale K + align right + width 10 + format "0.0" + } + column { + header "^CCSC^" /* Compressed Class Space Capacity - Current */ + data sun.gc.compressedclassspace.capacity + scale K + align right + width 10 + format "0.0" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations @@ -875,6 +963,14 @@ option gcutil { scale raw format "0.00" } + column { + header "^CCS^" /* Compressed Class Space Space - Percent Used */ + data (1-((sun.gc.compressedclassspace.capacity - sun.gc.compressedclassspace.used)/sun.gc.compressedclassspace.capacity)) * 100 + align right + width 6 + scale raw + format "0.00" + } column { header "^YGC^" /* Young Generation Collections */ data sun.gc.collector.0.invocations diff --git a/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk b/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk index c59de5f0bdb..ab630d143b6 100644 --- a/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcCapacityOutput1.awk @@ -3,19 +3,19 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC YGC FGC -# 2176.0 7232.0 2176.0 64.0 64.0 2048.0 6016.0 58304.0 6016.0 6016.0 8192.0 65536.0 8192.0 8192.0 0 +# NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC +# 4096.0 657408.0 8192.0 512.0 512.0 3072.0 6144.0 1312768.0 6144.0 6144.0 512.0 132096.0 5120.0 512.0 131072.0 512.0 1 0 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC YGC FGC $/ { +/^ NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcCauseOutput1.awk b/jdk/test/sun/tools/jstat/gcCauseOutput1.awk index 973d2c049e6..f6127e415f5 100644 --- a/jdk/test/sun/tools/jstat/gcCauseOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcCauseOutput1.awk @@ -3,15 +3,15 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC -# 0.00 100.00 14.01 3.06 23.20 1 0.032 0 0.000 0.032 Allocation Failure No GC +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC +# 0.00 0.00 0.00 9.97 90.94 87.70 2 0.013 0 0.000 0.013 Allocation Failure No GC BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT LGCC GCC $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC $/ { headerlines++; } @@ -23,7 +23,7 @@ BEGIN { # or more letters and spaces. It also provides for the ".", "(", and ")" # characters to allow for the string "System.gc()". # -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*[ ]*[a-zA-Z]+[a-zA-Z \.\(\)]*$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk b/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk index c015dd69c94..12d9544542a 100644 --- a/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcMetaCapacityOutput1.awk @@ -3,18 +3,18 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# MCMN MCMX MC YGC FGC FGCT GCT -# 8192.0 65536.0 8192.0 8192.0 1 0 0.000 0.029 +# MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT +# 512.0 132096.0 5120.0 512.0 131072.0 512.0 1 0 0.000 0.004 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ MCMN MCMX MC YGC FGC FGCT GCT $/ { +/^ MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcOldOutput1.awk b/jdk/test/sun/tools/jstat/gcOldOutput1.awk index df7c6b582c5..c007f66b3be 100644 --- a/jdk/test/sun/tools/jstat/gcOldOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcOldOutput1.awk @@ -3,19 +3,19 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# MC MU OC OU YGC FGC FGCT GCT -# 8192.0 1877.3 6016.0 180.8 1 0 0.000 0.030 +# MC MU CCSC CCSU OC OU YGC FGC FGCT GCT +# 5120.0 4152.0 512.0 397.9 6144.0 200.0 1 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ MC MU OC OU YGC FGC FGCT GCT $/ { +/^ MC MU CCSC CCSU OC OU YGC FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/gcOutput1.awk b/jdk/test/sun/tools/jstat/gcOutput1.awk index 5ac5b2837a2..d1d90a281e2 100644 --- a/jdk/test/sun/tools/jstat/gcOutput1.awk +++ b/jdk/test/sun/tools/jstat/gcOutput1.awk @@ -3,19 +3,19 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0C S1C S0U S1U EC EU OC OU MC MU YGC YGCT FGC FGCT GCT -# 64.0 64.0 0.0 0.0 2048.0 1711.2 6016.0 0.0 8192.0 1948.6 0 0.000 0 0.000 0.000 +# S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT +# 512.0 512.0 0.0 496.0 3072.0 615.5 6144.0 280.0 5120.0 4176.0 512.0 401.0 1 0.005 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0C S1C S0U S1U EC EU OC OU MC MU YGC YGCT FGC FGCT GCT $/ { +/^ S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts1.awk b/jdk/test/sun/tools/jstat/lineCounts1.awk index 33b2f08cc61..b5cb1cdd0bd 100644 --- a/jdk/test/sun/tools/jstat/lineCounts1.awk +++ b/jdk/test/sun/tools/jstat/lineCounts1.awk @@ -3,22 +3,22 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 93.76 28.80 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 73.04 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 73.04 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 73.04 1.82 77.74 68.02 1 0.005 0 0.000 0.005 +# 0.00 93.76 75.00 1.82 77.74 68.02 1 0.005 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts2.awk b/jdk/test/sun/tools/jstat/lineCounts2.awk index b1e80482241..1309d04f8cb 100644 --- a/jdk/test/sun/tools/jstat/lineCounts2.awk +++ b/jdk/test/sun/tools/jstat/lineCounts2.awk @@ -3,18 +3,18 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 93.76 28.40 1.82 77.74 68.02 1 0.005 0 0.000 0.005 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts3.awk b/jdk/test/sun/tools/jstat/lineCounts3.awk index e7c362fbd8f..2d8d4bf1368 100644 --- a/jdk/test/sun/tools/jstat/lineCounts3.awk +++ b/jdk/test/sun/tools/jstat/lineCounts3.awk @@ -3,27 +3,27 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 99.99 66.81 1.24 26.55 1 0.028 0 0.000 0.028 -# 0.00 99.99 68.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 76.81 1.24 27.85 1 0.028 0 0.000 0.028 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 93.76 26.48 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 71.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 73.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 73.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 73.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 75.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 75.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 77.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 77.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 +# 0.00 93.76 77.58 1.95 77.78 68.02 1 0.006 0 0.000 0.006 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstat/lineCounts4.awk b/jdk/test/sun/tools/jstat/lineCounts4.awk index af9487edb27..5ec4ac7e9bf 100644 --- a/jdk/test/sun/tools/jstat/lineCounts4.awk +++ b/jdk/test/sun/tools/jstat/lineCounts4.awk @@ -3,30 +3,30 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 99.99 66.81 1.24 26.55 1 0.028 0 0.000 0.028 -# 0.00 99.99 68.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 70.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 72.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 74.81 1.24 27.84 1 0.028 0 0.000 0.028 -# 0.00 99.99 76.81 1.24 27.85 1 0.028 0 0.000 0.028 -# S0 S1 E O P YGC YGCT FGC FGCT GCT -# 0.00 99.99 76.81 1.24 27.85 1 0.028 0 0.000 0.028 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 96.88 66.55 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 71.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 73.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 73.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 73.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 75.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 75.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 77.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 77.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# 0.00 96.88 77.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 96.88 79.58 2.34 77.78 68.02 1 0.003 0 0.000 0.003 BEGIN { headerlines=0; datalines=0; totallines=0 datalines2=0; } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { if (headerlines == 2) { datalines2++; } diff --git a/jdk/test/sun/tools/jstat/timeStamp1.awk b/jdk/test/sun/tools/jstat/timeStamp1.awk index 825101b3ac4..1d90a18f748 100644 --- a/jdk/test/sun/tools/jstat/timeStamp1.awk +++ b/jdk/test/sun/tools/jstat/timeStamp1.awk @@ -3,18 +3,18 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 +#Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.3 0.00 100.00 68.74 1.95 77.73 68.02 1 0.004 0 0.000 0.004 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^Timestamp S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } diff --git a/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk b/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk index 33b2f08cc61..76b355e6707 100644 --- a/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk +++ b/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk @@ -3,22 +3,22 @@ # that the numerical values conform to a specific pattern, rather than # specific values. # -# S0 S1 E O M YGC YGCT FGC FGCT GCT -# 0.00 100.00 68.87 1.24 27.75 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 68.87 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 -# 0.00 100.00 70.89 1.24 27.84 1 0.044 0 0.000 0.044 +# S0 S1 E O M CCS YGC YGCT FGC FGCT GCT +# 0.00 100.00 56.99 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 63.64 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 64.68 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 65.73 7.81 95.03 87.56 1 0.009 0 0.000 0.009 +# 0.00 100.00 67.22 7.81 95.03 87.56 1 0.009 0 0.000 0.009 BEGIN { headerlines=0; datalines=0; totallines=0 } -/^ S0 S1 E O M YGC YGCT FGC FGCT GCT $/ { +/^ S0 S1 E O M CCS YGC YGCT FGC FGCT GCT $/ { headerlines++; } -/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { +/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/ { datalines++; } From 1e581e11eaaa51a4631e6a97a960fea9c50dce20 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Thu, 3 Oct 2013 15:16:14 -0400 Subject: [PATCH 062/293] 8024427: Missing java.time.chrono serialization tests Add tests and cleanup existing serialization tests Reviewed-by: sherman --- .../java/time/temporal/ValueRange.java | 16 ++ .../time/tck/java/time/AbstractTCKTest.java | 35 +++- .../time/tck/java/time/TCKClock_Fixed.java | 6 - .../time/tck/java/time/TCKClock_Offset.java | 6 - .../time/tck/java/time/TCKClock_System.java | 8 - .../time/tck/java/time/TCKClock_Tick.java | 10 -- .../time/tck/java/time/chrono/CopticDate.java | 23 +++ .../time/chrono/TCKChronoZonedDateTime.java | 18 -- .../tck/java/time/chrono/TCKChronology.java | 17 -- .../time/chrono/TCKTestServiceLoader.java | 24 +-- .../TCKChronoLocalDateSerialization.java | 164 ++++++++++++++++++ ... TCKChronoLocalDateTimeSerialization.java} | 35 ++-- ... TCKChronoZonedDateTimeSerialization.java} | 46 ++--- .../serial/TCKChronologySerialization.java | 64 +++---- .../chrono/serial/TCKCopticSerialization.java | 82 +++++++++ .../chrono/serial/TCKEraSerialization.java | 135 ++++++++++++++ .../time/serial/TCKClockSerialization.java | 114 ++++++++++++ ...ion.java => TCKDurationSerialization.java} | 22 ++- ...tant.java => TCKInstantSerialization.java} | 4 +- ...te.java => TCKLocalDateSerialization.java} | 6 +- ...ava => TCKLocalDateTimeSerialization.java} | 6 +- ...me.java => TCKLocalTimeSerialization.java} | 4 +- ...Day.java => TCKMonthDaySerialization.java} | 9 +- ...va => TCKOffsetDateTimeSerialization.java} | 7 +- ...e.java => TCKOffsetTimeSerialization.java} | 4 +- ...eriod.java => TCKPeriodSerialization.java} | 5 +- ...th.java => TCKYearMonthSerialization.java} | 7 +- ...TCKYear.java => TCKYearSerialization.java} | 4 +- ...oneId.java => TCKZoneIdSerialization.java} | 4 +- ...t.java => TCKZoneOffsetSerialization.java} | 4 +- ...ava => TCKZonedDateTimeSerialization.java} | 5 +- .../java/time/temporal/TCKJulianFields.java | 17 +- .../serial/TCKChronoFieldSerialization.java | 145 ++++++++++++++++ .../serial/TCKChronoUnitSerialization.java | 122 +++++++++++++ .../serial/TCKJulianFieldsSerialization.java | 94 ++++++++++ .../serial/TCKValueRangeSerialization.java | 120 +++++++++++++ ...s.java => TCKWeekFieldsSerialization.java} | 4 +- .../time/zone/TCKZoneOffsetTransition.java | 2 - .../zone/TCKZoneOffsetTransitionRule.java | 3 - ...va => TCKFixedZoneRulesSerialization.java} | 4 +- ...oneOffsetTransitionRuleSerialization.java} | 34 +++- ...TCKZoneOffsetTransitionSerialization.java} | 26 ++- ...es.java => TCKZoneRulesSerialization.java} | 4 +- .../time/test/java/time/AbstractTest.java | 26 --- .../time/test/java/time/TestDuration.java | 28 --- .../time/temporal/TestDateTimeValueRange.java | 13 -- 46 files changed, 1208 insertions(+), 328 deletions(-) create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java rename jdk/test/java/time/tck/java/time/chrono/serial/{TCKChronoLocalDateTime.java => TCKChronoLocalDateTimeSerialization.java} (78%) rename jdk/test/java/time/tck/java/time/chrono/serial/{TCKChronoLocalDate.java => TCKChronoZonedDateTimeSerialization.java} (77%) create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java rename jdk/test/java/time/tck/java/time/serial/{TCKDuration.java => TCKDurationSerialization.java} (83%) rename jdk/test/java/time/tck/java/time/serial/{TCKInstant.java => TCKInstantSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKLocalDate.java => TCKLocalDateSerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKLocalDateTime.java => TCKLocalDateTimeSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKLocalTime.java => TCKLocalTimeSerialization.java} (98%) rename jdk/test/java/time/tck/java/time/serial/{TCKMonthDay.java => TCKMonthDaySerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKOffsetDateTime.java => TCKOffsetDateTimeSerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKOffsetTime.java => TCKOffsetTimeSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKPeriod.java => TCKPeriodSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKYearMonth.java => TCKYearMonthSerialization.java} (96%) rename jdk/test/java/time/tck/java/time/serial/{TCKYear.java => TCKYearSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKZoneId.java => TCKZoneIdSerialization.java} (99%) rename jdk/test/java/time/tck/java/time/serial/{TCKZoneOffset.java => TCKZoneOffsetSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/serial/{TCKZonedDateTime.java => TCKZonedDateTimeSerialization.java} (98%) create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java create mode 100644 jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java rename jdk/test/java/time/tck/java/time/temporal/serial/{TCKWeekFields.java => TCKWeekFieldsSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKFixedZoneRules.java => TCKFixedZoneRulesSerialization.java} (97%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKZoneOffsetTransitionRule.java => TCKZoneOffsetTransitionRuleSerialization.java} (77%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKZoneOffsetTransition.java => TCKZoneOffsetTransitionSerialization.java} (78%) rename jdk/test/java/time/tck/java/time/zone/serial/{TCKZoneRules.java => TCKZoneRulesSerialization.java} (98%) diff --git a/jdk/src/share/classes/java/time/temporal/ValueRange.java b/jdk/src/share/classes/java/time/temporal/ValueRange.java index e003f114adc..a48abafbf10 100644 --- a/jdk/src/share/classes/java/time/temporal/ValueRange.java +++ b/jdk/src/share/classes/java/time/temporal/ValueRange.java @@ -61,6 +61,7 @@ */ package java.time.temporal; +import java.io.InvalidObjectException; import java.io.Serializable; import java.time.DateTimeException; @@ -337,6 +338,21 @@ public final class ValueRange implements Serializable { } } + /** + * Return the ValueRange for the serialized values. + * The values are validated according to the constraints of the {@link #of} + * factory method. + * @return the ValueRange for the serialized fields + * @throws InvalidObjectException if the serialized object has invalid values + */ + private Object readResolve() throws InvalidObjectException { + try { + return of(minSmallest, minLargest, maxSmallest, maxLargest); + } catch (IllegalArgumentException iae) { + throw new InvalidObjectException("Invalid serialized ValueRange: " + iae.getMessage()); + } + } + //----------------------------------------------------------------------- /** * Checks if this range is equal to another range. diff --git a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java index ff7fc02aa1f..29c2aa9fe1a 100644 --- a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java +++ b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java @@ -68,6 +68,8 @@ import java.io.ObjectOutputStream; import java.io.ObjectStreamConstants; import java.io.Serializable; import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Formatter; /** * Base test class. @@ -131,10 +133,10 @@ public abstract class AbstractTCKTest { assertEquals(dis.readByte(), ObjectStreamConstants.TC_NULL); // no superclasses if (expectedBytes.length < 256) { assertEquals(dis.readByte(), ObjectStreamConstants.TC_BLOCKDATA); - assertEquals(dis.readUnsignedByte(), expectedBytes.length); + assertEquals(dis.readUnsignedByte(), expectedBytes.length, "blockdata length incorrect"); } else { assertEquals(dis.readByte(), ObjectStreamConstants.TC_BLOCKDATALONG); - assertEquals(dis.readInt(), expectedBytes.length); + assertEquals(dis.readInt(), expectedBytes.length, "blockdatalong length incorrect"); } byte[] input = new byte[expectedBytes.length]; dis.readFully(input); @@ -162,4 +164,33 @@ public abstract class AbstractTCKTest { } } + + /** + * Utility method to dump a byte array in a java syntax. + * @param bytes and array of bytes + * @return a string containing the bytes formatted in java syntax + */ + protected static String dumpSerialStream(byte[] bytes) { + StringBuilder sb = new StringBuilder(bytes.length * 5); + Formatter fmt = new Formatter(sb); + fmt.format(" byte[] bytes = {" ); + final int linelen = 10; + for (int i = 0; i < bytes.length; i++) { + if (i % linelen == 0) { + fmt.format("%n "); + } + fmt.format(" %3d,", bytes[i] & 0xff); + if ((i % linelen) == (linelen-1) || i == bytes.length - 1) { + fmt.format(" /*"); + int s = i / linelen * linelen; + int k = i % linelen; + for (int j = 0; j <= k && s + j < bytes.length; j++) { + fmt.format(" %c", bytes[s + j] & 0xff); + } + fmt.format(" */"); + } + } + fmt.format("%n };%n"); + return sb.toString(); + } } diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java index ef9f12acc47..3dc567d0ec1 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java @@ -80,12 +80,6 @@ public class TCKClock_Fixed extends AbstractTCKTest { private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); private static final Instant INSTANT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)).toInstant(); - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.fixed(INSTANT, ZoneOffset.UTC)); - assertSerializable(Clock.fixed(INSTANT, PARIS)); - } - //------------------------------------------------------------------------- public void test_fixed_InstantZoneId() { Clock test = Clock.fixed(INSTANT, PARIS); diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Offset.java b/jdk/test/java/time/tck/java/time/TCKClock_Offset.java index 3bab2acd52f..644c1a63880 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_Offset.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_Offset.java @@ -62,7 +62,6 @@ package tck.java.time; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; -import java.io.IOException; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -83,11 +82,6 @@ public class TCKClock_Offset extends AbstractTCKTest { private static final Instant INSTANT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)).toInstant(); private static final Duration OFFSET = Duration.ofSeconds(2); - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.offset(Clock.system(PARIS), OFFSET)); - } - //----------------------------------------------------------------------- public void test_offset_ClockDuration() { Clock test = Clock.offset(Clock.fixed(INSTANT, PARIS), OFFSET); diff --git a/jdk/test/java/time/tck/java/time/TCKClock_System.java b/jdk/test/java/time/tck/java/time/TCKClock_System.java index b5440b2bfd5..94f3b57a4aa 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_System.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_System.java @@ -62,7 +62,6 @@ package tck.java.time; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; -import java.io.IOException; import java.time.Clock; import java.time.Instant; import java.time.ZoneId; @@ -79,13 +78,6 @@ public class TCKClock_System extends AbstractTCKTest { private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow"); private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.systemUTC()); - assertSerializable(Clock.systemDefaultZone()); - assertSerializable(Clock.system(PARIS)); - } - //----------------------------------------------------------------------- public void test_instant() { Clock system = Clock.systemUTC(); diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Tick.java b/jdk/test/java/time/tck/java/time/TCKClock_Tick.java index b245d143ccb..c2212373cd8 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_Tick.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_Tick.java @@ -62,7 +62,6 @@ package tck.java.time; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; -import java.io.IOException; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -81,16 +80,7 @@ public class TCKClock_Tick extends AbstractTCKTest { private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow"); private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); - private static final Duration AMOUNT = Duration.ofSeconds(2); private static final ZonedDateTime ZDT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)); - private static final Instant INSTANT = ZDT.toInstant(); - - //----------------------------------------------------------------------- - public void test_isSerializable() throws IOException, ClassNotFoundException { - assertSerializable(Clock.tickSeconds(PARIS)); - assertSerializable(Clock.tickMinutes(MOSCOW)); - assertSerializable(Clock.tick(Clock.fixed(INSTANT, PARIS), AMOUNT)); - } //----------------------------------------------------------------------- public void test_tick_ClockDuration_250millis() { diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java index eca228adecb..6377c1fc421 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java @@ -354,4 +354,27 @@ public final class CopticDate .append(dom < 10 ? "-0" : "-").append(dom); return buf.toString(); } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof CopticDate) { + CopticDate cd = (CopticDate)obj; + if (this.prolepticYear == cd.prolepticYear && + this.month == cd.month && + this.day == cd.day) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + long epDay = toEpochDay(); + return getChronology().hashCode() ^ ((int) (epDay ^ (epDay >>> 32))); + } + } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java index 3b89857fa45..b2b7fc2cc6c 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java @@ -320,24 +320,6 @@ public class TCKChronoZonedDateTime { } } - //----------------------------------------------------------------------- - // Test Serialization of ISO via chrono API - //----------------------------------------------------------------------- - @Test( dataProvider="calendars") - public void test_ChronoZonedDateTimeSerialization(Chronology chrono) throws Exception { - ZonedDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3).atZone(ZoneId.of("GMT+01:23")); - ChronoZonedDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()).atZone(ref.getZone()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - ChronoZonedDateTime ser = (ChronoZonedDateTime) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); - } - //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_from_TemporalAccessor(Chronology chrono) { diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java index 363f2b94044..38f85fe08ac 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java @@ -64,7 +64,6 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import java.util.Locale; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; @@ -338,20 +337,4 @@ public class TCKChronology { Chronology chrono = Chronology.of("FooFoo"); } - //----------------------------------------------------------------------- - // serialization; serialize and check each calendar system - //----------------------------------------------------------------------- - @Test(dataProvider = "calendarNameAndType") - public void test_chronoSerializationSingleton(String id, String _calendarType) throws Exception { - Chronology original = Chronology.of(id); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(original); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - Chronology ser = (Chronology) in.readObject(); - assertEquals(ser, original, "Deserialized Chronology is not correct"); - } - } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java b/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java index b67f01185aa..1518c0cde29 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java @@ -60,10 +60,6 @@ package tck.java.time.chrono; import static org.testng.Assert.assertEquals; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.time.LocalDate; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; @@ -78,29 +74,11 @@ import org.testng.annotations.Test; public class TCKTestServiceLoader { @Test - public void test_CopticServiceLoader() { + public void test_TestServiceLoader() { Chronology chrono = Chronology.of("Coptic"); ChronoLocalDate copticDate = chrono.date(1729, 4, 27); LocalDate ld = LocalDate.from(copticDate); assertEquals(ld, LocalDate.of(2013, 1, 5), "CopticDate does not match LocalDate"); } - - //----------------------------------------------------------------------- - // Test Serialization of Loaded Coptic Calendar - //----------------------------------------------------------------------- - @Test - public void test_ChronoSerialization() throws Exception { - Chronology chrono = Chronology.of("Coptic"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(chrono); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - Chronology ser = (Chronology) in.readObject(); - assertEquals(ser, chrono, "deserialized Chronology is wrong"); - } } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java new file mode 100644 index 00000000000..af6e9fb2e02 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.YEAR; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.ObjectStreamConstants; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.HijrahChronology; +import java.time.chrono.HijrahDate; +import java.time.chrono.JapaneseDate; +import java.time.chrono.JapaneseEra; +import java.time.chrono.MinguoDate; +import java.time.chrono.ThaiBuddhistDate; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + + + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of built-in chronologies. + */ +@Test +public class TCKChronoLocalDateSerialization extends AbstractTCKTest { + + static final int CHRONO_TYPE = 1; // java.time.chrono.Ser.CHRONO_TYPE + static final int JAPANESE_DATE_TYPE = 4; // java.time.chrono.Ser.JAPANESE_DATE_TYPE + static final int HIJRAH_DATE_TYPE = 6; // java.time.chrono.Ser.HIJRAH_DATE_TYPE + static final int MINGUO_DATE_TYPE = 7; // java.time.chrono.Ser.MINGUO_DATE_TYPE + static final int THAIBUDDHIST_DATE_TYPE = 8; // java.time.chrono.Ser.THAIBUDDHIST_DATE_TYPE + + //----------------------------------------------------------------------- + // Regular data factory for names and descriptions of available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Object[][] data_of_calendars() { + return new Object[][]{ + {JapaneseDate.of(JapaneseEra.HEISEI, 25, 01, 05), JAPANESE_DATE_TYPE}, + {MinguoDate.of(102, 01, 05), MINGUO_DATE_TYPE}, + {ThaiBuddhistDate.of(2556, 01, 05), THAIBUDDHIST_DATE_TYPE}, + }; + } + + + //----------------------------------------------------------------------- + // Test Serialization of Calendars + //----------------------------------------------------------------------- + @Test( dataProvider="calendars") + public void test_ChronoSerialization(ChronoLocalDate date, int dateType) throws Exception { + assertSerializable(date); + } + + //----------------------------------------------------------------------- + // Test that serialization produces exact sequence of bytes + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + private void test_serialization_format(ChronoLocalDate date, int dateType) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(dateType); + dos.writeInt(date.get(YEAR)); + dos.writeByte(date.get(MONTH_OF_YEAR)); + dos.writeByte(date.get(DAY_OF_MONTH)); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(date, bytes); + } + + //----------------------------------------------------------------------- + // Test HijrajDate serialization is a type, Chronology, year, month, day + //----------------------------------------------------------------------- + @Test() + public void test_hijrahSerialization_format() throws Exception { + HijrahChronology chrono = HijrahChronology.INSTANCE; + HijrahDate date = HijrahDate.of(1433, 10, 29); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // Expect the type of the HijrahDate in the stream + byte[] hijrahDateBytes = new byte[] {HIJRAH_DATE_TYPE}; + + // Literal reference to Hijrah-Umalqura Chronology + byte[] hijrahChronoBytes = new byte[] { + 115, 113, 0, 126, 0, 0, /* p w \u0001 \u0006 s q \u0000 ~ \u0000 \u0000 */ + 119, 18, 1, 0, 15, 72, 105, 106, 114, 97, /* w \u0012 \u0001 \u0000 \u000f H i j r a */ + 104, 45, 117, 109, 97, 108, 113, 117, 114, 97, /* h - u m a l q u r a */ + 120, /* \u001d x */ + }; + + // Build the sequence that represents the data in the stream + baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); + dos.writeByte(6); // 6 bytes follow + dos.writeInt(date.get(YEAR)); + dos.writeByte(date.get(MONTH_OF_YEAR)); + dos.writeByte(date.get(DAY_OF_MONTH)); + dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); + } + byte[] dateBytes = baos.toByteArray(); + + assertSerializedBySer(date, hijrahDateBytes, hijrahChronoBytes, dateBytes); + } +} diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTimeSerialization.java similarity index 78% rename from jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java rename to jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTimeSerialization.java index 1ab1cda92c5..8da904b41c8 100644 --- a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTimeSerialization.java @@ -59,21 +59,23 @@ package tck.java.time.chrono.serial; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.chrono.*; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; +import java.time.chrono.IsoChronology; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.MinguoChronology; +import java.time.chrono.ThaiBuddhistChronology; -import static org.testng.Assert.assertEquals; +import tck.java.time.AbstractTCKTest; /** - * Test assertions that must be true for all built-in chronologies. + * Test serialization of ChronoLocalDateTime for all built-in chronologies. */ @Test -public class TCKChronoLocalDateTime { +public class TCKChronoLocalDateTimeSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- // regular data factory for available calendars @@ -89,22 +91,13 @@ public class TCKChronoLocalDateTime { } //----------------------------------------------------------------------- - // Test Serialization ZonedDateTime for each Chronology + // Test Serialization of ChronoLocalDateTime //----------------------------------------------------------------------- - @Test( dataProvider="calendars") + @Test(dataProvider="calendars") public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception { LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3); - ChronoLocalDateTime orginal = chrono.date(ref).atTime(ref.toLocalTime()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - ChronoLocalDateTime ser = (ChronoLocalDateTime) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); + ChronoLocalDateTime original = chrono.date(ref).atTime(ref.toLocalTime()); + assertSerializable(original); } - //----------------------------------------------------------------------- - } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoZonedDateTimeSerialization.java similarity index 77% rename from jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java rename to jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoZonedDateTimeSerialization.java index 4bec5cdc952..c941453a969 100644 --- a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronoZonedDateTimeSerialization.java @@ -56,23 +56,25 @@ */ package tck.java.time.chrono.serial; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.chrono.ChronoZonedDateTime; +import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; +import java.time.chrono.IsoChronology; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.MinguoChronology; +import java.time.chrono.ThaiBuddhistChronology; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.time.LocalDate; -import java.time.chrono.*; - -import static org.testng.Assert.assertEquals; +import tck.java.time.AbstractTCKTest; /** * Test assertions that must be true for all built-in chronologies. */ @Test -public class TCKChronoLocalDate { +public class TCKChronoZonedDateTimeSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- // regular data factory for names and descriptions of available calendars @@ -84,28 +86,18 @@ public class TCKChronoLocalDate { {IsoChronology.INSTANCE}, {JapaneseChronology.INSTANCE}, {MinguoChronology.INSTANCE}, - {ThaiBuddhistChronology.INSTANCE}}; + {ThaiBuddhistChronology.INSTANCE}, + }; } - //----------------------------------------------------------------------- - // Test Serialization of Calendars + // Test Serialization of ISO via chrono API //----------------------------------------------------------------------- @Test( dataProvider="calendars") - public void test_ChronoSerialization(Chronology chrono) throws Exception { - LocalDate ref = LocalDate.of(2013, 1, 5); - ChronoLocalDate orginal = chrono.date(ref); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); - assertEquals(ser, orginal, "deserialized date is wrong"); + public void test_ChronoZonedDateTimeSerialization(Chronology chrono) throws Exception { + ZonedDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3).atZone(ZoneId.of("GMT+01:23")); + ChronoZonedDateTime original = chrono.date(ref).atTime(ref.toLocalTime()).atZone(ref.getZone()); + assertSerializable(original); } - //----------------------------------------------------------------------- - } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java index aed919adafa..7f9e30d35c5 100644 --- a/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java @@ -56,13 +56,9 @@ */ package tck.java.time.chrono.serial; -import static org.testng.Assert.assertEquals; - -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.PrintStream; +import java.io.DataOutputStream; + import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; import java.time.chrono.IsoChronology; @@ -73,11 +69,15 @@ import java.time.chrono.ThaiBuddhistChronology; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + @Test -public class TCKChronologySerialization { +public class TCKChronologySerialization extends AbstractTCKTest { + + static final int CHRONO_TYPE = 1; // java.time.chrono.Ser.CHRONO_TYPE //----------------------------------------------------------------------- - // regular data factory for names and descriptions of available calendars + // Regular data factory for available calendars //----------------------------------------------------------------------- @DataProvider(name = "calendars") Chronology[][] data_of_calendars() { @@ -93,44 +93,22 @@ public class TCKChronologySerialization { // Test Serialization of Calendars //----------------------------------------------------------------------- @Test(dataProvider="calendars") - public void test_ChronoSerialization(Chronology chrono) throws Exception { - System.out.printf(" ChronoSerialization: %s%n", chrono); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(chrono); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - - ObjectInputStream in = new ObjectInputStream(bais); - @SuppressWarnings("unchecked") - Chronology ser = (Chronology) in.readObject(); - assertEquals(ser, chrono, "deserialized Chronology is wrong"); + public void test_chronoSerialization(Chronology chrono) throws Exception { + assertSerializable(chrono); } - /** - * Utility method to dump a byte array in a java syntax. - * @param bytes and array of bytes - * @param os the outputstream to receive the output. - */ - static void dumpSerialStream(byte[] bytes, PrintStream os) { - os.printf(" byte[] bytes = {" ); - final int linelen = 10; - for (int i = 0; i < bytes.length; i++) { - if (i % linelen == 0) { - os.printf("%n "); - } - os.printf(" %3d,", bytes[i] & 0xff); - if ((i % linelen) == (linelen-1) || i == bytes.length - 1) { - os.printf(" /*"); - int s = i / linelen * linelen; - int k = i % linelen; - for (int j = 0; j <= k && s + j < bytes.length; j++) { - os.printf(" %c", bytes[s + j] & 0xff); - } - os.printf(" */"); - } + //----------------------------------------------------------------------- + // Test that serialization produces exact sequence of bytes + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + private void test_serializationBytes(Chronology chrono) throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(CHRONO_TYPE); + dos.writeUTF(chrono.getId()); } - os.printf("%n };%n"); + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(chrono, bytes); } } diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java new file mode 100644 index 00000000000..0fc489ee27c --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + +import java.io.IOException; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Chronology; + +import org.testng.annotations.Test; +import tck.java.time.AbstractTCKTest; + +/** + * Tests the serialization of ChronoLocalDate using a CopticDate. + */ +@Test +public class TCKCopticSerialization extends AbstractTCKTest { + + @Test + public void test_eraSerialization() throws IOException, ClassNotFoundException { + Chronology chrono = Chronology.of("Coptic"); + ChronoLocalDate copticDate = chrono.date(1729, 4, 27); + assertSerializable(copticDate); + } + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java b/jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java new file mode 100644 index 00000000000..8df56baa8ef --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono.serial; + + +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.YEAR; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Era; +import java.time.chrono.HijrahEra; +import java.time.chrono.IsoEra; +import java.time.chrono.JapaneseEra; +import java.time.chrono.MinguoEra; +import java.time.chrono.ThaiBuddhistEra; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Tests the built-in Eras are serializable. + * Note that the serialized form of IsoEra, MinguoEra, ThaiBuddhistEra, + * and HijrahEra are defined and provided by Enum. + * The serialized form of these types are not tested, only that they are + * serializable. + */ +@Test +public class TCKEraSerialization extends AbstractTCKTest { + + static final int JAPANESE_ERA_TYPE = 5; // java.time.chrono.Ser.JAPANESE_ERA + + + //----------------------------------------------------------------------- + // Regular data factory for the available Eras + //----------------------------------------------------------------------- + @DataProvider(name = "Eras") + Era[][] data_of_calendars() { + return new Era[][] { + {HijrahEra.AH}, + {IsoEra.BCE}, + {IsoEra.CE}, + {MinguoEra.BEFORE_ROC}, + {MinguoEra.ROC}, + {ThaiBuddhistEra.BEFORE_BE}, + {ThaiBuddhistEra.BE}, + }; + } + + @Test(dataProvider="Eras") + public void test_eraSerialization(Era era) throws IOException, ClassNotFoundException { + assertSerializableSame(era); + } + + //----------------------------------------------------------------------- + // Test JapaneseEra serialization produces exact sequence of bytes + //----------------------------------------------------------------------- + @Test + private void test_JapaneseErasSerialization() throws Exception { + for (JapaneseEra era : JapaneseEra.values()) { + assertSerializableSame(era); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos) ) { + dos.writeByte(JAPANESE_ERA_TYPE); + dos.writeByte(era.getValue()); + } + byte[] bytes = baos.toByteArray(); + assertSerializedBySer(era, bytes); + } + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java b/jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java new file mode 100644 index 00000000000..d3ef560fb3f --- /dev/null +++ b/jdk/test/java/time/tck/java/time/serial/TCKClockSerialization.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012 Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.serial; + + +import java.io.IOException; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test system and offset clocks serialization. + */ +@Test +public class TCKClockSerialization extends AbstractTCKTest { + + private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow"); + private static final ZoneId PARIS = ZoneId.of("Europe/Paris"); + + private static final Duration AMOUNT = Duration.ofSeconds(2); + private static final ZonedDateTime ZDT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)); + private static final Instant INSTANT = ZDT.toInstant(); + + //----------------------------------------------------------------------- + public void test_systemClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.systemUTC()); + assertSerializable(Clock.systemDefaultZone()); + assertSerializable(Clock.system(PARIS)); + } + + //----------------------------------------------------------------------- + public void test_offsetClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.offset(Clock.system(PARIS), AMOUNT)); + } + + //----------------------------------------------------------------------- + public void test_tickClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.tickSeconds(PARIS)); + assertSerializable(Clock.tickMinutes(MOSCOW)); + assertSerializable(Clock.tick(Clock.fixed(INSTANT, PARIS), AMOUNT)); + } + + //----------------------------------------------------------------------- + public void test_fixedClockSerializable() throws IOException, ClassNotFoundException { + assertSerializable(Clock.fixed(INSTANT, ZoneOffset.UTC)); + assertSerializable(Clock.fixed(INSTANT, PARIS)); + } + +} diff --git a/jdk/test/java/time/tck/java/time/serial/TCKDuration.java b/jdk/test/java/time/tck/java/time/serial/TCKDurationSerialization.java similarity index 83% rename from jdk/test/java/time/tck/java/time/serial/TCKDuration.java rename to jdk/test/java/time/tck/java/time/serial/TCKDurationSerialization.java index e4a9a3f9a18..15d079b9b41 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKDuration.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKDurationSerialization.java @@ -59,18 +59,28 @@ */ package tck.java.time.serial; +import static org.testng.Assert.assertTrue; + import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; +import java.io.Serializable; import java.time.Duration; /** - * Test Duration. + * Test Duration serialization. */ @Test -public class TCKDuration extends AbstractTCKTest { +public class TCKDurationSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @Test + public void test_interfaces() { + assertTrue(Serializable.class.isAssignableFrom(Duration.class)); + assertTrue(Comparable.class.isAssignableFrom(Duration.class)); + } //----------------------------------------------------------------------- @Test @@ -92,4 +102,12 @@ public class TCKDuration extends AbstractTCKTest { assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes); } + //----------------------------------------------------------------------- + // serialization + //----------------------------------------------------------------------- + @Test + public void test_deserializationSingleton() throws Exception { + assertSerializableSame(Duration.ZERO); + } + } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKInstant.java b/jdk/test/java/time/tck/java/time/serial/TCKInstantSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKInstant.java rename to jdk/test/java/time/tck/java/time/serial/TCKInstantSerialization.java index 783ad586375..34a7a513797 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKInstant.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKInstantSerialization.java @@ -68,10 +68,10 @@ import java.io.DataOutputStream; import java.time.Instant; /** - * Test Instant. + * Test Instant serialization. */ @Test -public class TCKInstant extends AbstractTCKTest { +public class TCKInstantSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateSerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java rename to jdk/test/java/time/tck/java/time/serial/TCKLocalDateSerialization.java index aeaa96d372d..c42fa5ece91 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKLocalDate.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateSerialization.java @@ -68,10 +68,10 @@ import java.io.DataOutputStream; import java.time.LocalDate; /** - * Test LocalDate. + * Test LocalDate serialization. */ @Test -public class TCKLocalDate extends AbstractTCKTest { +public class TCKLocalDateSerialization extends AbstractTCKTest { private LocalDate TEST_2007_07_15; @@ -102,6 +102,4 @@ public class TCKLocalDate extends AbstractTCKTest { assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes); } - //----------------------------------------------------------------------- - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTimeSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKLocalDateTimeSerialization.java index a2ae9d2357c..aa739768808 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalDateTimeSerialization.java @@ -67,10 +67,10 @@ import java.io.DataOutputStream; import java.time.LocalDateTime; /** - * Test LocalDateTime. + * Test serialization of LocalDateTime. */ @Test -public class TCKLocalDateTime extends AbstractTCKTest { +public class TCKLocalDateTimeSerialization extends AbstractTCKTest { private LocalDateTime TEST_2007_07_15_12_30_40_987654321 = LocalDateTime.of(2007, 7, 15, 12, 30, 40, 987654321); @@ -99,6 +99,4 @@ public class TCKLocalDateTime extends AbstractTCKTest { assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes); } - - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/serial/TCKLocalTimeSerialization.java similarity index 98% rename from jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKLocalTimeSerialization.java index 06f2ce4c898..d78de651877 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKLocalTimeSerialization.java @@ -68,10 +68,10 @@ import java.io.DataOutputStream; import java.time.LocalTime; /** - * Test LocalTime. + * Test LocalTime serialization. */ @Test -public class TCKLocalTime extends AbstractTCKTest { +public class TCKLocalTimeSerialization extends AbstractTCKTest { private LocalTime TEST_12_30_40_987654321; diff --git a/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/serial/TCKMonthDaySerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java rename to jdk/test/java/time/tck/java/time/serial/TCKMonthDaySerialization.java index cd441663099..8650e7e641e 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKMonthDay.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKMonthDaySerialization.java @@ -69,10 +69,10 @@ import java.io.IOException; import java.time.MonthDay; /** - * Test MonthDay. + * Test MonthDay serialization. */ @Test -public class TCKMonthDay extends AbstractTCKTest { +public class TCKMonthDaySerialization extends AbstractTCKTest { private MonthDay TEST_07_15; @@ -81,8 +81,6 @@ public class TCKMonthDay extends AbstractTCKTest { TEST_07_15 = MonthDay.of(7, 15); } - - //----------------------------------------------------------------------- @Test public void test_serialization() throws ClassNotFoundException, IOException { @@ -101,7 +99,4 @@ public class TCKMonthDay extends AbstractTCKTest { assertSerializedBySer(MonthDay.of(9, 16), bytes); } - //----------------------------------------------------------------------- - - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTimeSerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTimeSerialization.java index 8a1406b8727..371014f5e5c 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetDateTimeSerialization.java @@ -70,10 +70,10 @@ import java.time.OffsetDateTime; import java.time.ZoneOffset; /** - * Test OffsetDateTime. + * Test OffsetDateTime serialization. */ @Test -public class TCKOffsetDateTime extends AbstractTCKTest { +public class TCKOffsetDateTimeSerialization extends AbstractTCKTest { private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); private OffsetDateTime TEST_2008_6_30_11_30_59_000000500; @@ -83,9 +83,6 @@ public class TCKOffsetDateTime extends AbstractTCKTest { TEST_2008_6_30_11_30_59_000000500 = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 500, OFFSET_PONE); } - //----------------------------------------------------------------------- - - //----------------------------------------------------------------------- @Test public void test_serialization() throws Exception { diff --git a/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTimeSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKOffsetTimeSerialization.java index 6bdddba2fb3..ee04e1e298f 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKOffsetTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKOffsetTimeSerialization.java @@ -69,10 +69,10 @@ import java.time.OffsetTime; import java.time.ZoneOffset; /** - * Test OffsetTime. + * Test OffsetTime serialization. */ @Test -public class TCKOffsetTime extends AbstractTCKTest { +public class TCKOffsetTimeSerialization extends AbstractTCKTest { private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); private OffsetTime TEST_11_30_59_500_PONE; diff --git a/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java b/jdk/test/java/time/tck/java/time/serial/TCKPeriodSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKPeriod.java rename to jdk/test/java/time/tck/java/time/serial/TCKPeriodSerialization.java index 2f94df132f0..57bb92f7dce 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKPeriod.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKPeriodSerialization.java @@ -65,10 +65,10 @@ import tck.java.time.AbstractTCKTest; import java.time.Period; /** - * Test Period. + * Test serialization of Period. */ @Test -public class TCKPeriod extends AbstractTCKTest { +public class TCKPeriodSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test @@ -78,5 +78,4 @@ public class TCKPeriod extends AbstractTCKTest { assertSerializable(Period.of(1, 2, 3)); } - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/serial/TCKYearMonthSerialization.java similarity index 96% rename from jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java rename to jdk/test/java/time/tck/java/time/serial/TCKYearMonthSerialization.java index 675767d976c..878b1639725 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKYearMonth.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKYearMonthSerialization.java @@ -69,10 +69,10 @@ import java.io.IOException; import java.time.YearMonth; /** - * Test YearMonth. + * Test serialization of YearMonth. */ @Test -public class TCKYearMonth extends AbstractTCKTest { +public class TCKYearMonthSerialization extends AbstractTCKTest { private YearMonth TEST_2008_06; @@ -100,7 +100,4 @@ public class TCKYearMonth extends AbstractTCKTest { assertSerializedBySer(YearMonth.of(2012, 9), bytes); } - //----------------------------------------------------------------------- - - } diff --git a/jdk/test/java/time/tck/java/time/serial/TCKYear.java b/jdk/test/java/time/tck/java/time/serial/TCKYearSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKYear.java rename to jdk/test/java/time/tck/java/time/serial/TCKYearSerialization.java index 954dacf0c99..12f3955dcc4 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKYear.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKYearSerialization.java @@ -67,10 +67,10 @@ import java.io.DataOutputStream; import java.time.Year; /** - * Test Year. + * Test Year serialization. */ @Test -public class TCKYear extends AbstractTCKTest { +public class TCKYearSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java similarity index 99% rename from jdk/test/java/time/tck/java/time/serial/TCKZoneId.java rename to jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java index 26923f12a80..c6f3abee38c 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKZoneId.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java @@ -73,10 +73,10 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; /** - * Test ZoneId. + * Test serialization of ZoneId. */ @Test -public class TCKZoneId extends AbstractTCKTest { +public class TCKZoneIdSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffsetSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java rename to jdk/test/java/time/tck/java/time/serial/TCKZoneOffsetSerialization.java index 61196e909a1..223d466fcb3 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKZoneOffset.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneOffsetSerialization.java @@ -67,10 +67,10 @@ import java.io.DataOutputStream; import java.time.ZoneOffset; /** - * Test ZoneOffset. + * Test serialization of ZoneOffset. */ @Test -public class TCKZoneOffset extends AbstractTCKTest { +public class TCKZoneOffsetSerialization extends AbstractTCKTest { diff --git a/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTimeSerialization.java similarity index 98% rename from jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java rename to jdk/test/java/time/tck/java/time/serial/TCKZonedDateTimeSerialization.java index a44946b7450..bde33acc04b 100644 --- a/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/serial/TCKZonedDateTimeSerialization.java @@ -72,10 +72,10 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; /** - * Test ZonedDateTime. + * Test serialization of ZonedDateTime. */ @Test -public class TCKZonedDateTime extends AbstractTCKTest { +public class TCKZonedDateTimeSerialization extends AbstractTCKTest { private static final ZoneOffset OFFSET_0100 = ZoneOffset.ofHours(1); private static final ZoneId ZONE_0100 = OFFSET_0100; @@ -139,5 +139,4 @@ public class TCKZonedDateTime extends AbstractTCKTest { assertSerializedBySer(zdt, bytes); } - } diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java index 711792fbedb..a15c31dd2c7 100644 --- a/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/TCKJulianFields.java @@ -76,7 +76,7 @@ import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; /** - * Test. + * Test Julian Fields. */ @Test public class TCKJulianFields extends AbstractTCKTest { @@ -86,16 +86,6 @@ public class TCKJulianFields extends AbstractTCKTest { private static final LocalDate NOV12_1945 = LocalDate.of(1945, 11, 12); private static final LocalDate JAN01_0001 = LocalDate.of(1, 1, 1); - //----------------------------------------------------------------------- - @DataProvider(name="julian_fields") - Object[][] julian_samples() { - return new Object[][] { - {JulianFields.JULIAN_DAY}, - {JulianFields.MODIFIED_JULIAN_DAY}, - {JulianFields.RATA_DIE}, - }; - } - @DataProvider(name="samples") Object[][] data_samples() { return new Object[][] { @@ -122,11 +112,6 @@ public class TCKJulianFields extends AbstractTCKTest { } //----------------------------------------------------------------------- - @Test(dataProvider="julian_fields") - public void test_serializable(TemporalField field) throws IOException, ClassNotFoundException { - assertSerializable(field); - } - public void test_basics() { assertEquals(JulianFields.JULIAN_DAY.isDateBased(), true); assertEquals(JulianFields.JULIAN_DAY.isTimeBased(), false); diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java new file mode 100644 index 00000000000..a80869dc775 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.temporal.ChronoField.AMPM_OF_DAY; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.EPOCH_DAY; +import static java.time.temporal.ChronoField.HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.MICRO_OF_DAY; +import static java.time.temporal.ChronoField.MICRO_OF_SECOND; +import static java.time.temporal.ChronoField.MILLI_OF_DAY; +import static java.time.temporal.ChronoField.MILLI_OF_SECOND; +import static java.time.temporal.ChronoField.MINUTE_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.NANO_OF_DAY; +import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; +import static java.time.temporal.ChronoField.SECOND_OF_DAY; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; +import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoField.ERA; + +import java.io.IOException; +import java.time.temporal.ChronoField; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of ChronoField. + */ +@Test +public class TCKChronoFieldSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + // List of Fields + //----------------------------------------------------------------------- + @DataProvider(name="fieldBased") + Object[][] data_fieldBased() { + return new Object[][] { + {DAY_OF_WEEK}, + {ALIGNED_DAY_OF_WEEK_IN_MONTH}, + {ALIGNED_DAY_OF_WEEK_IN_YEAR}, + {DAY_OF_MONTH}, + {DAY_OF_YEAR}, + {EPOCH_DAY}, + {ALIGNED_WEEK_OF_MONTH}, + {ALIGNED_WEEK_OF_YEAR}, + {MONTH_OF_YEAR}, + {PROLEPTIC_MONTH}, + {YEAR_OF_ERA}, + {YEAR}, + {ERA}, + + {AMPM_OF_DAY}, + {CLOCK_HOUR_OF_DAY}, + {HOUR_OF_DAY}, + {CLOCK_HOUR_OF_AMPM}, + {HOUR_OF_AMPM}, + {MINUTE_OF_DAY}, + {MINUTE_OF_HOUR}, + {SECOND_OF_DAY}, + {SECOND_OF_MINUTE}, + {MILLI_OF_DAY}, + {MILLI_OF_SECOND}, + {MICRO_OF_DAY}, + {MICRO_OF_SECOND}, + {NANO_OF_DAY}, + {NANO_OF_SECOND}, + }; + } + + @Test(dataProvider = "fieldBased") + public void test_fieldSerializable(ChronoField field) throws IOException, ClassNotFoundException { + assertSerializableSame(field); + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java new file mode 100644 index 00000000000..15e34c6a1b0 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HALF_DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLENNIA; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.time.temporal.ChronoUnit.WEEKS; +import static java.time.temporal.ChronoUnit.YEARS; + +import java.io.IOException; +import java.time.temporal.ChronoUnit; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test. + */ +@Test +public class TCKChronoUnitSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + // ChronoUnits + //----------------------------------------------------------------------- + @DataProvider(name="chronoUnit") + Object[][] data_chronoUnit() { + return new Object[][] { + {FOREVER}, + {ERAS}, + {MILLENNIA}, + {CENTURIES}, + {DECADES}, + {YEARS}, + {MONTHS}, + {WEEKS}, + {DAYS}, + + {HALF_DAYS}, + {HOURS}, + {MINUTES}, + {SECONDS}, + {MICROS}, + {MILLIS}, + {NANOS}, + + }; + } + + @Test(dataProvider = "chronoUnit") + public void test_unitType(ChronoUnit unit) throws IOException, ClassNotFoundException { + assertSerializableSame(unit); + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java new file mode 100644 index 00000000000..53047f8441a --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import java.io.IOException; +import java.time.temporal.JulianFields; +import java.time.temporal.TemporalField; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of JulianFields + */ +@Test +public class TCKJulianFieldsSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + @DataProvider(name="julian_fields") + Object[][] julian_samples() { + return new Object[][] { + {JulianFields.JULIAN_DAY}, + {JulianFields.MODIFIED_JULIAN_DAY}, + {JulianFields.RATA_DIE}, + }; + } + + + //----------------------------------------------------------------------- + @Test(dataProvider="julian_fields") + public void test_serializable(TemporalField field) throws IOException, ClassNotFoundException { + assertSerializable(field); + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java new file mode 100644 index 00000000000..9114bec6ca0 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal.serial; + +import static org.testng.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.time.temporal.ValueRange; + +import org.testng.annotations.Test; + +import tck.java.time.AbstractTCKTest; + +/** + * Test serialization of ValueRange. + */ +@Test +public class TCKValueRangeSerialization extends AbstractTCKTest { + + //----------------------------------------------------------------------- + // Serialization + //----------------------------------------------------------------------- + public void test_serialization() throws Exception { + ValueRange range = ValueRange.of(1, 2, 3, 4); + assertSerializable(range); + } + + + /** + * Verify Serialized bytes of a ValueRange. + * @throws IOException if thrown during serialization is an unexpected test tailure + */ + public void test_valueRangeSerialized() throws IOException { + byte[] expected = { + (byte)172, (byte)237, 0, 5, 115, 114, 0, 29, 106, 97, /* \u00ac \u00ed \u0000 \u0005 s r \u0000 \u001d j a */ + 118, 97, 46, 116, 105, 109, 101, 46, 116, 101, /* v a . t i m e . t e */ + 109, 112, 111, 114, 97, 108, 46, 86, 97, 108, /* m p o r a l . V a l */ + 117, 101, 82, 97, 110, 103, 101, (byte)154, 113, (byte)169, /* u e R a n g e \u009a q \u00a9 */ + 86, (byte)242, (byte)205, 90, (byte)184, 2, 0, 4, 74, 0, /* V \u00f2 \u00cd Z \u00b8 \u0002 \u0000 \u0004 J \u0000 */ + 10, 109, 97, 120, 76, 97, 114, 103, 101, 115, /* m a x L a r g e s */ + 116, 74, 0, 11, 109, 97, 120, 83, 109, 97, /* t J \u0000 \u000b m a x S m a */ + 108, 108, 101, 115, 116, 74, 0, 10, 109, 105,/* l l e s t J \u0000 m i */ + 110, 76, 97, 114, 103, 101, 115, 116, 74, 0, /* n L a r g e s t J \u0000 */ + 11, 109, 105, 110, 83, 109, 97, 108, 108, 101, /* \u000b m i n S m a l l e */ + 115, 116, 120, 112, 0, 0, 0, 0, 0, 0, /* s t x p \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 */ + 0, 40, 0, 0, 0, 0, 0, 0, 0, 30, /* \u0000 ( \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u001e */ + 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, /* \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0014 \u0000 \u0000 */ + 0, 0, 0, 0, 0, 10, /* \u0000 \u0000 \u0000 \u0000 \u0000 */ + }; + + ValueRange range = ValueRange.of(10, 20, 30, 40); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos) ) { + oos.writeObject(range); + + byte[] actual = baos.toByteArray(); + assertEquals(actual, expected, "Serialized bytes incorrect"); + } + } + +} diff --git a/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFieldsSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java rename to jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFieldsSerialization.java index 749515e7c9d..43f45a84f22 100644 --- a/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/serial/TCKWeekFieldsSerialization.java @@ -65,10 +65,10 @@ import java.time.DayOfWeek; import java.time.temporal.WeekFields; /** - * Test WeekFields. + * Test serialization of WeekFields. */ @Test -public class TCKWeekFields extends AbstractTCKTest { +public class TCKWeekFieldsSerialization extends AbstractTCKTest { //----------------------------------------------------------------------- @Test(dataProvider="weekFields") diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java index 891deb76733..9cd42624bfa 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java @@ -127,7 +127,6 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); assertEquals(test.getDuration(), Duration.of(1, HOURS)); - assertSerializable(test); } @Test @@ -143,7 +142,6 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertEquals(test.getOffsetBefore(), OFFSET_0300); assertEquals(test.getOffsetAfter(), OFFSET_0200); assertEquals(test.getDuration(), Duration.of(-1, HOURS)); - assertSerializable(test); } diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java index 9ad26627edd..58e2ff56e7b 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java @@ -173,7 +173,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertEquals(test.getStandardOffset(), OFFSET_0200); assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); - assertSerializable(test); } @Test @@ -190,7 +189,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertEquals(test.getStandardOffset(), OFFSET_0200); assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); - assertSerializable(test); } @Test @@ -207,7 +205,6 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertEquals(test.getStandardOffset(), OFFSET_0200); assertEquals(test.getOffsetBefore(), OFFSET_0200); assertEquals(test.getOffsetAfter(), OFFSET_0300); - assertSerializable(test); } diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRulesSerialization.java similarity index 97% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRulesSerialization.java index b5d88d4f983..790e54fbb6d 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRulesSerialization.java @@ -72,10 +72,10 @@ import java.time.zone.ZoneRules; import static org.testng.Assert.assertEquals; /** - * Test ZoneRules for fixed offset time-zones. + * Test serialization of ZoneRules for fixed offset time-zones. */ @Test -public class TCKFixedZoneRules { +public class TCKFixedZoneRulesSerialization { private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1); private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2); diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRuleSerialization.java similarity index 77% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRuleSerialization.java index 1ccae56c8d9..9e4bf9b455e 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRule.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRuleSerialization.java @@ -59,10 +59,7 @@ */ package tck.java.time.zone.serial; -import static org.testng.Assert.assertEquals; - import java.time.DayOfWeek; -import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; import java.time.ZoneOffset; @@ -73,17 +70,19 @@ import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; /** - * Test ZoneOffsetTransitionRule. + * Test ZoneOffsetTransitionRule serialization. */ @Test -public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { +public class TCKZoneOffsetTransitionRuleSerialization extends AbstractTCKTest { private static final LocalTime TIME_0100 = LocalTime.of(1, 0); private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2); private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3); - + //----------------------------------------------------------------------- + // Test serialization + //----------------------------------------------------------------------- @Test public void test_serialization_unusualOffsets() throws Exception { ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( @@ -110,5 +109,28 @@ public class TCKZoneOffsetTransitionRule extends AbstractTCKTest { assertSerializable(test); } + @Test + public void test_serialization_floatingWeek() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_floatingWeekBackwards() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_fixedDate() throws Exception { + ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of( + Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.WALL, + OFFSET_0200, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } } diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionSerialization.java similarity index 78% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionSerialization.java index a57d31eaf71..e70fc747d88 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransition.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionSerialization.java @@ -59,6 +59,9 @@ */ package tck.java.time.zone.serial; +import static java.time.temporal.ChronoUnit.HOURS; + +import java.time.Duration; import org.testng.annotations.Test; import tck.java.time.AbstractTCKTest; @@ -68,10 +71,13 @@ import java.time.ZoneOffset; import java.time.zone.ZoneOffsetTransition; /** - * Test ZoneOffsetTransition. + * Test serialization of ZoneOffsetTransition. */ @Test -public class TCKZoneOffsetTransition extends AbstractTCKTest { +public class TCKZoneOffsetTransitionSerialization extends AbstractTCKTest { + + private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2); + private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3); //----------------------------------------------------------------------- @Test @@ -88,4 +94,20 @@ public class TCKZoneOffsetTransition extends AbstractTCKTest { assertSerializable(test); } + @Test + public void test_serialization_gap() throws Exception { + LocalDateTime before = LocalDateTime.of(2010, 3, 31, 1, 0); + LocalDateTime after = LocalDateTime.of(2010, 3, 31, 2, 0); + ZoneOffsetTransition test = ZoneOffsetTransition.of(before, OFFSET_0200, OFFSET_0300); + assertSerializable(test); + } + + @Test + public void test_serialization_overlap() throws Exception { + LocalDateTime before = LocalDateTime.of(2010, 10, 31, 1, 0); + LocalDateTime after = LocalDateTime.of(2010, 10, 31, 0, 0); + ZoneOffsetTransition test = ZoneOffsetTransition.of(before, OFFSET_0300, OFFSET_0200); + assertSerializable(test); + } + } diff --git a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRulesSerialization.java similarity index 98% rename from jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java rename to jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRulesSerialization.java index 6f83223f07c..80237967990 100644 --- a/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/serial/TCKZoneRulesSerialization.java @@ -71,10 +71,10 @@ import java.time.zone.ZoneRules; import static org.testng.Assert.assertEquals; /** - * Test ZoneRules. + * Test serialization of ZoneRules. */ @Test -public class TCKZoneRules { +public class TCKZoneRulesSerialization { public void test_serialization_loaded() throws Exception { assertSerialization(europeLondon()); diff --git a/jdk/test/java/time/test/java/time/AbstractTest.java b/jdk/test/java/time/test/java/time/AbstractTest.java index 6d4d1340964..97f1cf4b486 100644 --- a/jdk/test/java/time/test/java/time/AbstractTest.java +++ b/jdk/test/java/time/test/java/time/AbstractTest.java @@ -63,11 +63,6 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -87,27 +82,6 @@ public abstract class AbstractTest { return true; } - protected static void assertSerializable(Object o) throws IOException, ClassNotFoundException { - Object deserialisedObject = writeThenRead(o); - assertEquals(deserialisedObject, o); - } - - protected static void assertSerializableAndSame(Object o) throws IOException, ClassNotFoundException { - Object deserialisedObject = writeThenRead(o); - assertSame(deserialisedObject, o); - } - - private static Object writeThenRead(Object o) throws IOException, ClassNotFoundException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) { - oos.writeObject(o); - } - - try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { - return ois.readObject(); - } - } - protected static void assertImmutable(Class cls) { assertTrue(Modifier.isPublic(cls.getModifiers())); assertTrue(Modifier.isFinal(cls.getModifiers())); diff --git a/jdk/test/java/time/test/java/time/TestDuration.java b/jdk/test/java/time/test/java/time/TestDuration.java index 23aedd84aa5..2b2043377f3 100644 --- a/jdk/test/java/time/test/java/time/TestDuration.java +++ b/jdk/test/java/time/test/java/time/TestDuration.java @@ -63,11 +63,6 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; import java.time.Duration; import org.testng.annotations.Test; @@ -84,29 +79,6 @@ public class TestDuration extends AbstractTest { assertImmutable(Duration.class); } - //----------------------------------------------------------------------- - @Test - public void test_interfaces() { - assertTrue(Serializable.class.isAssignableFrom(Duration.class)); - assertTrue(Comparable.class.isAssignableFrom(Duration.class)); - } - - //----------------------------------------------------------------------- - // serialization - //----------------------------------------------------------------------- - @Test - public void test_deserializationSingleton() throws Exception { - Duration orginal = Duration.ZERO; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(orginal); - out.close(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bais); - Duration ser = (Duration) in.readObject(); - assertSame(ser, Duration.ZERO); - } - @Test public void plus_zeroReturnsThis() { Duration t = Duration.ofSeconds(-1); diff --git a/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java b/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java index 67a40839257..4fa31f23b69 100644 --- a/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java +++ b/jdk/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java @@ -87,19 +87,6 @@ public class TestDateTimeValueRange extends AbstractTest { assertImmutable(ValueRange.class); } - //----------------------------------------------------------------------- - // Serialization - //----------------------------------------------------------------------- - public void test_serialization() throws Exception { - Object obj = ValueRange.of(1, 2, 3, 4); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(obj); - oos.close(); - ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); - assertEquals(ois.readObject(), obj); - } - //----------------------------------------------------------------------- // of(long,long) //----------------------------------------------------------------------- From f426e35d99b8c4f49f3b0b3068b480d5f8bb0517 Mon Sep 17 00:00:00 2001 From: Peter Allwin Date: Fri, 4 Oct 2013 15:00:42 +0200 Subject: [PATCH 063/293] 8025829: Add java/lang/instrument/RetransformBigClass.sh to problemlist Reviewed-by: sla, jbachorik --- jdk/test/ProblemList.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 984d431ef35..c8279529c28 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -134,6 +134,9 @@ java/lang/management/MemoryMXBean/LowMemoryTest2.sh generic-all # 8021230 java/lang/ThreadLocal/ThreadLocalSupplierTest.java generic-all +# 8023201 +java/lang/instrument/RetransformBigClass.sh generic-all +java/lang/instrument/RedefineBigClass.sh generic-all ############################################################################ From cbe29b7b72f02cdf21f51695d6cf87c51383bc60 Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Fri, 4 Oct 2013 16:05:55 +0100 Subject: [PATCH 064/293] 8008296: keytool utility doesn't support '-importpassword' command Reviewed-by: weijun --- .../sun/security/tools/keytool/Main.java | 115 +++++++++-- .../sun/security/tools/keytool/Resources.java | 11 +- .../tools/keytool/StorePasswords.java | 186 ++++++++++++++++++ .../tools/keytool/StorePasswordsByShell.sh | 140 +++++++++++++ 4 files changed, 440 insertions(+), 12 deletions(-) create mode 100644 jdk/test/sun/security/tools/keytool/StorePasswords.java create mode 100644 jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Main.java b/jdk/src/share/classes/sun/security/tools/keytool/Main.java index 02ea1d0497f..c5e0fe7d627 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Main.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Main.java @@ -72,6 +72,8 @@ import sun.security.provider.certpath.CertStoreHelper; import sun.security.util.Password; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; import sun.security.pkcs.PKCS9Attribute; import sun.security.tools.KeyStoreUtil; @@ -190,6 +192,10 @@ public final class Main { KEYPASS, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), + IMPORTPASS("Imports.a.password", + ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE, + STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, + PROVIDERARG, PROVIDERPATH, V, PROTECTED), IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore", SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE, DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS, @@ -409,6 +415,8 @@ public final class Main { command = GENKEYPAIR; } else if (collator.compare(flags, "-import") == 0) { command = IMPORTCERT; + } else if (collator.compare(flags, "-importpassword") == 0) { + command = IMPORTPASS; } /* * Help @@ -727,6 +735,7 @@ public final class Main { command != GENSECKEY && command != IDENTITYDB && command != IMPORTCERT && + command != IMPORTPASS && command != IMPORTKEYSTORE && command != PRINTCRL) { throw new Exception(rb.getString @@ -808,6 +817,7 @@ public final class Main { command == GENKEYPAIR || command == GENSECKEY || command == IMPORTCERT || + command == IMPORTPASS || command == IMPORTKEYSTORE || command == KEYCLONE || command == CHANGEALIAS || @@ -958,6 +968,13 @@ public final class Main { } doGenSecretKey(alias, keyAlgName, keysize); kssave = true; + } else if (command == IMPORTPASS) { + if (keyAlgName == null) { + keyAlgName = "PBE"; + } + // password is stored as a secret key + doGenSecretKey(alias, keyAlgName, keysize); + kssave = true; } else if (command == IDENTITYDB) { if (filename != null) { try (InputStream inStream = new FileInputStream(filename)) { @@ -1419,6 +1436,43 @@ public final class Main { } return null; // PKCS11, MSCAPI, or -protected } + + /* + * Prompt the user for the password credential to be stored. + */ + private char[] promptForCredential() throws Exception { + // Handle password supplied via stdin + if (System.console() == null) { + char[] importPass = Password.readPassword(System.in); + passwords.add(importPass); + return importPass; + } + + int count; + for (count = 0; count < 3; count++) { + System.err.print( + rb.getString("Enter.the.password.to.be.stored.")); + System.err.flush(); + char[] entered = Password.readPassword(System.in); + passwords.add(entered); + System.err.print(rb.getString("Re.enter.password.")); + char[] passAgain = Password.readPassword(System.in); + passwords.add(passAgain); + if (!Arrays.equals(entered, passAgain)) { + System.err.println(rb.getString("They.don.t.match.Try.again")); + continue; + } + return entered; + } + + if (count == 3) { + throw new Exception(rb.getString + ("Too.many.failures.key.not.added.to.keystore")); + } + + return null; + } + /** * Creates a new secret key. */ @@ -1436,24 +1490,63 @@ public final class Main { throw new Exception(form.format(source)); } + // Use the keystore's default PBE algorithm for entry protection + boolean useDefaultPBEAlgorithm = true; SecretKey secKey = null; - KeyGenerator keygen = KeyGenerator.getInstance(keyAlgName); - if (keysize != -1) { - keygen.init(keysize); - } else if ("DES".equalsIgnoreCase(keyAlgName)) { - keygen.init(56); - } else if ("DESede".equalsIgnoreCase(keyAlgName)) { - keygen.init(168); + + if (keyAlgName.toUpperCase().startsWith("PBE")) { + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE"); + + // User is prompted for PBE credential + secKey = + factory.generateSecret(new PBEKeySpec(promptForCredential())); + + // Check whether a specific PBE algorithm was specified + if (!"PBE".equalsIgnoreCase(keyAlgName)) { + useDefaultPBEAlgorithm = false; + } + + if (verbose) { + MessageFormat form = new MessageFormat(rb.getString( + "Generated.keyAlgName.secret.key")); + Object[] source = + {useDefaultPBEAlgorithm ? "PBE" : secKey.getAlgorithm()}; + System.err.println(form.format(source)); + } } else { - throw new Exception(rb.getString - ("Please.provide.keysize.for.secret.key.generation")); + KeyGenerator keygen = KeyGenerator.getInstance(keyAlgName); + if (keysize == -1) { + if ("DES".equalsIgnoreCase(keyAlgName)) { + keysize = 56; + } else if ("DESede".equalsIgnoreCase(keyAlgName)) { + keysize = 168; + } else { + throw new Exception(rb.getString + ("Please.provide.keysize.for.secret.key.generation")); + } + } + keygen.init(keysize); + secKey = keygen.generateKey(); + + if (verbose) { + MessageFormat form = new MessageFormat(rb.getString + ("Generated.keysize.bit.keyAlgName.secret.key")); + Object[] source = {new Integer(keysize), + secKey.getAlgorithm()}; + System.err.println(form.format(source)); + } } - secKey = keygen.generateKey(); if (keyPass == null) { keyPass = promptForKeyPass(alias, null, storePass); } - keyStore.setKeyEntry(alias, secKey, keyPass, null); + + if (useDefaultPBEAlgorithm) { + keyStore.setKeyEntry(alias, secKey, keyPass, null); + } else { + keyStore.setEntry(alias, new KeyStore.SecretKeyEntry(secKey), + new KeyStore.PasswordProtection(keyPass, keyAlgName, null)); + } } /** diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources.java index 393aa3babe1..6199927ee44 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,10 +65,16 @@ public class Resources extends java.util.ListResourceBundle { {"Generates.certificate.from.a.certificate.request", "Generates certificate from a certificate request"}, //-gencert {"Generates.CRL", "Generates CRL"}, //-gencrl + {"Generated.keyAlgName.secret.key", + "Generated {0} secret key"}, //-genseckey + {"Generated.keysize.bit.keyAlgName.secret.key", + "Generated {0}-bit {1} secret key"}, //-genseckey {"Imports.entries.from.a.JDK.1.1.x.style.identity.database", "Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb {"Imports.a.certificate.or.a.certificate.chain", "Imports a certificate or a certificate chain"}, //-importcert + {"Imports.a.password", + "Imports a password"}, //-importpass {"Imports.one.or.all.entries.from.another.keystore", "Imports one or all entries from another keystore"}, //-importkeystore {"Clones.a.key.entry", @@ -220,6 +226,8 @@ public class Resources extends java.util.ListResourceBundle { {"Must.specify.alias", "Must specify alias"}, {"Keystore.password.must.be.at.least.6.characters", "Keystore password must be at least 6 characters"}, + {"Enter.the.password.to.be.stored.", + "Enter the password to be stored: "}, {"Enter.keystore.password.", "Enter keystore password: "}, {"Enter.source.keystore.password.", "Enter source keystore password: "}, {"Enter.destination.keystore.password.", "Enter destination keystore password: "}, @@ -328,6 +336,7 @@ public class Resources extends java.util.ListResourceBundle { {"New.prompt.", "New {0}: "}, {"Passwords.must.differ", "Passwords must differ"}, {"Re.enter.new.prompt.", "Re-enter new {0}: "}, + {"Re.enter.passpword.", "Re-enter password: "}, {"Re.enter.new.password.", "Re-enter new password: "}, {"They.don.t.match.Try.again", "They don't match. Try again"}, {"Enter.prompt.alias.name.", "Enter {0} alias name: "}, diff --git a/jdk/test/sun/security/tools/keytool/StorePasswords.java b/jdk/test/sun/security/tools/keytool/StorePasswords.java new file mode 100644 index 00000000000..e1f0c275b94 --- /dev/null +++ b/jdk/test/sun/security/tools/keytool/StorePasswords.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8008296 + * @summary Store and retrieve user passwords using PKCS#12 keystore + */ + +import java.io.*; +import java.security.*; +import java.util.*; +import javax.crypto.*; +import javax.crypto.spec.*; + +/* + * Store and retrieve passwords protected by a selection of PBE algorithms, + * using a PKCS#12 keystore. + */ +public class StorePasswords { + + private static final String[] PBE_ALGORITHMS = new String[] { + "default PBE algorithm", + "PBEWithMD5AndDES", + "PBEWithSHA1AndDESede", + "PBEWithSHA1AndRC2_40", + "PBEWithSHA1AndRC2_128", + "PBEWithSHA1AndRC4_40", + "PBEWithSHA1AndRC4_128", + "PBEWithHmacSHA1AndAES_128", + "PBEWithHmacSHA224AndAES_128", + "PBEWithHmacSHA256AndAES_128", + "PBEWithHmacSHA384AndAES_128", + "PBEWithHmacSHA512AndAES_128", + "PBEWithHmacSHA1AndAES_256", + "PBEWithHmacSHA224AndAES_256", + "PBEWithHmacSHA256AndAES_256", + "PBEWithHmacSHA384AndAES_256", + "PBEWithHmacSHA512AndAES_256" + }; + + private static final String KEYSTORE = "mykeystore.p12"; + private static final char[] KEYSTORE_PWD = "changeit".toCharArray(); + private static final char[] ENTRY_PWD = "protectit".toCharArray(); + private static final char[] USER_PWD = "hello1".toCharArray(); + + public static void main(String[] args) throws Exception { + + new File(KEYSTORE).delete(); + + int storeCount = store(); + int recoverCount = recover(); + + if (recoverCount != storeCount) { + throw new Exception("Stored " + storeCount + " user passwords, " + + "recovered " + recoverCount + " user passwords"); + } + System.out.println("\nStored " + storeCount + " user passwords, " + + "recovered " + recoverCount + " user passwords"); + } + + private static int store() throws Exception { + int count = 0; + // Load an empty PKCS#12 keystore + KeyStore keystore = KeyStore.getInstance("PKCS12"); + System.out.println("\nLoading PKCS#12 keystore..."); + keystore.load(null, null); + + // Derive a PBE key from the password + PBEKeySpec keySpec = new PBEKeySpec(USER_PWD); + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE"); + SecretKey key = factory.generateSecret(keySpec); + PBEParameterSpec specWithEightByteSalt = + new PBEParameterSpec("NaClNaCl".getBytes(), 1024); + + // Store the user password in a keystore entry (for each algorithm) + for (String algorithm : PBE_ALGORITHMS) { + + try { + System.out.println("Storing user password '" + + new String(USER_PWD) + "' (protected by " + algorithm + + ")"); + + if (algorithm.equals("default PBE algorithm")) { + keystore.setKeyEntry( + "this entry is protected by " + algorithm, key, + ENTRY_PWD, null); + } else { + keystore.setEntry( + "this entry is protected by " + algorithm, + new KeyStore.SecretKeyEntry(key), + new KeyStore.PasswordProtection(ENTRY_PWD, algorithm, + null)); + } + count++; + + } catch (KeyStoreException e) { + Throwable inner = e.getCause(); + if (inner instanceof UnrecoverableKeyException) { + Throwable inner2 = inner.getCause(); + if (inner2 instanceof InvalidAlgorithmParameterException) { + System.out.println("...re-trying due to: " + + inner2.getMessage()); + + // Some PBE algorithms demand an 8-byte salt + keystore.setEntry( + "this entry is protected by " + algorithm, + new KeyStore.SecretKeyEntry(key), + new KeyStore.PasswordProtection(ENTRY_PWD, + algorithm, specWithEightByteSalt)); + count++; + + } else if (inner2 instanceof InvalidKeyException) { + System.out.println("...skipping due to: " + + inner2.getMessage()); + // Unsupported crypto keysize + continue; + } + } else { + throw e; + } + } + } + + // Store the PKCS#12 keystore + System.out.println("Storing PKCS#12 keystore to: " + KEYSTORE); + keystore.store(new FileOutputStream(KEYSTORE), KEYSTORE_PWD); + + return count; + } + + private static int recover() throws Exception { + int count = 0; + // Load the PKCS#12 keystore + KeyStore keystore = KeyStore.getInstance("PKCS12"); + System.out.println("\nLoading PKCS#12 keystore from: " + KEYSTORE); + keystore.load(new FileInputStream(KEYSTORE), KEYSTORE_PWD); + + SecretKey key; + SecretKeyFactory factory; + PBEKeySpec keySpec; + + // Retrieve each user password from the keystore + for (String algorithm : PBE_ALGORITHMS) { + key = (SecretKey) keystore.getKey("this entry is protected by " + + algorithm, ENTRY_PWD); + + if (key != null) { + count++; + factory = SecretKeyFactory.getInstance(key.getAlgorithm()); + keySpec = + (PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class); + char[] pwd = keySpec.getPassword(); + System.out.println("Recovered user password '" + + new String(pwd) + "' (protected by " + algorithm + ")"); + + if (!Arrays.equals(USER_PWD, pwd)) { + throw new Exception("Failed to recover the user password " + + "protected by " + algorithm); + } + } + } + + return count; + } +} diff --git a/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh b/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh new file mode 100644 index 00000000000..7347f345878 --- /dev/null +++ b/jdk/test/sun/security/tools/keytool/StorePasswordsByShell.sh @@ -0,0 +1,140 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# @test +# @bug 8008296 +# @summary confirm that keytool correctly imports user passwords +# +# @run shell StorePasswordsByShell.sh + +# set a few environment variables so that the shell-script can run stand-alone +# in the source directory +if [ "${TESTSRC}" = "" ] ; then + TESTSRC="." +fi + +if [ "${TESTCLASSES}" = "" ] ; then + TESTCLASSES="." +fi + +if [ "${TESTJAVA}" = "" ] ; then + echo "TESTJAVA not set. Test cannot execute." + echo "FAILED!!!" + exit 1 +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + SunOS ) + PATHSEP=":" + FILESEP="/" + ;; + Linux ) + PATHSEP=":" + FILESEP="/" + ;; + Darwin ) + PATHSEP=":" + FILESEP="/" + ;; + CYGWIN* ) + PATHSEP=";" + FILESEP="/" + ;; + Windows* ) + PATHSEP=";" + FILESEP="\\" + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + +PBE_ALGORITHMS="\ + default-PBE-algorithm \ + PBEWithMD5AndDES \ + PBEWithSHA1AndDESede \ + PBEWithSHA1AndRC2_40 \ + PBEWithSHA1AndRC2_128 + PBEWithSHA1AndRC4_40 \ + PBEWithSHA1AndRC4_128 \ + PBEWithHmacSHA1AndAES_128 \ + PBEWithHmacSHA224AndAES_128 \ + PBEWithHmacSHA256AndAES_128 \ + PBEWithHmacSHA384AndAES_128 \ + PBEWithHmacSHA512AndAES_128 \ + PBEWithHmacSHA1AndAES_256 \ + PBEWithHmacSHA224AndAES_256 \ + PBEWithHmacSHA256AndAES_256 \ + PBEWithHmacSHA384AndAES_256 \ + PBEWithHmacSHA512AndAES_256" + +USER_PWD="hello1\n" +ALIAS_PREFIX="this entry is protected by " +COUNTER=0 + +# cleanup +rm mykeystore.p12 > /dev/null 2>&1 + +echo +for i in $PBE_ALGORITHMS; do + + if [ $i = "default-PBE-algorithm" ]; then + KEYALG="" + else + KEYALG="-keyalg ${i}" + fi + + if [ $COUNTER -lt 5 ]; then + IMPORTPASSWORD="-importpassword" + else + IMPORTPASSWORD="-importpass" + fi + + echo "Storing user password (protected by ${i})" + echo "${USER_PWD}" | \ + ${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${IMPORTPASSWORD} \ + -storetype pkcs12 -keystore mykeystore.p12 -storepass changeit \ + -alias "${ALIAS_PREFIX}${i}" ${KEYALG} > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo Error + else + echo OK + COUNTER=`expr ${COUNTER} + 1` + fi +done +echo + +COUNTER2=`${TESTJAVA}${FILESEP}bin${FILESEP}keytool -list -storetype pkcs12 \ + -keystore mykeystore.p12 -storepass changeit | grep -c "${ALIAS_PREFIX}"` + +RESULT="stored ${COUNTER} user passwords, detected ${COUNTER2} user passwords" +if [ $COUNTER -ne $COUNTER2 -o $COUNTER -lt 11 ]; then + echo "ERROR: $RESULT" + exit 1 +else + echo "OK: $RESULT" + exit 0 +fi From c76298448522272938ff347e3210da58f90f74dd Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Thu, 29 Aug 2013 20:38:46 +0100 Subject: [PATCH 065/293] 8023764: Optimize Period addition Optimise plus/minus for common cases Reviewed-by: sherman --- jdk/src/share/classes/java/time/LocalDate.java | 10 ++++++++++ jdk/src/share/classes/java/time/LocalDateTime.java | 10 ++++++++++ jdk/src/share/classes/java/time/ZonedDateTime.java | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java index 3005658366a..e2043f9a90d 100644 --- a/jdk/src/share/classes/java/time/LocalDate.java +++ b/jdk/src/share/classes/java/time/LocalDate.java @@ -1125,6 +1125,11 @@ public final class LocalDate */ @Override public LocalDate plus(TemporalAmount amountToAdd) { + Objects.requireNonNull(amountToAdd, "amountToAdd"); + if (amountToAdd instanceof Period) { + Period periodToAdd = (Period) amountToAdd; + return plusMonths(periodToAdd.toTotalMonths()).plusDays(periodToAdd.getDays()); + } return (LocalDate) amountToAdd.addTo(this); } @@ -1353,6 +1358,11 @@ public final class LocalDate */ @Override public LocalDate minus(TemporalAmount amountToSubtract) { + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); + if (amountToSubtract instanceof Period) { + Period periodToSubtract = (Period) amountToSubtract; + return minusMonths(periodToSubtract.toTotalMonths()).minusDays(periodToSubtract.getDays()); + } return (LocalDate) amountToSubtract.subtractFrom(this); } diff --git a/jdk/src/share/classes/java/time/LocalDateTime.java b/jdk/src/share/classes/java/time/LocalDateTime.java index de8b246d6bb..d0b72b90f82 100644 --- a/jdk/src/share/classes/java/time/LocalDateTime.java +++ b/jdk/src/share/classes/java/time/LocalDateTime.java @@ -1129,6 +1129,11 @@ public final class LocalDateTime */ @Override public LocalDateTime plus(TemporalAmount amountToAdd) { + Objects.requireNonNull(amountToAdd, "amountToAdd"); + if (amountToAdd instanceof Period) { + Period periodToAdd = (Period) amountToAdd; + return with(date.plus(periodToAdd), time); + } return (LocalDateTime) amountToAdd.addTo(this); } @@ -1343,6 +1348,11 @@ public final class LocalDateTime */ @Override public LocalDateTime minus(TemporalAmount amountToSubtract) { + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); + if (amountToSubtract instanceof Period) { + Period periodToSubtract = (Period) amountToSubtract; + return with(date.minus(periodToSubtract), time); + } return (LocalDateTime) amountToSubtract.subtractFrom(this); } diff --git a/jdk/src/share/classes/java/time/ZonedDateTime.java b/jdk/src/share/classes/java/time/ZonedDateTime.java index 251ca888a14..971ba6daf5b 100644 --- a/jdk/src/share/classes/java/time/ZonedDateTime.java +++ b/jdk/src/share/classes/java/time/ZonedDateTime.java @@ -1540,6 +1540,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime plus(TemporalAmount amountToAdd) { + Objects.requireNonNull(amountToAdd, "amountToAdd"); + if (amountToAdd instanceof Period) { + Period periodToAdd = (Period) amountToAdd; + return resolveLocal(dateTime.plus(periodToAdd)); + } return (ZonedDateTime) amountToAdd.addTo(this); } @@ -1787,6 +1792,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime minus(TemporalAmount amountToSubtract) { + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); + if (amountToSubtract instanceof Period) { + Period periodToSubtract = (Period) amountToSubtract; + return resolveLocal(dateTime.minus(periodToSubtract)); + } return (ZonedDateTime) amountToSubtract.subtractFrom(this); } From 75fb106fec45102b509deef5eb5efdca67cdbb3f Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Fri, 30 Aug 2013 11:43:57 +0100 Subject: [PATCH 066/293] 8023763: Rename ChronoDateImpl Rename ChronoDateImpl to ChronoLocalDateImpl Reviewed-by: sherman --- .../classes/java/time/chrono/ChronoLocalDate.java | 12 ++++++------ ...hronoDateImpl.java => ChronoLocalDateImpl.java} | 14 +++++++------- .../java/time/chrono/ChronoLocalDateTimeImpl.java | 2 +- .../share/classes/java/time/chrono/HijrahDate.java | 2 +- .../classes/java/time/chrono/JapaneseDate.java | 5 +---- .../share/classes/java/time/chrono/MinguoDate.java | 2 +- .../classes/java/time/chrono/ThaiBuddhistDate.java | 2 +- 7 files changed, 18 insertions(+), 21 deletions(-) rename jdk/src/share/classes/java/time/chrono/{ChronoDateImpl.java => ChronoLocalDateImpl.java} (96%) diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index 923e8960b0f..e02a8cd5392 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -428,7 +428,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate with(TemporalAdjuster adjuster) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -442,7 +442,7 @@ public interface ChronoLocalDate if (field instanceof ChronoField) { throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } - return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); + return ChronoLocalDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); } /** @@ -452,7 +452,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate plus(TemporalAmount amount) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -465,7 +465,7 @@ public interface ChronoLocalDate if (unit instanceof ChronoUnit) { throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); + return ChronoLocalDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); } /** @@ -475,7 +475,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate minus(TemporalAmount amount) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -486,7 +486,7 @@ public interface ChronoLocalDate */ @Override default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) { - return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); + return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java similarity index 96% rename from jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java rename to jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java index 99ba58f05b9..fd8c8f88662 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java @@ -140,7 +140,7 @@ import java.util.Objects; * @param the ChronoLocalDate of this date-time * @since 1.8 */ -abstract class ChronoDateImpl +abstract class ChronoLocalDateImpl implements ChronoLocalDate, Temporal, TemporalAdjuster, Serializable { /** @@ -170,7 +170,7 @@ abstract class ChronoDateImpl /** * Creates an instance. */ - ChronoDateImpl() { + ChronoLocalDateImpl() { } @Override @@ -309,7 +309,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusYears(long yearsToSubtract) { - return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract)); + return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract)); } /** @@ -330,7 +330,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusMonths(long monthsToSubtract) { - return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract)); + return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract)); } /** @@ -350,7 +350,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusWeeks(long weeksToSubtract) { - return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract)); + return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract)); } /** @@ -368,7 +368,7 @@ abstract class ChronoDateImpl */ @SuppressWarnings("unchecked") D minusDays(long daysToSubtract) { - return (daysToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract)); + return (daysToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract)); } //----------------------------------------------------------------------- @@ -411,7 +411,7 @@ abstract class ChronoDateImpl private long monthsUntil(ChronoLocalDate end) { ValueRange range = getChronology().range(MONTH_OF_YEAR); if (range.getMaximum() != 12) { - throw new IllegalStateException("ChronoDateImpl only supports Chronologies with 12 months per year"); + throw new IllegalStateException("ChronoLocalDateImpl only supports Chronologies with 12 months per year"); } long packed1 = getLong(PROLEPTIC_MONTH) * 32L + get(DAY_OF_MONTH); // no overflow long packed2 = end.getLong(PROLEPTIC_MONTH) * 32L + end.get(DAY_OF_MONTH); // no overflow diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index cd7f04e4798..13b3a0e8817 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -220,7 +220,7 @@ final class ChronoLocalDateTimeImpl return this; } // Validate that the new Temporal is a ChronoLocalDate (and not something else) - D cd = ChronoDateImpl.ensureValid(date.getChronology(), newDate); + D cd = ChronoLocalDateImpl.ensureValid(date.getChronology(), newDate); return new ChronoLocalDateTimeImpl<>(cd, newTime); } diff --git a/jdk/src/share/classes/java/time/chrono/HijrahDate.java b/jdk/src/share/classes/java/time/chrono/HijrahDate.java index 8e385c9470b..c0d942396cd 100644 --- a/jdk/src/share/classes/java/time/chrono/HijrahDate.java +++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java @@ -109,7 +109,7 @@ import java.time.temporal.ValueRange; * @since 1.8 */ public final class HijrahDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java index 24ad7a921c0..bc9f473486d 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java @@ -61,10 +61,8 @@ import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; import static java.time.temporal.ChronoField.DAY_OF_MONTH; -import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; -import static java.time.temporal.ChronoField.YEAR_OF_ERA; import java.io.DataInput; import java.io.DataOutput; @@ -76,7 +74,6 @@ import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; import java.time.Period; -import java.time.Year; import java.time.ZoneId; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -119,7 +116,7 @@ import sun.util.calendar.LocalGregorianCalendar; * @since 1.8 */ public final class JapaneseDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** diff --git a/jdk/src/share/classes/java/time/chrono/MinguoDate.java b/jdk/src/share/classes/java/time/chrono/MinguoDate.java index 16585e7e992..fd10e0e985e 100644 --- a/jdk/src/share/classes/java/time/chrono/MinguoDate.java +++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java @@ -96,7 +96,7 @@ import java.util.Objects; * @since 1.8 */ public final class MinguoDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java index 3d8f4078cc9..648793b7337 100644 --- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java +++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java @@ -96,7 +96,7 @@ import java.util.Objects; * @since 1.8 */ public final class ThaiBuddhistDate - extends ChronoDateImpl + extends ChronoLocalDateImpl implements ChronoLocalDate, Serializable { /** From 34d47bd6722ffc6e16a4b74eb5b3bdb134209fe6 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Wed, 4 Sep 2013 08:55:08 -0400 Subject: [PATCH 067/293] 8022798: "assert(seq > 0) failed: counter overflow" in Kitchensink Removed incorrect assertion, sequence number can overflow Reviewed-by: dholmes, kamg --- hotspot/src/share/vm/services/memPtr.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/services/memPtr.cpp b/hotspot/src/share/vm/services/memPtr.cpp index 3e124e2bde2..bc460517c58 100644 --- a/hotspot/src/share/vm/services/memPtr.cpp +++ b/hotspot/src/share/vm/services/memPtr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,9 +34,9 @@ jint SequenceGenerator::next() { jint seq = Atomic::add(1, &_seq_number); if (seq < 0) { MemTracker::shutdown(MemTracker::NMT_sequence_overflow); + } else { + NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;) } - assert(seq > 0, "counter overflow"); - NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;) return seq; } From 61fc7dfe0c702ee5399a453515cc986eae0a7077 Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Wed, 4 Sep 2013 15:18:54 +0100 Subject: [PATCH 068/293] 8023762: Add ChronoPeriod interface and bind period to Chronology Make Period ISO-only, adding a Chronology-specific period concept Reviewed-by: sherman --- .../share/classes/java/time/LocalDate.java | 6 +- jdk/src/share/classes/java/time/Period.java | 198 +++++---- .../java/time/chrono/ChronoLocalDate.java | 12 +- .../java/time/chrono/ChronoPeriod.java | 365 ++++++++++++++++ .../java/time/chrono/ChronoPeriodImpl.java | 399 ++++++++++++++++++ .../classes/java/time/chrono/Chronology.java | 35 +- .../classes/java/time/chrono/HijrahDate.java | 5 +- .../java/time/chrono/IsoChronology.java | 19 + .../java/time/chrono/JapaneseDate.java | 5 +- .../classes/java/time/chrono/MinguoDate.java | 5 +- .../share/classes/java/time/chrono/Ser.java | 5 + .../java/time/chrono/ThaiBuddhistDate.java | 5 +- .../classes/java/time/temporal/Temporal.java | 27 +- .../java/time/tck/java/time/TCKPeriod.java | 111 ++++- .../tck/java/time/chrono/TCKChronoPeriod.java | 279 ++++++++++++ .../time/chrono/TCKJapaneseChronology.java | 10 +- .../java/time/chrono/TCKMinguoChronology.java | 12 +- .../chrono/TCKThaiBuddhistChronology.java | 10 +- .../time/chrono/TestUmmAlQuraChronology.java | 22 +- 19 files changed, 1390 insertions(+), 140 deletions(-) create mode 100644 jdk/src/share/classes/java/time/chrono/ChronoPeriod.java create mode 100644 jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java create mode 100644 jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java index e2043f9a90d..110a80fc9c0 100644 --- a/jdk/src/share/classes/java/time/LocalDate.java +++ b/jdk/src/share/classes/java/time/LocalDate.java @@ -1642,12 +1642,12 @@ public final class LocalDate * * The choice should be made based on which makes the code more readable. * - * @param endDate the end date, exclusive, which may be in any chronology, not null + * @param endDateExclusive the end date, exclusive, which may be in any chronology, not null * @return the period between this date and the end date, not null */ @Override - public Period until(ChronoLocalDate endDate) { - LocalDate end = LocalDate.from(endDate); + public Period until(ChronoLocalDate endDateExclusive) { + LocalDate end = LocalDate.from(endDateExclusive); long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe int days = end.day - this.day; if (totalMonths > 0 && days < 0) { diff --git a/jdk/src/share/classes/java/time/Period.java b/jdk/src/share/classes/java/time/Period.java index 161ce49e565..bd272a9913e 100644 --- a/jdk/src/share/classes/java/time/Period.java +++ b/jdk/src/share/classes/java/time/Period.java @@ -61,7 +61,6 @@ */ package java.time; -import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.MONTHS; import static java.time.temporal.ChronoUnit.YEARS; @@ -70,17 +69,19 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.io.InvalidObjectException; -import java.io.InvalidObjectException; import java.io.Serializable; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; import java.time.chrono.Chronology; +import java.time.chrono.IsoChronology; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalQuery; import java.time.temporal.TemporalUnit; import java.time.temporal.UnsupportedTemporalTypeException; -import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -89,12 +90,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * A date-based amount of time, such as '2 years, 3 months and 4 days'. + * A date-based amount of time in the ISO-8601 calendar system, + * such as '2 years, 3 months and 4 days'. *

* This class models a quantity or amount of time in terms of years, months and days. * See {@link Duration} for the time-based equivalent to this class. *

- * Durations and period differ in their treatment of daylight savings time + * Durations and periods differ in their treatment of daylight savings time * when added to {@link ZonedDateTime}. A {@code Duration} will add an exact * number of seconds, thus a duration of one day is always exactly 24 hours. * By contrast, a {@code Period} will add a conceptual day, trying to maintain @@ -110,14 +112,12 @@ import java.util.regex.Pattern; * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}. * All three fields are always present, but may be set to zero. *

- * The period may be used with any calendar system. - * The meaning of a "year" or "month" is only applied when the object is added to a date. + * The ISO-8601 calendar system is the modern civil calendar system used today + * in most of the world. It is equivalent to the proleptic Gregorian calendar + * system, in which today's rules for leap years are applied for all time. *

* The period is modeled as a directed amount of time, meaning that individual parts of the * period may be negative. - *

- * The months and years fields may be {@linkplain #normalized() normalized}. - * The normalization assumes a 12 month year, so is not appropriate for all calendar systems. * * @implSpec * This class is immutable and thread-safe. @@ -125,7 +125,7 @@ import java.util.regex.Pattern; * @since 1.8 */ public final class Period - implements TemporalAmount, Serializable { + implements ChronoPeriod, Serializable { /** * A constant for a period of zero. @@ -140,6 +140,7 @@ public final class Period */ private final static Pattern PATTERN = Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE); + /** * The set of supported units. */ @@ -234,12 +235,14 @@ public final class Period *

* This obtains a period based on the specified amount. * A {@code TemporalAmount} represents an amount of time, which may be - * date-based or time-based, which this factory extracts to a period. + * date-based or time-based, which this factory extracts to a {@code Period}. *

* The conversion loops around the set of units from the amount and uses * the {@link ChronoUnit#YEARS YEARS}, {@link ChronoUnit#MONTHS MONTHS} * and {@link ChronoUnit#DAYS DAYS} units to create a period. * If any other units are found then an exception is thrown. + *

+ * If the amount is a {@code ChronoPeriod} then it must use the ISO chronology. * * @param amount the temporal amount to convert, not null * @return the equivalent period, not null @@ -247,6 +250,14 @@ public final class Period * @throws ArithmeticException if the amount of years, months or days exceeds an int */ public static Period from(TemporalAmount amount) { + if (amount instanceof Period) { + return (Period) amount; + } + if (amount instanceof ChronoPeriod) { + if (IsoChronology.INSTANCE.equals(((ChronoPeriod) amount).getChronology()) == false) { + throw new DateTimeException("Period requires ISO chronology: " + amount); + } + } Objects.requireNonNull(amount, "amount"); int years = 0; int months = 0; @@ -358,13 +369,13 @@ public final class Period * The result of this method can be a negative period if the end is before the start. * The negative sign will be the same in each of year, month and day. * - * @param startDate the start date, inclusive, not null - * @param endDate the end date, exclusive, not null + * @param startDateInclusive the start date, inclusive, not null + * @param endDateExclusive the end date, exclusive, not null * @return the period between this date and the end date, not null * @see ChronoLocalDate#until(ChronoLocalDate) */ - public static Period between(LocalDate startDate, LocalDate endDate) { - return startDate.until(endDate); + public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive) { + return startDateInclusive.until(endDateExclusive); } //----------------------------------------------------------------------- @@ -439,6 +450,21 @@ public final class Period return SUPPORTED_UNITS; } + /** + * Gets the chronology of this period, which is the ISO calendar system. + *

+ * The {@code Chronology} represents the calendar system in use. + * The ISO-8601 calendar system is the modern civil calendar system used today + * in most of the world. It is equivalent to the proleptic Gregorian calendar + * system, in which today's rules for leap years are applied for all time. + * + * @return the ISO chronology, not null + */ + @Override + public IsoChronology getChronology() { + return IsoChronology.INSTANCE; + } + //----------------------------------------------------------------------- /** * Checks if all three units of this period are zero. @@ -468,7 +494,7 @@ public final class Period *

* This returns the years unit. *

- * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". * @@ -483,7 +509,7 @@ public final class Period *

* This returns the months unit. *

- * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". * @@ -511,7 +537,7 @@ public final class Period * This sets the amount of the years unit in a copy of this period. * The months and days units are unaffected. *

- * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". *

@@ -533,7 +559,7 @@ public final class Period * This sets the amount of the months unit in a copy of this period. * The years and days units are unaffected. *

- * The months unit is not normalized with the years unit. + * The months unit is not automatically normalized with the years unit. * This means that a period of "15 months" is different to a period * of "1 year and 3 months". *

@@ -572,21 +598,28 @@ public final class Period * Returns a copy of this period with the specified period added. *

* This operates separately on the years, months and days. + * No normalization is performed. *

* For example, "1 year, 6 months and 3 days" plus "2 years, 2 months and 2 days" * returns "3 years, 8 months and 5 days". *

+ * The specified amount is typically an instance of {@code Period}. + * Other types are interpreted using {@link Period#from(TemporalAmount)}. + *

* This instance is immutable and unaffected by this method call. * * @param amountToAdd the period to add, not null * @return a {@code Period} based on this period with the requested period added, not null + * @throws DateTimeException if the specified amount has a non-ISO chronology or + * contains an invalid unit * @throws ArithmeticException if numeric overflow occurs */ - public Period plus(Period amountToAdd) { + public Period plus(TemporalAmount amountToAdd) { + Period isoAmount = Period.from(amountToAdd); return create( - Math.addExact(years, amountToAdd.years), - Math.addExact(months, amountToAdd.months), - Math.addExact(days, amountToAdd.days)); + Math.addExact(years, isoAmount.years), + Math.addExact(months, isoAmount.months), + Math.addExact(days, isoAmount.days)); } /** @@ -654,21 +687,28 @@ public final class Period * Returns a copy of this period with the specified period subtracted. *

* This operates separately on the years, months and days. + * No normalization is performed. *

* For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days" * returns "-1 years, 4 months and 1 day". *

+ * The specified amount is typically an instance of {@code Period}. + * Other types are interpreted using {@link Period#from(TemporalAmount)}. + *

* This instance is immutable and unaffected by this method call. * * @param amountToSubtract the period to subtract, not null * @return a {@code Period} based on this period with the requested period subtracted, not null + * @throws DateTimeException if the specified amount has a non-ISO chronology or + * contains an invalid unit * @throws ArithmeticException if numeric overflow occurs */ - public Period minus(Period amountToSubtract) { + public Period minus(TemporalAmount amountToSubtract) { + Period isoAmount = Period.from(amountToSubtract); return create( - Math.subtractExact(years, amountToSubtract.years), - Math.subtractExact(months, amountToSubtract.months), - Math.subtractExact(days, amountToSubtract.days)); + Math.subtractExact(years, isoAmount.years), + Math.subtractExact(months, isoAmount.months), + Math.subtractExact(days, isoAmount.days)); } /** @@ -766,8 +806,7 @@ public final class Period //----------------------------------------------------------------------- /** - * Returns a copy of this period with the years and months normalized - * using a 12 month year. + * Returns a copy of this period with the years and months normalized. *

* This normalizes the years and months units, leaving the days unit unchanged. * The months unit is adjusted to have an absolute value less than 11, @@ -778,8 +817,6 @@ public final class Period * For example, a period of "1 year and -25 months" will be normalized to * "-1 year and -1 month". *

- * This normalization uses a 12 month year which is not valid for all calendar systems. - *

* This instance is immutable and unaffected by this method call. * * @return a {@code Period} based on this period with excess months normalized to years, not null @@ -796,13 +833,11 @@ public final class Period } /** - * Gets the total number of months in this period using a 12 month year. + * Gets the total number of months in this period. *

* This returns the total number of months in the period by multiplying the * number of years by 12 and adding the number of months. *

- * This uses a 12 month year which is not valid for all calendar systems. - *

* This instance is immutable and unaffected by this method call. * * @return the total number of months in the period, may be negative @@ -817,6 +852,7 @@ public final class Period *

* This returns a temporal object of the same observable type as the input * with this period added. + * If the temporal has a chronology, it must be the ISO chronology. *

* In most cases, it is clearer to reverse the calling pattern by using * {@link Temporal#plus(TemporalAmount)}. @@ -826,10 +862,17 @@ public final class Period * dateTime = dateTime.plus(thisPeriod); * *

- * The calculation will add the years, then months, then days. - * Only non-zero amounts will be added. - * If the date-time has a calendar system with a fixed number of months in a - * year, then the years and months will be combined before being added. + * The calculation operates as follows. + * First, the chronology of the temporal is checked to ensure it is ISO chronology or null. + * Second, if the months are zero, the years are added if non-zero, otherwise + * the combination of years and months is added if non-zero. + * Finally, any days are added. + *

+ * This approach ensures that a partial period can be added to a partial date. + * For example, a period of years and/or months can be added to a {@code YearMonth}, + * but a period including days cannot. + * The approach also adds years and months together when necessary, which ensures + * correct behaviour at the end of the month. *

* This instance is immutable and unaffected by this method call. * @@ -840,18 +883,15 @@ public final class Period */ @Override public Temporal addTo(Temporal temporal) { - Objects.requireNonNull(temporal, "temporal"); - if ((years | months) != 0) { - long monthRange = monthRange(temporal); - if (monthRange >= 0) { - temporal = temporal.plus(years * monthRange + months, MONTHS); - } else { - if (years != 0) { - temporal = temporal.plus(years, YEARS); - } - if (months != 0) { - temporal = temporal.plus(months, MONTHS); - } + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.plus(years, YEARS); + } + } else { + long totalMonths = toTotalMonths(); + if (totalMonths != 0) { + temporal = temporal.plus(totalMonths, MONTHS); } } if (days != 0) { @@ -865,6 +905,7 @@ public final class Period *

* This returns a temporal object of the same observable type as the input * with this period subtracted. + * If the temporal has a chronology, it must be the ISO chronology. *

* In most cases, it is clearer to reverse the calling pattern by using * {@link Temporal#minus(TemporalAmount)}. @@ -874,10 +915,17 @@ public final class Period * dateTime = dateTime.minus(thisPeriod); * *

- * The calculation will subtract the years, then months, then days. - * Only non-zero amounts will be subtracted. - * If the date-time has a calendar system with a fixed number of months in a - * year, then the years and months will be combined before being subtracted. + * The calculation operates as follows. + * First, the chronology of the temporal is checked to ensure it is ISO chronology or null. + * Second, if the months are zero, the years are subtracted if non-zero, otherwise + * the combination of years and months is subtracted if non-zero. + * Finally, any days are subtracted. + *

+ * This approach ensures that a partial period can be subtracted from a partial date. + * For example, a period of years and/or months can be subtracted from a {@code YearMonth}, + * but a period including days cannot. + * The approach also subtracts years and months together when necessary, which ensures + * correct behaviour at the end of the month. *

* This instance is immutable and unaffected by this method call. * @@ -888,18 +936,15 @@ public final class Period */ @Override public Temporal subtractFrom(Temporal temporal) { - Objects.requireNonNull(temporal, "temporal"); - if ((years | months) != 0) { - long monthRange = monthRange(temporal); - if (monthRange >= 0) { - temporal = temporal.minus(years * monthRange + months, MONTHS); - } else { - if (years != 0) { - temporal = temporal.minus(years, YEARS); - } - if (months != 0) { - temporal = temporal.minus(months, MONTHS); - } + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.minus(years, YEARS); + } + } else { + long totalMonths = toTotalMonths(); + if (totalMonths != 0) { + temporal = temporal.minus(totalMonths, MONTHS); } } if (days != 0) { @@ -909,26 +954,21 @@ public final class Period } /** - * Calculates the range of months based on the temporal. - * - * @param temporal the temporal, not null - * @return the month range, negative if not fixed range + * Validates that the temporal has the correct chronology. */ - private long monthRange(Temporal temporal) { - if (temporal.isSupported(MONTH_OF_YEAR)) { - ValueRange startRange = Chronology.from(temporal).range(MONTH_OF_YEAR); - if (startRange.isFixed() && startRange.isIntValue()) { - return startRange.getMaximum() - startRange.getMinimum() + 1; - } + private void validateChrono(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); + Chronology temporalChrono = temporal.query(TemporalQuery.chronology()); + if (temporalChrono != null && IsoChronology.INSTANCE.equals(temporalChrono) == false) { + throw new DateTimeException("Chronology mismatch, expected: ISO, actual: " + temporalChrono.getId()); } - return -1; } //----------------------------------------------------------------------- /** * Checks if this period is equal to another period. *

- * The comparison is based on the amounts held in the period. + * The comparison is based on the type {@code Period} and each of the three amounts. * To be equal, the years, months and days units must be individually equal. * Note that this means that a period of "15 Months" is not equal to a period * of "1 Year and 3 Months". diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index e02a8cd5392..58ae3b8c1c5 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -69,7 +69,6 @@ import static java.time.temporal.ChronoUnit.DAYS; import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; -import java.time.Period; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; @@ -602,9 +601,12 @@ public interface ChronoLocalDate long until(Temporal endDate, TemporalUnit unit); /** - * Calculates the period between this date and another date as a {@code Period}. + * Calculates the period between this date and another date as a {@code ChronoPeriod}. + *

+ * This calculates the period between two dates. All supplied chronologies + * calculate the period using years, months and days, however the + * {@code ChronoPeriod} API allows the period to be represented using other units. *

- * This calculates the period between two dates in terms of years, months and days. * The start and end points are {@code this} and the specified date. * The result will be negative if the end is before the start. * The negative sign will be the same in each of year, month and day. @@ -614,12 +616,12 @@ public interface ChronoLocalDate *

* This instance is immutable and unaffected by this method call. * - * @param endDate the end date, exclusive, which may be in any chronology, not null + * @param endDateExclusive the end date, exclusive, which may be in any chronology, not null * @return the period between this date and the end date, not null * @throws DateTimeException if the period cannot be calculated * @throws ArithmeticException if numeric overflow occurs */ - Period until(ChronoLocalDate endDate); + ChronoPeriod until(ChronoLocalDate endDateExclusive); /** * Formats this date using the specified formatter. diff --git a/jdk/src/share/classes/java/time/chrono/ChronoPeriod.java b/jdk/src/share/classes/java/time/chrono/ChronoPeriod.java new file mode 100644 index 00000000000..0ac1d395143 --- /dev/null +++ b/jdk/src/share/classes/java/time/chrono/ChronoPeriod.java @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2013, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package java.time.chrono; + +import java.time.DateTimeException; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalUnit; +import java.time.temporal.UnsupportedTemporalTypeException; +import java.util.List; +import java.util.Objects; + +/** + * A date-based amount of time, such as '3 years, 4 months and 5 days' in an + * arbitrary chronology, intended for advanced globalization use cases. + *

+ * This interface models a date-based amount of time in a calendar system. + * While most calendar systems use years, months and days, some do not. + * Therefore, this interface operates solely in terms of a set of supported + * units that are defined by the {@code Chronology}. + * The set of supported units is fixed for a given chronology. + * The amount of a supported unit may be set to zero. + *

+ * The period is modeled as a directed amount of time, meaning that individual + * parts of the period may be negative. + * + * @implSpec + * This interface must be implemented with care to ensure other classes operate correctly. + * All implementations that can be instantiated must be final, immutable and thread-safe. + * Subclasses should be Serializable wherever possible. + * + * @since 1.8 + */ +public interface ChronoPeriod + extends TemporalAmount { + + /** + * Obtains a {@code ChronoPeriod} consisting of amount of time between two dates. + *

+ * The start date is included, but the end date is not. + * The period is calculated using {@link ChronoLocalDate#until(ChronoLocalDate)}. + * As such, the calculation is chronology specific. + *

+ * The chronology of the first date is used. + * The chronology of the second date is ignored, with the date being converted + * to the target chronology system before the calculation starts. + *

+ * The result of this method can be a negative period if the end is before the start. + * In most cases, the positive/negative sign will be the same in each of the supported fields. + * + * @param startDateInclusive the start date, inclusive, specifying the chronology of the calculation, not null + * @param endDateExclusive the end date, exclusive, in any chronology, not null + * @return the period between this date and the end date, not null + * @see ChronoLocalDate#until(ChronoLocalDate) + */ + public static ChronoPeriod between(ChronoLocalDate startDateInclusive, ChronoLocalDate endDateExclusive) { + Objects.requireNonNull(startDateInclusive, "startDateInclusive"); + Objects.requireNonNull(endDateExclusive, "endDateExclusive"); + return startDateInclusive.until(endDateExclusive); + } + + //----------------------------------------------------------------------- + /** + * Gets the value of the requested unit. + *

+ * The supported units are chronology specific. + * They will typically be {@link ChronoUnit#YEARS YEARS}, + * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}. + * Requesting an unsupported unit will throw an exception. + * + * @param unit the {@code TemporalUnit} for which to return the value + * @return the long value of the unit + * @throws DateTimeException if the unit is not supported + * @throws UnsupportedTemporalTypeException if the unit is not supported + */ + @Override + long get(TemporalUnit unit); + + /** + * Gets the set of units supported by this period. + *

+ * The supported units are chronology specific. + * They will typically be {@link ChronoUnit#YEARS YEARS}, + * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}. + * They are returned in order from largest to smallest. + *

+ * This set can be used in conjunction with {@link #get(TemporalUnit)} + * to access the entire state of the period. + * + * @return a list containing the supported units, not null + */ + @Override + List getUnits(); + + /** + * Gets the chronology that defines the meaning of the supported units. + *

+ * The period is defined by the chronology. + * It controls the supported units and restricts addition/subtraction + * to {@code ChronoLocalDate} instances of the same chronology. + * + * @return the chronology defining the period, not null + */ + Chronology getChronology(); + + //----------------------------------------------------------------------- + /** + * Checks if all the supported units of this period are zero. + * + * @return true if this period is zero-length + */ + default boolean isZero() { + for (TemporalUnit unit : getUnits()) { + if (get(unit) != 0) { + return false; + } + } + return true; + } + + /** + * Checks if any of the supported units of this period are negative. + * + * @return true if any unit of this period is negative + */ + default boolean isNegative() { + for (TemporalUnit unit : getUnits()) { + if (get(unit) < 0) { + return true; + } + } + return false; + } + + //----------------------------------------------------------------------- + /** + * Returns a copy of this period with the specified period added. + *

+ * If the specified amount is a {@code ChronoPeriod} then it must have + * the same chronology as this period. Implementations may choose to + * accept or reject other {@code TemporalAmount} implementations. + *

+ * This instance is immutable and unaffected by this method call. + * + * @param amountToAdd the period to add, not null + * @return a {@code ChronoPeriod} based on this period with the requested period added, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod plus(TemporalAmount amountToAdd); + + /** + * Returns a copy of this period with the specified period subtracted. + *

+ * If the specified amount is a {@code ChronoPeriod} then it must have + * the same chronology as this period. Implementations may choose to + * accept or reject other {@code TemporalAmount} implementations. + *

+ * This instance is immutable and unaffected by this method call. + * + * @param amountToSubtract the period to subtract, not null + * @return a {@code ChronoPeriod} based on this period with the requested period subtracted, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod minus(TemporalAmount amountToSubtract); + + //----------------------------------------------------------------------- + /** + * Returns a new instance with each amount in this period in this period + * multiplied by the specified scalar. + *

+ * This returns a period with each supported unit individually multiplied. + * For example, a period of "2 years, -3 months and 4 days" multiplied by + * 3 will return "6 years, -9 months and 12 days". + * No normalization is performed. + * + * @param scalar the scalar to multiply by, not null + * @return a {@code ChronoPeriod} based on this period with the amounts multiplied + * by the scalar, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod multipliedBy(int scalar); + + /** + * Returns a new instance with each amount in this period negated. + *

+ * This returns a period with each supported unit individually negated. + * For example, a period of "2 years, -3 months and 4 days" will be + * negated to "-2 years, 3 months and -4 days". + * No normalization is performed. + * + * @return a {@code ChronoPeriod} based on this period with the amounts negated, not null + * @throws ArithmeticException if numeric overflow occurs, which only happens if + * one of the units has the value {@code Long.MIN_VALUE} + */ + default ChronoPeriod negated() { + return multipliedBy(-1); + } + + //----------------------------------------------------------------------- + /** + * Returns a copy of this period with the amounts of each unit normalized. + *

+ * The process of normalization is specific to each calendar system. + * For example, in the ISO calendar system, the years and months are + * normalized but the days are not, such that "15 months" would be + * normalized to "1 year and 3 months". + *

+ * This instance is immutable and unaffected by this method call. + * + * @return a {@code ChronoPeriod} based on this period with the amounts of each + * unit normalized, not null + * @throws ArithmeticException if numeric overflow occurs + */ + ChronoPeriod normalized(); + + //------------------------------------------------------------------------- + /** + * Adds this period to the specified temporal object. + *

+ * This returns a temporal object of the same observable type as the input + * with this period added. + *

+ * In most cases, it is clearer to reverse the calling pattern by using + * {@link Temporal#plus(TemporalAmount)}. + *

+     *   // these two lines are equivalent, but the second approach is recommended
+     *   dateTime = thisPeriod.addTo(dateTime);
+     *   dateTime = dateTime.plus(thisPeriod);
+     * 
+ *

+ * The specified temporal must have the same chronology as this period. + * This returns a temporal with the non-zero supported units added. + *

+ * This instance is immutable and unaffected by this method call. + * + * @param temporal the temporal object to adjust, not null + * @return an object of the same type with the adjustment made, not null + * @throws DateTimeException if unable to add + * @throws ArithmeticException if numeric overflow occurs + */ + @Override + Temporal addTo(Temporal temporal); + + /** + * Subtracts this period from the specified temporal object. + *

+ * This returns a temporal object of the same observable type as the input + * with this period subtracted. + *

+ * In most cases, it is clearer to reverse the calling pattern by using + * {@link Temporal#minus(TemporalAmount)}. + *

+     *   // these two lines are equivalent, but the second approach is recommended
+     *   dateTime = thisPeriod.subtractFrom(dateTime);
+     *   dateTime = dateTime.minus(thisPeriod);
+     * 
+ *

+ * The specified temporal must have the same chronology as this period. + * This returns a temporal with the non-zero supported units subtracted. + *

+ * This instance is immutable and unaffected by this method call. + * + * @param temporal the temporal object to adjust, not null + * @return an object of the same type with the adjustment made, not null + * @throws DateTimeException if unable to subtract + * @throws ArithmeticException if numeric overflow occurs + */ + @Override + Temporal subtractFrom(Temporal temporal); + + //----------------------------------------------------------------------- + /** + * Checks if this period is equal to another period, including the chronology. + *

+ * Compares this period with another ensuring that the type, each amount and + * the chronology are the same. + * Note that this means that a period of "15 Months" is not equal to a period + * of "1 Year and 3 Months". + * + * @param obj the object to check, null returns false + * @return true if this is equal to the other period + */ + @Override + boolean equals(Object obj); + + /** + * A hash code for this period. + * + * @return a suitable hash code + */ + @Override + int hashCode(); + + //----------------------------------------------------------------------- + /** + * Outputs this period as a {@code String}. + *

+ * The output will include the period amounts and chronology. + * + * @return a string representation of this period, not null + */ + @Override + String toString(); + +} diff --git a/jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java new file mode 100644 index 00000000000..d301adb2d03 --- /dev/null +++ b/jdk/src/share/classes/java/time/chrono/ChronoPeriodImpl.java @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2013, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package java.time.chrono; + +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.YEARS; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.time.DateTimeException; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; +import java.time.temporal.UnsupportedTemporalTypeException; +import java.time.temporal.ValueRange; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * A period expressed in terms of a standard year-month-day calendar system. + *

+ * This class is used by applications seeking to handle dates in non-ISO calendar systems. + * For example, the Japanese, Minguo, Thai Buddhist and others. + * + * @implSpec + * This class is immutable nad thread-safe. + * + * @since 1.8 + */ +final class ChronoPeriodImpl + implements ChronoPeriod, Serializable { + // this class is only used by JDK chronology implementations and makes assumptions based on that fact + + /** + * Serialization version. + */ + private static final long serialVersionUID = 57387258289L; + + /** + * The set of supported units. + */ + private final static List SUPPORTED_UNITS = + Collections.unmodifiableList(Arrays.asList(YEARS, MONTHS, DAYS)); + + /** + * The chronology. + */ + private final Chronology chrono; + /** + * The number of years. + */ + final int years; + /** + * The number of months. + */ + final int months; + /** + * The number of days. + */ + final int days; + + /** + * Creates an instance. + */ + ChronoPeriodImpl(Chronology chrono, int years, int months, int days) { + Objects.requireNonNull(chrono, "chrono"); + this.chrono = chrono; + this.years = years; + this.months = months; + this.days = days; + } + + //----------------------------------------------------------------------- + @Override + public long get(TemporalUnit unit) { + if (unit == ChronoUnit.YEARS) { + return years; + } else if (unit == ChronoUnit.MONTHS) { + return months; + } else if (unit == ChronoUnit.DAYS) { + return days; + } else { + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); + } + } + + @Override + public List getUnits() { + return ChronoPeriodImpl.SUPPORTED_UNITS; + } + + @Override + public Chronology getChronology() { + return chrono; + } + + //----------------------------------------------------------------------- + @Override + public boolean isZero() { + return years == 0 && months == 0 && days == 0; + } + + @Override + public boolean isNegative() { + return years < 0 || months < 0 || days < 0; + } + + //----------------------------------------------------------------------- + @Override + public ChronoPeriod plus(TemporalAmount amountToAdd) { + ChronoPeriodImpl amount = validateAmount(amountToAdd); + return new ChronoPeriodImpl( + chrono, + Math.addExact(years, amount.years), + Math.addExact(months, amount.months), + Math.addExact(days, amount.days)); + } + + @Override + public ChronoPeriod minus(TemporalAmount amountToSubtract) { + ChronoPeriodImpl amount = validateAmount(amountToSubtract); + return new ChronoPeriodImpl( + chrono, + Math.subtractExact(years, amount.years), + Math.subtractExact(months, amount.months), + Math.subtractExact(days, amount.days)); + } + + /** + * Obtains an instance of {@code ChronoPeriodImpl} from a temporal amount. + * + * @param amount the temporal amount to convert, not null + * @return the period, not null + */ + private ChronoPeriodImpl validateAmount(TemporalAmount amount) { + Objects.requireNonNull(amount, "amount"); + if (amount instanceof ChronoPeriodImpl == false) { + throw new DateTimeException("Unable to obtain ChronoPeriod from TemporalAmount: " + amount.getClass()); + } + ChronoPeriodImpl period = (ChronoPeriodImpl) amount; + if (chrono.equals(period.getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + period.getChronology().getId()); + } + return period; + } + + //----------------------------------------------------------------------- + @Override + public ChronoPeriod multipliedBy(int scalar) { + if (this.isZero() || scalar == 1) { + return this; + } + return new ChronoPeriodImpl( + chrono, + Math.multiplyExact(years, scalar), + Math.multiplyExact(months, scalar), + Math.multiplyExact(days, scalar)); + } + + //----------------------------------------------------------------------- + @Override + public ChronoPeriod normalized() { + long monthRange = monthRange(); + if (monthRange > 0) { + long totalMonths = years * monthRange + months; + long splitYears = totalMonths / monthRange; + int splitMonths = (int) (totalMonths % monthRange); // no overflow + if (splitYears == years && splitMonths == months) { + return this; + } + return new ChronoPeriodImpl(chrono, Math.toIntExact(splitYears), splitMonths, days); + + } + return this; + } + + /** + * Calculates the range of months. + * + * @return the month range, -1 if not fixed range + */ + private long monthRange() { + ValueRange startRange = chrono.range(MONTH_OF_YEAR); + if (startRange.isFixed() && startRange.isIntValue()) { + return startRange.getMaximum() - startRange.getMinimum() + 1; + } + return -1; + } + + //------------------------------------------------------------------------- + @Override + public Temporal addTo(Temporal temporal) { + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.plus(years, YEARS); + } + } else { + long monthRange = monthRange(); + if (monthRange > 0) { + temporal = temporal.plus(years * monthRange + months, MONTHS); + } else { + if (years != 0) { + temporal = temporal.plus(years, YEARS); + } + temporal = temporal.plus(months, MONTHS); + } + } + if (days != 0) { + temporal = temporal.plus(days, DAYS); + } + return temporal; + } + + + + @Override + public Temporal subtractFrom(Temporal temporal) { + validateChrono(temporal); + if (months == 0) { + if (years != 0) { + temporal = temporal.minus(years, YEARS); + } + } else { + long monthRange = monthRange(); + if (monthRange > 0) { + temporal = temporal.minus(years * monthRange + months, MONTHS); + } else { + if (years != 0) { + temporal = temporal.minus(years, YEARS); + } + temporal = temporal.minus(months, MONTHS); + } + } + if (days != 0) { + temporal = temporal.minus(days, DAYS); + } + return temporal; + } + + /** + * Validates that the temporal has the correct chronology. + */ + private void validateChrono(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); + Chronology temporalChrono = temporal.query(TemporalQuery.chronology()); + if (temporalChrono != null && chrono.equals(temporalChrono) == false) { + throw new DateTimeException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + temporalChrono.getId()); + } + } + + //----------------------------------------------------------------------- + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ChronoPeriodImpl) { + ChronoPeriodImpl other = (ChronoPeriodImpl) obj; + return years == other.years && months == other.months && + days == other.days && chrono.equals(other.chrono); + } + return false; + } + + @Override + public int hashCode() { + return (years + Integer.rotateLeft(months, 8) + Integer.rotateLeft(days, 16)) ^ chrono.hashCode(); + } + + //----------------------------------------------------------------------- + @Override + public String toString() { + if (isZero()) { + return getChronology().toString() + " P0D"; + } else { + StringBuilder buf = new StringBuilder(); + buf.append(getChronology().toString()).append(' ').append('P'); + if (years != 0) { + buf.append(years).append('Y'); + } + if (months != 0) { + buf.append(months).append('M'); + } + if (days != 0) { + buf.append(days).append('D'); + } + return buf.toString(); + } + } + + //----------------------------------------------------------------------- + /** + * Writes the Chronology using a + * dedicated serialized form. + *

+     *  out.writeByte(12);  // identifies this as a ChronoPeriodImpl
+     *  out.writeUTF(getId());  // the chronology
+     *  out.writeInt(years);
+     *  out.writeInt(months);
+     *  out.writeInt(days);
+     * 
+ * + * @return the instance of {@code Ser}, not null + */ + protected Object writeReplace() { + return new Ser(Ser.CHRONO_PERIOD_TYPE, this); + } + + /** + * Defend against malicious streams. + * @return never + * @throws InvalidObjectException always + */ + private Object readResolve() throws ObjectStreamException { + throw new InvalidObjectException("Deserialization via serialization delegate"); + } + + void writeExternal(DataOutput out) throws IOException { + out.writeUTF(chrono.getId()); + out.writeInt(years); + out.writeInt(months); + out.writeInt(days); + } + + static ChronoPeriodImpl readExternal(DataInput in) throws IOException { + Chronology chrono = Chronology.of(in.readUTF()); + int years = in.readInt(); + int months = in.readInt(); + int days = in.readInt(); + return new ChronoPeriodImpl(chrono, years, months, days); + } + +} diff --git a/jdk/src/share/classes/java/time/chrono/Chronology.java b/jdk/src/share/classes/java/time/chrono/Chronology.java index 36c9d31c3fd..ed40f4138f0 100644 --- a/jdk/src/share/classes/java/time/chrono/Chronology.java +++ b/jdk/src/share/classes/java/time/chrono/Chronology.java @@ -91,14 +91,11 @@ import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; -import java.time.Month; -import java.time.Year; import java.time.ZoneId; import java.time.format.DateTimeFormatterBuilder; import java.time.format.ResolverStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; -import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; @@ -1190,6 +1187,38 @@ public abstract class Chronology implements Comparable { fieldValues.put(field, value); } + //----------------------------------------------------------------------- + /** + * Obtains a period for this chronology based on years, months and days. + *

+ * This returns a period tied to this chronology using the specified + * years, months and days. All supplied chronologies use periods + * based on years, months and days, however the {@code ChronoPeriod} API + * allows the period to be represented using other units. + * + * @implSpec + * The default implementation returns an implementation class suitable + * for most calendar systems. It is based solely on the three units. + * Normalization, addition and subtraction derive the number of months + * in a year from the {@link #range(ChronoField)}. If the number of + * months within a year is fixed, then the calculation approach for + * addition, subtraction and normalization is slightly different. + *

+ * If implementing an unusual calendar system that is not based on + * years, months and days, or where you want direct control, then + * the {@code ChronoPeriod} interface must be directly implemented. + *

+ * The returned period is immutable and thread-safe. + * + * @param years the number of years, may be negative + * @param months the number of years, may be negative + * @param days the number of years, may be negative + * @return the period in terms of this chronology, not null + */ + public ChronoPeriod period(int years, int months, int days) { + return new ChronoPeriodImpl(this, years, months, days); + } + //----------------------------------------------------------------------- /** * Compares this chronology to another chronology. diff --git a/jdk/src/share/classes/java/time/chrono/HijrahDate.java b/jdk/src/share/classes/java/time/chrono/HijrahDate.java index c0d942396cd..d2c9929316c 100644 --- a/jdk/src/share/classes/java/time/chrono/HijrahDate.java +++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java @@ -73,7 +73,6 @@ import java.time.Clock; import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalTime; -import java.time.Period; import java.time.ZoneId; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -582,7 +581,7 @@ public final class HijrahDate } @Override - public Period until(ChronoLocalDate endDate) { + public ChronoPeriod until(ChronoLocalDate endDate) { // TODO: untested HijrahDate end = getChronology().date(endDate); long totalMonths = (end.prolepticYear - this.prolepticYear) * 12 + (end.monthOfYear - this.monthOfYear); // safe @@ -597,7 +596,7 @@ public final class HijrahDate } long years = totalMonths / 12; // safe int months = (int) (totalMonths % 12); // safe - return Period.of(Math.toIntExact(years), months, days); + return getChronology().period(Math.toIntExact(years), months, days); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/IsoChronology.java b/jdk/src/share/classes/java/time/chrono/IsoChronology.java index 2012e64e04d..9638f6eea4f 100644 --- a/jdk/src/share/classes/java/time/chrono/IsoChronology.java +++ b/jdk/src/share/classes/java/time/chrono/IsoChronology.java @@ -77,6 +77,7 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Month; +import java.time.Period; import java.time.Year; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -565,6 +566,24 @@ public final class IsoChronology extends Chronology implements Serializable { return field.range(); } + //----------------------------------------------------------------------- + /** + * Obtains a period for this chronology based on years, months and days. + *

+ * This returns a period tied to the ISO chronology using the specified + * years, months and days. See {@link Period} for further details. + * + * @param years the number of years, may be negative + * @param months the number of years, may be negative + * @param days the number of years, may be negative + * @return the period in terms of this chronology, not null + * @return the ISO period, not null + */ + @Override // override with covariant return type + public Period period(int years, int months, int days) { + return Period.of(years, months, days); + } + //----------------------------------------------------------------------- /** * Writes the Chronology using a diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java index bc9f473486d..ae4708dbaff 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java @@ -659,8 +659,9 @@ public final class JapaneseDate } @Override - public Period until(ChronoLocalDate endDate) { - return isoDate.until(endDate); + public ChronoPeriod until(ChronoLocalDate endDate) { + Period period = isoDate.until(endDate); + return getChronology().period(period.getYears(), period.getMonths(), period.getDays()); } @Override // override for performance diff --git a/jdk/src/share/classes/java/time/chrono/MinguoDate.java b/jdk/src/share/classes/java/time/chrono/MinguoDate.java index fd10e0e985e..42e0dab0da5 100644 --- a/jdk/src/share/classes/java/time/chrono/MinguoDate.java +++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java @@ -421,8 +421,9 @@ public final class MinguoDate } @Override - public Period until(ChronoLocalDate endDate) { - return isoDate.until(endDate); + public ChronoPeriod until(ChronoLocalDate endDate) { + Period period = isoDate.until(endDate); + return getChronology().period(period.getYears(), period.getMonths(), period.getDays()); } @Override // override for performance diff --git a/jdk/src/share/classes/java/time/chrono/Ser.java b/jdk/src/share/classes/java/time/chrono/Ser.java index cc99f481f8c..5a4e3c12623 100644 --- a/jdk/src/share/classes/java/time/chrono/Ser.java +++ b/jdk/src/share/classes/java/time/chrono/Ser.java @@ -104,6 +104,7 @@ final class Ser implements Externalizable { static final byte HIJRAH_DATE_TYPE = 6; static final byte MINGUO_DATE_TYPE = 7; static final byte THAIBUDDHIST_DATE_TYPE = 8; + static final byte CHRONO_PERIOD_TYPE = 9; /** The type being serialized. */ private byte type; @@ -183,6 +184,9 @@ final class Ser implements Externalizable { case THAIBUDDHIST_DATE_TYPE: ((ThaiBuddhistDate) object).writeExternal(out); break; + case CHRONO_PERIOD_TYPE: + ((ChronoPeriodImpl) object).writeExternal(out); + break; default: throw new InvalidClassException("Unknown serialized type"); } @@ -235,6 +239,7 @@ final class Ser implements Externalizable { case HIJRAH_DATE_TYPE: return HijrahDate.readExternal(in); case MINGUO_DATE_TYPE: return MinguoDate.readExternal(in); case THAIBUDDHIST_DATE_TYPE: return ThaiBuddhistDate.readExternal(in); + case CHRONO_PERIOD_TYPE: return ChronoPeriodImpl.readExternal(in); default: throw new StreamCorruptedException("Unknown serialized type"); } } diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java index 648793b7337..89895c8ac48 100644 --- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java +++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java @@ -421,8 +421,9 @@ public final class ThaiBuddhistDate } @Override - public Period until(ChronoLocalDate endDate) { - return isoDate.until(endDate); + public ChronoPeriod until(ChronoLocalDate endDate) { + Period period = isoDate.until(endDate); + return getChronology().period(period.getYears(), period.getMonths(), period.getDays()); } @Override // override for performance diff --git a/jdk/src/share/classes/java/time/temporal/Temporal.java b/jdk/src/share/classes/java/time/temporal/Temporal.java index af8424c1560..54110bed771 100644 --- a/jdk/src/share/classes/java/time/temporal/Temporal.java +++ b/jdk/src/share/classes/java/time/temporal/Temporal.java @@ -170,7 +170,8 @@ public interface Temporal extends TemporalAccessor { * * * @implSpec - * Implementations must not alter either this object. + *

+ * Implementations must not alter either this object or the specified temporal object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

@@ -209,7 +210,7 @@ public interface Temporal extends TemporalAccessor { * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)} * passing {@code this} as the first argument. *

- * Implementations must not alter either this object or the specified temporal object. + * Implementations must not alter this object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. * @@ -232,16 +233,17 @@ public interface Temporal extends TemporalAccessor { *

* Some example code indicating how and why this method is used: *

-     *  date = date.plus(period);                      // add a Period instance
-     *  date = date.plus(duration);                    // add a Duration instance
-     *  date = date.plus(workingDays(6));              // example user-written workingDays method
+     *  date = date.plus(period);                // add a Period instance
+     *  date = date.plus(duration);              // add a Duration instance
+     *  date = date.plus(workingDays(6));        // example user-written workingDays method
      * 
*

* Note that calling {@code plus} followed by {@code minus} is not guaranteed to * return the same date-time. * * @implSpec - * Implementations must not alter either this object. + *

+ * Implementations must not alter either this object or the specified temporal object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

@@ -280,7 +282,7 @@ public interface Temporal extends TemporalAccessor { * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)} * passing {@code this} as the first argument. *

- * Implementations must not alter either this object or the specified temporal object. + * Implementations must not alter this object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. * @@ -303,16 +305,17 @@ public interface Temporal extends TemporalAccessor { *

* Some example code indicating how and why this method is used: *

-     *  date = date.minus(period);                      // subtract a Period instance
-     *  date = date.minus(duration);                    // subtract a Duration instance
-     *  date = date.minus(workingDays(6));              // example user-written workingDays method
+     *  date = date.minus(period);               // subtract a Period instance
+     *  date = date.minus(duration);             // subtract a Duration instance
+     *  date = date.minus(workingDays(6));       // example user-written workingDays method
      * 
*

* Note that calling {@code plus} followed by {@code minus} is not guaranteed to * return the same date-time. * * @implSpec - * Implementations must not alter either this object. + *

+ * Implementations must not alter either this object or the specified temporal object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

@@ -345,7 +348,7 @@ public interface Temporal extends TemporalAccessor { * @implSpec * Implementations must behave in a manor equivalent to the default method behavior. *

- * Implementations must not alter either this object or the specified temporal object. + * Implementations must not alter this object. * Instead, an adjusted copy of the original must be returned. * This provides equivalent, safe behavior for immutable and mutable implementations. *

diff --git a/jdk/test/java/time/tck/java/time/TCKPeriod.java b/jdk/test/java/time/tck/java/time/TCKPeriod.java index 3a1fe42ec45..7743512002f 100644 --- a/jdk/test/java/time/tck/java/time/TCKPeriod.java +++ b/jdk/test/java/time/tck/java/time/TCKPeriod.java @@ -60,6 +60,7 @@ package tck.java.time; import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.YEARS; import static org.testng.Assert.assertEquals; @@ -67,6 +68,7 @@ import java.time.DateTimeException; import java.time.Duration; import java.time.LocalDate; import java.time.Period; +import java.time.chrono.ThaiBuddhistChronology; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; @@ -212,6 +214,41 @@ public class TCKPeriod extends AbstractTCKTest { Period.from(amount); } + @Test(expectedExceptions = DateTimeException.class) + public void factory_from_TemporalAmount_DaysHours() { + TemporalAmount amount = new TemporalAmount() { + @Override + public long get(TemporalUnit unit) { + if (unit == DAYS) { + return 1; + } else { + return 2; + } + } + @Override + public List getUnits() { + List list = new ArrayList<>(); + list.add(DAYS); + list.add(HOURS); + return list; + } + @Override + public Temporal addTo(Temporal temporal) { + throw new UnsupportedOperationException(); + } + @Override + public Temporal subtractFrom(Temporal temporal) { + throw new UnsupportedOperationException(); + } + }; + Period.from(amount); + } + + @Test(expectedExceptions = DateTimeException.class) + public void factory_from_TemporalAmount_NonISO() { + Period.from(ThaiBuddhistChronology.INSTANCE.period(1, 1, 1)); + } + @Test(expectedExceptions = DateTimeException.class) public void factory_from_TemporalAmount_Duration() { Period.from(Duration.ZERO); @@ -594,10 +631,45 @@ public class TCKPeriod extends AbstractTCKTest { } @Test(dataProvider="plus") - public void test_plus(Period base, Period add, Period expected) { + public void test_plus_TemporalAmount(Period base, Period add, Period expected) { assertEquals(base.plus(add), expected); } + @Test(expectedExceptions = DateTimeException.class) + public void test_plus_TemporalAmount_nonISO() { + pymd(4, 5, 6).plus(ThaiBuddhistChronology.INSTANCE.period(1, 0, 0)); + } + + @Test(expectedExceptions = DateTimeException.class) + public void test_plus_TemporalAmount_DaysHours() { + TemporalAmount amount = new TemporalAmount() { + @Override + public long get(TemporalUnit unit) { + if (unit == DAYS) { + return 1; + } else { + return 2; + } + } + @Override + public List getUnits() { + List list = new ArrayList<>(); + list.add(DAYS); + list.add(HOURS); + return list; + } + @Override + public Temporal addTo(Temporal temporal) { + throw new UnsupportedOperationException(); + } + @Override + public Temporal subtractFrom(Temporal temporal) { + throw new UnsupportedOperationException(); + } + }; + pymd(4, 5, 6).plus(amount); + } + //----------------------------------------------------------------------- // plusYears() //----------------------------------------------------------------------- @@ -704,10 +776,45 @@ public class TCKPeriod extends AbstractTCKTest { } @Test(dataProvider="minus") - public void test_minus(Period base, Period subtract, Period expected) { + public void test_minus_TemporalAmount(Period base, Period subtract, Period expected) { assertEquals(base.minus(subtract), expected); } + @Test(expectedExceptions = DateTimeException.class) + public void test_minus_TemporalAmount_nonISO() { + pymd(4, 5, 6).minus(ThaiBuddhistChronology.INSTANCE.period(1, 0, 0)); + } + + @Test(expectedExceptions = DateTimeException.class) + public void test_minus_TemporalAmount_DaysHours() { + TemporalAmount amount = new TemporalAmount() { + @Override + public long get(TemporalUnit unit) { + if (unit == DAYS) { + return 1; + } else { + return 2; + } + } + @Override + public List getUnits() { + List list = new ArrayList<>(); + list.add(DAYS); + list.add(HOURS); + return list; + } + @Override + public Temporal addTo(Temporal temporal) { + throw new UnsupportedOperationException(); + } + @Override + public Temporal subtractFrom(Temporal temporal) { + throw new UnsupportedOperationException(); + } + }; + pymd(4, 5, 6).minus(amount); + } + //----------------------------------------------------------------------- // minusYears() //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java new file mode 100644 index 00000000000..58a1c35eddb --- /dev/null +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Copyright (c) 2013, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.chrono; + +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.YEARS; +import static org.testng.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.DateTimeException; +import java.time.LocalDate; +import java.time.Period; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; +import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; +import java.time.chrono.IsoChronology; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.MinguoChronology; +import java.time.chrono.ThaiBuddhistChronology; +import java.time.temporal.Temporal; +import java.time.temporal.UnsupportedTemporalTypeException; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class TCKChronoPeriod { + + //----------------------------------------------------------------------- + // regular data factory for names and descriptions of available calendars + //----------------------------------------------------------------------- + @DataProvider(name = "calendars") + Chronology[][] data_of_calendars() { + return new Chronology[][]{ + {HijrahChronology.INSTANCE}, + {IsoChronology.INSTANCE}, + {JapaneseChronology.INSTANCE}, + {MinguoChronology.INSTANCE}, + {ThaiBuddhistChronology.INSTANCE}}; + } + + //----------------------------------------------------------------------- + // Test Serialization of Calendars + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_serialization(Chronology chrono) throws Exception { + ChronoPeriod period = chrono.period(1, 2, 3); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(period); + out.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + + ObjectInputStream in = new ObjectInputStream(bais); + ChronoPeriod ser = (ChronoPeriod) in.readObject(); + assertEquals(ser, period, "deserialized ChronoPeriod is wrong"); + } + + @Test(dataProvider="calendars") + public void test_get(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.get(YEARS), 1); + assertEquals(period.get(MONTHS), 2); + assertEquals(period.get(DAYS), 3); + } + + @Test(dataProvider="calendars", expectedExceptions=UnsupportedTemporalTypeException.class) + public void test_get_unsupported(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + period.get(HOURS); + } + + @Test(dataProvider="calendars") + public void test_getUnits(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.getUnits().size(), 3); + assertEquals(period.getUnits().get(0), YEARS); + assertEquals(period.getUnits().get(1), MONTHS); + assertEquals(period.getUnits().get(2), DAYS); + } + + @Test(dataProvider="calendars") + public void test_getChronology(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.getChronology(), chrono); + } + + @Test(dataProvider="calendars") + public void test_isZero_isNegative(Chronology chrono) { + ChronoPeriod periodPositive = chrono.period(1, 2, 3); + assertEquals(periodPositive.isZero(), false); + assertEquals(periodPositive.isNegative(), false); + + ChronoPeriod periodZero = chrono.period(0, 0, 0); + assertEquals(periodZero.isZero(), true); + assertEquals(periodZero.isNegative(), false); + + ChronoPeriod periodNegative = chrono.period(-1, 0, 0); + assertEquals(periodNegative.isZero(), false); + assertEquals(periodNegative.isNegative(), true); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_plus(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod period2 = chrono.period(2, 3, 4); + ChronoPeriod result = period.plus(period2); + assertEquals(result, chrono.period(3, 5, 7)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_plus_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod isoPeriod = Period.of(2, 3, 4); + ChronoPeriod thaiPeriod = ThaiBuddhistChronology.INSTANCE.period(2, 3, 4); + // one of these two will fail + period.plus(isoPeriod); + period.plus(thaiPeriod); + } + + @Test(dataProvider="calendars") + public void test_minus(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod period2 = chrono.period(2, 3, 4); + ChronoPeriod result = period.minus(period2); + assertEquals(result, chrono.period(-1, -1, -1)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_minus_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoPeriod isoPeriod = Period.of(2, 3, 4); + ChronoPeriod thaiPeriod = ThaiBuddhistChronology.INSTANCE.period(2, 3, 4); + // one of these two will fail + period.minus(isoPeriod); + period.minus(thaiPeriod); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_addTo(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate date = chrono.dateNow(); + Temporal result = period.addTo(date); + assertEquals(result, date.plus(14, MONTHS).plus(3, DAYS)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_addTo_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate isoDate = LocalDate.of(2000, 1, 1); + ChronoLocalDate thaiDate = ThaiBuddhistChronology.INSTANCE.date(2000, 1, 1); + // one of these two will fail + period.addTo(isoDate); + period.addTo(thaiDate); + } + + @Test(dataProvider="calendars") + public void test_subtractFrom(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate date = chrono.dateNow(); + Temporal result = period.subtractFrom(date); + assertEquals(result, date.minus(14, MONTHS).minus(3, DAYS)); + } + + @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class) + public void test_subtractFrom_wrongChrono(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + ChronoLocalDate isoDate = LocalDate.of(2000, 1, 1); + ChronoLocalDate thaiDate = ThaiBuddhistChronology.INSTANCE.date(2000, 1, 1); + // one of these two will fail + period.subtractFrom(isoDate); + period.subtractFrom(thaiDate); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_negated(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.negated(), chrono.period(-1, -2, -3)); + } + + @Test(dataProvider="calendars") + public void test_multipliedBy(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + assertEquals(period.multipliedBy(3), chrono.period(3, 6, 9)); + } + + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_equals_equal(Chronology chrono) { + ChronoPeriod a1 = chrono.period(1, 2, 3); + ChronoPeriod a2 = chrono.period(1, 2, 3); + assertEquals(a1, a1); + assertEquals(a1, a2); + assertEquals(a2, a1); + assertEquals(a2, a2); + assertEquals(a1.hashCode(), a2.hashCode()); + } + + @Test(dataProvider="calendars") + public void test_equals_notEqual(Chronology chrono) { + ChronoPeriod a = chrono.period(1, 2, 3); + ChronoPeriod b = chrono.period(2, 2, 3); + assertEquals(a.equals(b), false); + assertEquals(b.equals(a), false); + assertEquals(a.equals(""), false); + assertEquals(a.equals(null), false); + } + + @Test(dataProvider="calendars") + public void test_toString(Chronology chrono) { + ChronoPeriod period = chrono.period(1, 2, 3); + if (period instanceof Period == false) { + assertEquals(period.toString(), chrono.getId() + " P1Y2M3D"); + } + } + +} diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java index e9d963c73af..fd53b0f0be1 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java @@ -79,6 +79,7 @@ import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; import java.time.chrono.Chronology; import java.time.chrono.Era; import java.time.chrono.IsoChronology; @@ -87,6 +88,7 @@ import java.time.chrono.JapaneseDate; import java.time.chrono.JapaneseEra; import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; +import java.time.chrono.ThaiBuddhistChronology; import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; @@ -615,8 +617,8 @@ public class TCKJapaneseChronology { public void test_periodUntilDate() { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); - Period period = mdate1.until(mdate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(mdate2); + assertEquals(period, JapaneseChronology.INSTANCE.period(1, 1, 1)); } @Test @@ -632,8 +634,8 @@ public class TCKJapaneseChronology { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.until(ldate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(ldate2); + assertEquals(period, JapaneseChronology.INSTANCE.period(1, 1, 1)); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java index 50ddf70cb3e..ad98e9119b3 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java @@ -69,13 +69,13 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; import java.time.OffsetDateTime; -import java.time.Period; import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoPeriod; import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.chrono.Era; @@ -84,8 +84,6 @@ import java.time.chrono.JapaneseDate; import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; import java.time.chrono.MinguoEra; -import java.time.chrono.MinguoChronology; -import java.time.chrono.MinguoDate; import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; import java.time.format.ResolverStyle; @@ -499,8 +497,8 @@ public class TCKMinguoChronology { public void test_periodUntilDate() { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); - Period period = mdate1.until(mdate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(mdate2); + assertEquals(period, MinguoChronology.INSTANCE.period(1, 1, 1)); } @Test @@ -516,8 +514,8 @@ public class TCKMinguoChronology { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); ThaiBuddhistDate ldate2 = ThaiBuddhistChronology.INSTANCE.date(mdate2); - Period period = mdate1.until(ldate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(ldate2); + assertEquals(period, MinguoChronology.INSTANCE.period(1, 1, 1)); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java index e57847c0619..5557641738a 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java @@ -72,11 +72,11 @@ import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Month; -import java.time.Period; import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoPeriod; import java.time.chrono.Chronology; import java.time.chrono.Era; import java.time.chrono.IsoChronology; @@ -458,8 +458,8 @@ public class TCKThaiBuddhistChronology { public void test_periodUntilDate() { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); - Period period = mdate1.until(mdate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(mdate2); + assertEquals(period, ThaiBuddhistChronology.INSTANCE.period(1, 1, 1)); } @Test @@ -475,8 +475,8 @@ public class TCKThaiBuddhistChronology { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.until(ldate2); - assertEquals(period, Period.of(1, 1, 1)); + ChronoPeriod period = mdate1.until(ldate2); + assertEquals(period, ThaiBuddhistChronology.INSTANCE.period(1, 1, 1)); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java index 3e7cce46d1f..05a6d4b515d 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java +++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java @@ -26,9 +26,9 @@ package test.java.time.chrono; import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; -import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -39,12 +39,12 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; -import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoPeriod; import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; @@ -330,26 +330,26 @@ public class TestUmmAlQuraChronology { @DataProvider(name="datesForPeriod") Object[][] data_Period() { return new Object[][] { - {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), Period.of(84, 2, 5)}, - {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), Period.of(31, 1, 22)}, - {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), Period.of(49, 6, 24)}, - {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), Period.of(-50, -1, -20)}, - {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), Period.of(0, 11, 28)}, + {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(84, 2, 5)}, + {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(31, 1, 22)}, + {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), HijrahChronology.INSTANCE.period(49, 6, 24)}, + {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), HijrahChronology.INSTANCE.period(-50, -1, -20)}, + {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), HijrahChronology.INSTANCE.period(0, 11, 28)}, }; } // Test to get the Period between two given dates @Test(dataProvider="datesForPeriod") - public void test_until(HijrahDate h1, HijrahDate h2, Period p) { - Period period = h1.until(h2); + public void test_until(HijrahDate h1, HijrahDate h2, ChronoPeriod p) { + ChronoPeriod period = h1.until(h2); assertEquals(period, p); } // Test to get the Period between dates in different chronologies @Test(dataProvider="datesForPeriod") - public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, Period p) { + public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, ChronoPeriod p) { MinguoDate m = MinguoChronology.INSTANCE.date(h2); - Period period = h1.until(m); + ChronoPeriod period = h1.until(m); assertEquals(period, p); } From 1c2a7eea85ea261102687190d6b2e92c560770b8 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 6 Sep 2013 08:42:42 -0700 Subject: [PATCH 069/293] 8022335: Native stack walk while generating hs_err does not work on Windows x64 Use WinDbg API StackWalk64() Reviewed-by: zgu, dholmes --- hotspot/src/os/windows/vm/decoder_windows.cpp | 91 +++++++++++++++++- hotspot/src/os/windows/vm/decoder_windows.hpp | 41 +++++++++ .../os_cpu/windows_x86/vm/os_windows_x86.cpp | 92 +++++++++++++++++++ .../os_cpu/windows_x86/vm/os_windows_x86.hpp | 6 ++ hotspot/src/share/vm/runtime/frame.cpp | 2 +- hotspot/src/share/vm/runtime/frame.hpp | 1 + hotspot/src/share/vm/runtime/os.hpp | 8 ++ hotspot/src/share/vm/utilities/decoder.cpp | 18 +++- hotspot/src/share/vm/utilities/decoder.hpp | 14 +++ hotspot/src/share/vm/utilities/vmError.cpp | 5 + hotspot/src/share/vm/utilities/vmError.hpp | 4 + 11 files changed, 275 insertions(+), 7 deletions(-) diff --git a/hotspot/src/os/windows/vm/decoder_windows.cpp b/hotspot/src/os/windows/vm/decoder_windows.cpp index 326d3288020..b99adaa9f4f 100644 --- a/hotspot/src/os/windows/vm/decoder_windows.cpp +++ b/hotspot/src/os/windows/vm/decoder_windows.cpp @@ -32,7 +32,11 @@ WindowsDecoder::WindowsDecoder() { _can_decode_in_vm = false; _pfnSymGetSymFromAddr64 = NULL; _pfnUndecorateSymbolName = NULL; - +#ifdef AMD64 + _pfnStackWalk64 = NULL; + _pfnSymFunctionTableAccess64 = NULL; + _pfnSymGetModuleBase64 = NULL; +#endif _decoder_status = no_error; initialize(); } @@ -53,14 +57,24 @@ void WindowsDecoder::initialize() { _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName"); if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) { - _pfnSymGetSymFromAddr64 = NULL; - _pfnUndecorateSymbolName = NULL; - ::FreeLibrary(handle); - _dbghelp_handle = NULL; + uninitialize(); _decoder_status = helper_func_error; return; } +#ifdef AMD64 + _pfnStackWalk64 = (pfn_StackWalk64)::GetProcAddress(handle, "StackWalk64"); + _pfnSymFunctionTableAccess64 = (pfn_SymFunctionTableAccess64)::GetProcAddress(handle, "SymFunctionTableAccess64"); + _pfnSymGetModuleBase64 = (pfn_SymGetModuleBase64)::GetProcAddress(handle, "SymGetModuleBase64"); + if (_pfnStackWalk64 == NULL || _pfnSymFunctionTableAccess64 == NULL || _pfnSymGetModuleBase64 == NULL) { + // We can't call StackWalk64 to walk the stack, but we are still + // able to decode the symbols. Let's limp on. + _pfnStackWalk64 = NULL; + _pfnSymFunctionTableAccess64 = NULL; + _pfnSymGetModuleBase64 = NULL; + } +#endif + HANDLE hProcess = ::GetCurrentProcess(); _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS); if (!_pfnSymInitialize(hProcess, NULL, TRUE)) { @@ -156,6 +170,11 @@ void WindowsDecoder::initialize() { void WindowsDecoder::uninitialize() { _pfnSymGetSymFromAddr64 = NULL; _pfnUndecorateSymbolName = NULL; +#ifdef AMD64 + _pfnStackWalk64 = NULL; + _pfnSymFunctionTableAccess64 = NULL; + _pfnSymGetModuleBase64 = NULL; +#endif if (_dbghelp_handle != NULL) { ::FreeLibrary(_dbghelp_handle); } @@ -195,3 +214,65 @@ bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) { _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE); } +#ifdef AMD64 +BOOL WindowsDbgHelp::StackWalk64(DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress) { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error() && wd->_pfnStackWalk64) { + return wd->_pfnStackWalk64(MachineType, + hProcess, + hThread, + StackFrame, + ContextRecord, + ReadMemoryRoutine, + FunctionTableAccessRoutine, + GetModuleBaseRoutine, + TranslateAddress); + } else { + return false; + } +} + +PVOID WindowsDbgHelp::SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error() && wd->_pfnSymFunctionTableAccess64) { + return wd->_pfnSymFunctionTableAccess64(hProcess, AddrBase); + } else { + return NULL; + } +} + +pfn_SymFunctionTableAccess64 WindowsDbgHelp::pfnSymFunctionTableAccess64() { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error()) { + return wd->_pfnSymFunctionTableAccess64; + } else { + return NULL; + } +} + +pfn_SymGetModuleBase64 WindowsDbgHelp::pfnSymGetModuleBase64() { + DecoderLocker locker; + WindowsDecoder* wd = (WindowsDecoder*)locker.decoder(); + + if (!wd->has_error()) { + return wd->_pfnSymGetModuleBase64; + } else { + return NULL; + } +} + +#endif // AMD64 diff --git a/hotspot/src/os/windows/vm/decoder_windows.hpp b/hotspot/src/os/windows/vm/decoder_windows.hpp index 3008ee79136..2555e8c9b79 100644 --- a/hotspot/src/os/windows/vm/decoder_windows.hpp +++ b/hotspot/src/os/windows/vm/decoder_windows.hpp @@ -38,6 +38,20 @@ typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWOR typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR); typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int); +#ifdef AMD64 +typedef BOOL (WINAPI *pfn_StackWalk64)(DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); +typedef PVOID (WINAPI *pfn_SymFunctionTableAccess64)(HANDLE hProcess, DWORD64 AddrBase); +typedef DWORD64 (WINAPI *pfn_SymGetModuleBase64)(HANDLE hProcess, DWORD64 dwAddr); +#endif + class WindowsDecoder : public AbstractDecoder { public: @@ -61,7 +75,34 @@ private: bool _can_decode_in_vm; pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64; pfn_UndecorateSymbolName _pfnUndecorateSymbolName; +#ifdef AMD64 + pfn_StackWalk64 _pfnStackWalk64; + pfn_SymFunctionTableAccess64 _pfnSymFunctionTableAccess64; + pfn_SymGetModuleBase64 _pfnSymGetModuleBase64; + + friend class WindowsDbgHelp; +#endif }; +#ifdef AMD64 +// TODO: refactor and move the handling of dbghelp.dll outside of Decoder +class WindowsDbgHelp : public Decoder { +public: + static BOOL StackWalk64(DWORD MachineType, + HANDLE hProcess, + HANDLE hThread, + LPSTACKFRAME64 StackFrame, + PVOID ContextRecord, + PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); + static PVOID SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); + + static pfn_SymFunctionTableAccess64 pfnSymFunctionTableAccess64(); + static pfn_SymGetModuleBase64 pfnSymGetModuleBase64(); +}; +#endif + #endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp index a0f2a7680be..09735dae0c6 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp @@ -29,6 +29,7 @@ #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" +#include "decoder_windows.hpp" #include "interpreter/interpreter.hpp" #include "jvm_windows.h" #include "memory/allocation.inline.hpp" @@ -327,6 +328,94 @@ add_ptr_func_t* os::atomic_add_ptr_func = os::atomic_add_ptr_bootstrap cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; +#ifdef AMD64 +/* + * Windows/x64 does not use stack frames the way expected by Java: + * [1] in most cases, there is no frame pointer. All locals are addressed via RSP + * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may + * not be RBP. + * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx + * + * So it's not possible to print the native stack using the + * while (...) {... fr = os::get_sender_for_C_frame(&fr); } + * loop in vmError.cpp. We need to roll our own loop. + */ +bool os::platform_print_native_stack(outputStream* st, void* context, + char *buf, int buf_size) +{ + CONTEXT ctx; + if (context != NULL) { + memcpy(&ctx, context, sizeof(ctx)); + } else { + RtlCaptureContext(&ctx); + } + + st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); + + STACKFRAME stk; + memset(&stk, 0, sizeof(stk)); + stk.AddrStack.Offset = ctx.Rsp; + stk.AddrStack.Mode = AddrModeFlat; + stk.AddrFrame.Offset = ctx.Rbp; + stk.AddrFrame.Mode = AddrModeFlat; + stk.AddrPC.Offset = ctx.Rip; + stk.AddrPC.Mode = AddrModeFlat; + + int count = 0; + address lastpc = 0; + while (count++ < StackPrintLimit) { + intptr_t* sp = (intptr_t*)stk.AddrStack.Offset; + intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp! + address pc = (address)stk.AddrPC.Offset; + + if (pc != NULL && sp != NULL && fp != NULL) { + if (count == 2 && lastpc == pc) { + // Skip it -- StackWalk64() may return the same PC + // (but different SP) on the first try. + } else { + // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame + // may not contain what Java expects, and may cause the frame() constructor + // to crash. Let's just print out the symbolic address. + frame::print_C_frame(st, buf, buf_size, pc); + st->cr(); + } + lastpc = pc; + } else { + break; + } + + PVOID p = WindowsDbgHelp::SymFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset); + if (!p) { + // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash. + break; + } + + BOOL result = WindowsDbgHelp::StackWalk64( + IMAGE_FILE_MACHINE_AMD64, // __in DWORD MachineType, + GetCurrentProcess(), // __in HANDLE hProcess, + GetCurrentThread(), // __in HANDLE hThread, + &stk, // __inout LP STACKFRAME64 StackFrame, + &ctx, // __inout PVOID ContextRecord, + NULL, // __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + WindowsDbgHelp::pfnSymFunctionTableAccess64(), + // __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + WindowsDbgHelp::pfnSymGetModuleBase64(), + // __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + NULL); // __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress + + if (!result) { + break; + } + } + if (count > StackPrintLimit) { + st->print_cr("......"); + } + st->cr(); + + return true; +} +#endif // AMD64 + ExtendedPC os::fetch_frame_from_context(void* ucVoid, intptr_t** ret_sp, intptr_t** ret_fp) { @@ -401,6 +490,9 @@ frame os::current_frame() { StubRoutines::x86::get_previous_fp_entry()); if (func == NULL) return frame(); intptr_t* fp = (*func)(); + if (fp == NULL) { + return frame(); + } #else intptr_t* fp = _get_previous_fp(); #endif // AMD64 diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp index 41814b6c61b..22ffeb5dc34 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.hpp @@ -62,4 +62,10 @@ static bool register_code_area(char *low, char *high); +#ifdef AMD64 +#define PLATFORM_PRINT_NATIVE_STACK 1 +static bool platform_print_native_stack(outputStream* st, void* context, + char *buf, int buf_size); +#endif + #endif // OS_CPU_WINDOWS_X86_VM_OS_WINDOWS_X86_HPP diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp index 6f5724323cd..4fae1c8fe11 100644 --- a/hotspot/src/share/vm/runtime/frame.cpp +++ b/hotspot/src/share/vm/runtime/frame.cpp @@ -652,7 +652,7 @@ void frame::interpreter_frame_print_on(outputStream* st) const { // Return whether the frame is in the VM or os indicating a Hotspot problem. // Otherwise, it's likely a bug in the native library that the Java code calls, // hopefully indicating where to submit bugs. -static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) { +void frame::print_C_frame(outputStream* st, char* buf, int buflen, address pc) { // C/C++ frame bool in_vm = os::address_is_in_vm(pc); st->print(in_vm ? "V" : "C"); diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp index 096b467b5f8..78292c662ec 100644 --- a/hotspot/src/share/vm/runtime/frame.hpp +++ b/hotspot/src/share/vm/runtime/frame.hpp @@ -406,6 +406,7 @@ class frame VALUE_OBJ_CLASS_SPEC { void print_on(outputStream* st) const; void interpreter_frame_print_on(outputStream* st) const; void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const; + static void print_C_frame(outputStream* st, char* buf, int buflen, address pc); // Add annotated descriptions of memory locations belonging to this frame to values void describe(FrameValues& values, int frame_no); diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e43d68981cb..4ca0d32607b 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -795,6 +795,14 @@ class os: AllStatic { #endif public: +#ifndef PLATFORM_PRINT_NATIVE_STACK + // No platform-specific code for printing the native stack. + static bool platform_print_native_stack(outputStream* st, void* context, + char *buf, int buf_size) { + return false; + } +#endif + // debugging support (mostly used by debug.cpp but also fatal error handler) static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address diff --git a/hotspot/src/share/vm/utilities/decoder.cpp b/hotspot/src/share/vm/utilities/decoder.cpp index 5489fe6fefb..3fc934b4f32 100644 --- a/hotspot/src/share/vm/utilities/decoder.cpp +++ b/hotspot/src/share/vm/utilities/decoder.cpp @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "prims/jvm.h" -#include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "utilities/decoder.hpp" #include "utilities/vmError.hpp" @@ -80,6 +79,23 @@ AbstractDecoder* Decoder::create_decoder() { return decoder; } +inline bool DecoderLocker::is_first_error_thread() { + return (os::current_thread_id() == VMError::get_first_error_tid()); +} + +DecoderLocker::DecoderLocker() : + MutexLockerEx(DecoderLocker::is_first_error_thread() ? + NULL : Decoder::shared_decoder_lock(), true) { + _decoder = is_first_error_thread() ? + Decoder::get_error_handler_instance() : Decoder::get_shared_instance(); + assert(_decoder != NULL, "null decoder"); +} + +Mutex* Decoder::shared_decoder_lock() { + assert(_shared_decoder_lock != NULL, "Just check"); + return _shared_decoder_lock; +} + bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) { assert(_shared_decoder_lock != NULL, "Just check"); bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid; diff --git a/hotspot/src/share/vm/utilities/decoder.hpp b/hotspot/src/share/vm/utilities/decoder.hpp index 0d2af80986c..0cc880f1915 100644 --- a/hotspot/src/share/vm/utilities/decoder.hpp +++ b/hotspot/src/share/vm/utilities/decoder.hpp @@ -28,6 +28,7 @@ #include "memory/allocation.hpp" #include "runtime/mutex.hpp" +#include "runtime/mutexLocker.hpp" class AbstractDecoder : public CHeapObj { public: @@ -124,6 +125,19 @@ private: protected: static Mutex* _shared_decoder_lock; + static Mutex* shared_decoder_lock(); + + friend class DecoderLocker; +}; + +class DecoderLocker : public MutexLockerEx { + AbstractDecoder* _decoder; + inline bool is_first_error_thread(); +public: + DecoderLocker(); + AbstractDecoder* decoder() { + return _decoder; + } }; #endif // SHARE_VM_UTILITIES_DECODER_HPP diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index b07404dc9b7..79769aeb3bc 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -574,6 +574,10 @@ void VMError::report(outputStream* st) { STEP(120, "(printing native stack)" ) if (_verbose) { + if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) { + // We have printed the native stack in platform-specific code + // Windows/x64 needs special handling. + } else { frame fr = _context ? os::fetch_frame_from_context(_context) : os::current_frame(); @@ -604,6 +608,7 @@ void VMError::report(outputStream* st) { st->cr(); } } + } STEP(130, "(printing Java stack)" ) diff --git a/hotspot/src/share/vm/utilities/vmError.hpp b/hotspot/src/share/vm/utilities/vmError.hpp index 1b1608bdc90..299cfaa6f3d 100644 --- a/hotspot/src/share/vm/utilities/vmError.hpp +++ b/hotspot/src/share/vm/utilities/vmError.hpp @@ -136,6 +136,10 @@ public: // check to see if fatal error reporting is in progress static bool fatal_error_in_progress() { return first_error != NULL; } + + static jlong get_first_error_tid() { + return first_error_tid; + } }; #endif // SHARE_VM_UTILITIES_VMERROR_HPP From 972efc6f0a9dff15c6f1c9fb57e7fe796baa300f Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Mon, 9 Sep 2013 10:01:09 +0100 Subject: [PATCH 070/293] 8023478: Test fails with HS crash in GCNotifier Reviewed-by: sla --- hotspot/src/share/vm/services/gcNotifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/gcNotifier.cpp b/hotspot/src/share/vm/services/gcNotifier.cpp index 7d1fe5d8944..1025072339a 100644 --- a/hotspot/src/share/vm/services/gcNotifier.cpp +++ b/hotspot/src/share/vm/services/gcNotifier.cpp @@ -209,7 +209,7 @@ void GCNotifier::sendNotificationInternal(TRAPS) { GCNotificationRequest *request = getRequest(); if (request != NULL) { NotificationMark nm(request); - Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD); + Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, CHECK); Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK); Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK); From 76033b1a3738d01a7778b2e595df222a1370b34a Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Mon, 9 Sep 2013 14:44:37 -0400 Subject: [PATCH 071/293] 8023167: JVM allows duplicate Runtime[In]VisibleTypeAnnotations attributes in ClassFile/field_info/method_info structures Add checks for duplicates and issue errors when detected. Reviewed-by: coleenp, zgu --- .../share/vm/classfile/classFileParser.cpp | 71 +++++++++++++++---- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 0705c5f14d6..7b79a1ab274 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -888,6 +888,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_type_annotations_exists = false; while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length u2 attribute_name_index = cfs->get_u2_fast(); @@ -946,15 +947,27 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, assert(runtime_invisible_annotations != NULL, "null invisible annotations"); cfs->skip_u1(runtime_invisible_annotations_length, CHECK); } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", CHECK); + } runtime_visible_type_annotations_length = attribute_length; runtime_visible_type_annotations = cfs->get_u1_buffer(); assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); - } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { - runtime_invisible_type_annotations_length = attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", CHECK); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else { cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes } @@ -2060,6 +2073,7 @@ methodHandle ClassFileParser::parse_method(bool is_interface, int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_type_annotations_exists = false; u1* annotation_default = NULL; int annotation_default_length = 0; @@ -2316,16 +2330,30 @@ methodHandle ClassFileParser::parse_method(bool is_interface, assert(annotation_default != NULL, "null annotation default"); cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s", + CHECK_(nullHandle)); + } runtime_visible_type_annotations_length = method_attribute_length; runtime_visible_type_annotations = cfs->get_u1_buffer(); assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); // No need for the VM to parse Type annotations cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); - } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { - runtime_invisible_type_annotations_length = method_attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s", + CHECK_(nullHandle)); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = method_attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); } else { // Skip unknown attributes cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); @@ -2818,6 +2846,7 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio int runtime_visible_type_annotations_length = 0; u1* runtime_invisible_type_annotations = NULL; int runtime_invisible_type_annotations_length = 0; + bool runtime_invisible_type_annotations_exists = false; u1* inner_classes_attribute_start = NULL; u4 inner_classes_attribute_length = 0; u2 enclosing_method_class_index = 0; @@ -2921,16 +2950,28 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio parsed_bootstrap_methods_attribute = true; parse_classfile_bootstrap_methods_attribute(attribute_length, CHECK); } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { + if (runtime_visible_type_annotations != NULL) { + classfile_parse_error( + "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", CHECK); + } runtime_visible_type_annotations_length = attribute_length; runtime_visible_type_annotations = cfs->get_u1_buffer(); assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); // No need for the VM to parse Type annotations cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); - } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) { - runtime_invisible_type_annotations_length = attribute_length; - runtime_invisible_type_annotations = cfs->get_u1_buffer(); - assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); - cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) { + if (runtime_invisible_type_annotations_exists) { + classfile_parse_error( + "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", CHECK); + } else { + runtime_invisible_type_annotations_exists = true; + } + if (PreserveAllAnnotations) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + } + cfs->skip_u1(attribute_length, CHECK); } else { // Unknown attribute cfs->skip_u1(attribute_length, CHECK); From ce469f1922e134ac709a9189c4328637655d5e38 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 11 Sep 2013 00:38:18 -0400 Subject: [PATCH 072/293] 8024256: Minimal VM build is broken with PCH disabled Reviewed-by: coleenp, twisti --- hotspot/make/excludeSrc.make | 2 +- .../share/vm/gc_implementation/shared/allocationStats.hpp | 6 ++---- .../share/vm/gc_implementation/shared/hSpaceCounters.hpp | 4 +--- hotspot/src/share/vm/memory/binaryTreeDictionary.cpp | 4 ++-- hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp | 5 +---- 5 files changed, 7 insertions(+), 14 deletions(-) diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make index 7cc879a3d7b..c3a9b4dea0e 100644 --- a/hotspot/make/excludeSrc.make +++ b/hotspot/make/excludeSrc.make @@ -99,7 +99,7 @@ ifeq ($(INCLUDE_ALL_GCS), false) psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \ parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \ gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \ - mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp + mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp endif ifeq ($(INCLUDE_NMT), false) diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp index cf7cd3ae0f2..0fb6d7fa23e 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,9 @@ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS -#include "gc_implementation/shared/gcUtil.hpp" #include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" -#endif // INCLUDE_ALL_GCS +#include "gc_implementation/shared/gcUtil.hpp" class AllocationStats VALUE_OBJ_CLASS_SPEC { // A duration threshold (in ms) used to filter diff --git a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp index 034d319b078..0b855e7f674 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,9 @@ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS #include "gc_implementation/shared/generationCounters.hpp" #include "memory/generation.hpp" #include "runtime/perfData.hpp" -#endif // INCLUDE_ALL_GCS // A HSpaceCounter is a holder class for performance counters // that track a collections (logical spaces) in a heap; diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp index 8ed2b61a921..bfe1d1b4ca8 100644 --- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp +++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,10 +33,10 @@ #include "runtime/globals.hpp" #include "utilities/ostream.hpp" #include "utilities/macros.hpp" +#include "gc_implementation/shared/spaceDecorator.hpp" #if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" -#include "gc_implementation/shared/spaceDecorator.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" #endif // INCLUDE_ALL_GCS diff --git a/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp b/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp index 5a626ce7fa3..98d8f438ea4 100644 --- a/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp +++ b/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,10 +26,7 @@ #define SHARE_VM_UTILITIES_YIELDINGWORKGROUP_HPP #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS #include "utilities/workgroup.hpp" -#endif // INCLUDE_ALL_GCS - // Forward declarations class YieldingFlexibleWorkGang; From 86624d96d773b48cf814ed669ff4bc8aac40623c Mon Sep 17 00:00:00 2001 From: Stefan Johansson Date: Wed, 11 Sep 2013 08:57:02 +0200 Subject: [PATCH 073/293] 8024176: [macosx] gc/metaspace/ClassMetaspaceSizeInJmapHeap.java failed since jdk8b105, hs25b47 The code for reading compressed klass pointers in the sa-agent on Mac used readCompOopAddress instead of readCompKlassAddress, this is wrong but has been hidden because compressed oops and compressed klasses has used the same base address in the past. Reviewed-by: sla, jmasa --- .../share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java index d1b56881f13..f25d50ff23c 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdAddress.java @@ -81,7 +81,7 @@ class BsdAddress implements Address { public Address getCompKlassAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException { - return debugger.readCompOopAddress(addr + offset); + return debugger.readCompKlassAddress(addr + offset); } // From 1d978716242b7d4ef33f8e82f8ce6d79f802e38b Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Wed, 11 Sep 2013 09:37:14 +0200 Subject: [PATCH 074/293] 8009561: NPG: Metaspace fragmentation when retiring a Metachunk Use best-fit block-splitting freelist allocation from the block freelist. Reviewed-by: jmasa, stefank --- hotspot/src/share/vm/memory/metaspace.cpp | 35 +++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 1c5cec84d5f..63e6be716da 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -51,7 +51,7 @@ const bool metaspace_slow_verify = false; // Parameters for stress mode testing const uint metadata_deallocate_a_lot_block = 10; const uint metadata_deallocate_a_lock_chunk = 3; -size_t const allocation_from_dictionary_limit = 64 * K; +size_t const allocation_from_dictionary_limit = 4 * K; MetaWord* last_allocated = 0; @@ -228,6 +228,10 @@ class BlockFreelist VALUE_OBJ_CLASS_SPEC { BlockTreeDictionary* _dictionary; static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size); + // Only allocate and split from freelist if the size of the allocation + // is at least 1/4th the size of the available block. + const static int WasteMultiplier = 4; + // Accessors BlockTreeDictionary* dictionary() const { return _dictionary; } @@ -623,6 +627,7 @@ class SpaceManager : public CHeapObj { // Add chunk to the list of chunks in use void add_chunk(Metachunk* v, bool make_current); + void retire_current_chunk(); Mutex* lock() const { return _lock; } @@ -807,12 +812,25 @@ MetaWord* BlockFreelist::get_block(size_t word_size) { } Metablock* free_block = - dictionary()->get_chunk(word_size, FreeBlockDictionary::exactly); + dictionary()->get_chunk(word_size, FreeBlockDictionary::atLeast); if (free_block == NULL) { return NULL; } - return (MetaWord*) free_block; + const size_t block_size = free_block->size(); + if (block_size > WasteMultiplier * word_size) { + return_block((MetaWord*)free_block, block_size); + return NULL; + } + + MetaWord* new_block = (MetaWord*)free_block; + assert(block_size >= word_size, "Incorrect size of block from freelist"); + const size_t unused = block_size - word_size; + if (unused >= TreeChunk::min_size()) { + return_block(new_block + word_size, unused); + } + + return new_block; } void BlockFreelist::print_on(outputStream* st) const { @@ -2278,6 +2296,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { ChunkIndex index = ChunkManager::list_index(new_chunk->word_size()); if (index != HumongousIndex) { + retire_current_chunk(); set_current_chunk(new_chunk); new_chunk->set_next(chunks_in_use(index)); set_chunks_in_use(index, new_chunk); @@ -2313,6 +2332,16 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { } } +void SpaceManager::retire_current_chunk() { + if (current_chunk() != NULL) { + size_t remaining_words = current_chunk()->free_word_size(); + if (remaining_words >= TreeChunk::min_size()) { + block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words); + inc_used_metrics(remaining_words); + } + } +} + Metachunk* SpaceManager::get_new_chunk(size_t word_size, size_t grow_chunks_by_words) { From a136d0573963ee7cc319a0e4c577479479420172 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 11 Sep 2013 10:14:32 +0200 Subject: [PATCH 075/293] 8016825: Large pages for the heap broken on Windows for compressed oops Correctly pass the requested base address for the heap to the OS function to reserve memory. Reviewed-by: brutisso, stefank --- hotspot/src/os/windows/vm/os_windows.cpp | 68 ++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 015f94d6662..985cbd6230f 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -3189,9 +3189,12 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, boo return p_buf; } else { + if (TracePageSizes && Verbose) { + tty->print_cr("Reserving large pages in a single large chunk."); + } // normal policy just allocate it all at once DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; - char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); + char * res = (char *)VirtualAlloc(addr, bytes, flag, prot); if (res != NULL) { address pc = CALLER_PC; MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc); @@ -5714,7 +5717,66 @@ BOOL os::Advapi32Dll::AdvapiAvailable() { #endif #ifndef PRODUCT + +// test the code path in reserve_memory_special() that tries to allocate memory in a single +// contiguous memory block at a particular address. +// The test first tries to find a good approximate address to allocate at by using the same +// method to allocate some memory at any address. The test then tries to allocate memory in +// the vicinity (not directly after it to avoid possible by-chance use of that location) +// This is of course only some dodgy assumption, there is no guarantee that the vicinity of +// the previously allocated memory is available for allocation. The only actual failure +// that is reported is when the test tries to allocate at a particular location but gets a +// different valid one. A NULL return value at this point is not considered an error but may +// be legitimate. +// If -XX:+VerboseInternalVMTests is enabled, print some explanatory messages. void TestReserveMemorySpecial_test() { - // No tests available for this platform + if (!UseLargePages) { + if (VerboseInternalVMTests) { + gclog_or_tty->print("Skipping test because large pages are disabled"); + } + return; + } + // save current value of globals + bool old_use_large_pages_individual_allocation = UseLargePagesIndividualAllocation; + bool old_use_numa_interleaving = UseNUMAInterleaving; + + // set globals to make sure we hit the correct code path + UseLargePagesIndividualAllocation = UseNUMAInterleaving = false; + + // do an allocation at an address selected by the OS to get a good one. + const size_t large_allocation_size = os::large_page_size() * 4; + char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false); + if (result == NULL) { + if (VerboseInternalVMTests) { + gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.", + large_allocation_size); + } + } else { + os::release_memory_special(result, large_allocation_size); + + // allocate another page within the recently allocated memory area which seems to be a good location. At least + // we managed to get it once. + const size_t expected_allocation_size = os::large_page_size(); + char* expected_location = result + os::large_page_size(); + char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false); + if (actual_location == NULL) { + if (VerboseInternalVMTests) { + gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.", + expected_location, large_allocation_size); + } + } else { + // release memory + os::release_memory_special(actual_location, expected_allocation_size); + // only now check, after releasing any memory to avoid any leaks. + assert(actual_location == expected_location, + err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead", + expected_location, expected_allocation_size, actual_location)); + } + } + + // restore globals + UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation; + UseNUMAInterleaving = old_use_numa_interleaving; } -#endif +#endif // PRODUCT + From 87a98b7267958dc8046ff36226083785fa442f36 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 11 Sep 2013 10:19:16 +0200 Subject: [PATCH 076/293] 8021823: G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs Correctly calculate the initialization value for the shift between object start and bitmap bit in the G1 mark bitmaps. Reviewed-by: tonyp --- .../gc_implementation/g1/concurrentMark.cpp | 5 +- hotspot/test/gc/TestObjectAlignment.java | 65 +++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 hotspot/test/gc/TestObjectAlignment.java diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 04f8ccd0fc7..77f08f0d3a3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -481,9 +481,8 @@ uint ConcurrentMark::scale_parallel_threads(uint n_par_threads) { ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : _g1h(g1h), - _markBitMap1(MinObjAlignment - 1), - _markBitMap2(MinObjAlignment - 1), - + _markBitMap1(log2_intptr(MinObjAlignment)), + _markBitMap2(log2_intptr(MinObjAlignment)), _parallel_marking_threads(0), _max_parallel_marking_threads(0), _sleep_factor(0.0), diff --git a/hotspot/test/gc/TestObjectAlignment.java b/hotspot/test/gc/TestObjectAlignment.java new file mode 100644 index 00000000000..8cfc9709f16 --- /dev/null +++ b/hotspot/test/gc/TestObjectAlignment.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test TestObjectAlignment + * @key gc + * @bug 8021823 + * @summary G1: Concurrent marking crashes with -XX:ObjectAlignmentInBytes>=32 in 64bit VMs + * @library /testlibrary + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=64 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=128 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:+ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=256 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=8 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=16 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=64 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=128 + * @run main/othervm TestObjectAlignment -Xmx20M -XX:-ExplicitGCInvokesConcurrent -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=256 + */ + +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class TestObjectAlignment { + + public static byte[] garbage; + + private static boolean runsOn32bit() { + return System.getProperty("sun.arch.data.model").equals("32"); + } + + public static void main(String[] args) throws Exception { + if (runsOn32bit()) { + // 32 bit VMs do not allow setting ObjectAlignmentInBytes, so there is nothing to test. We still get called. + return; + } + for (int i = 0; i < 10; i++) { + garbage = new byte[1000]; + System.gc(); + } + } +} From eaa4cfd4a7c29b81b55422f0b013d28061236172 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Wed, 11 Sep 2013 14:30:17 +0400 Subject: [PATCH 077/293] 8024056: runtime/InitialThreadOverflow/testme.sh fails On some macines gcc not able to link cxx program Reviewed-by: dholmes --- hotspot/test/runtime/InitialThreadOverflow/testme.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/test/runtime/InitialThreadOverflow/testme.sh b/hotspot/test/runtime/InitialThreadOverflow/testme.sh index 015a6bd43b1..b7154dc2abd 100644 --- a/hotspot/test/runtime/InitialThreadOverflow/testme.sh +++ b/hotspot/test/runtime/InitialThreadOverflow/testme.sh @@ -43,9 +43,9 @@ then exit 0 fi -gcc_cmd=`which gcc` -if [ "x$gcc_cmd" == "x" ]; then - echo "WARNING: gcc not found. Cannot execute test." 2>&1 +gcc_cmd=`which g++` +if [ "x$gcc_cmd" = "x" ]; then + echo "WARNING: g++ not found. Cannot execute test." 2>&1 exit 0; fi From 962008f22b4767fa6c87a36119bc3f2fdbbe397c Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 11 Sep 2013 16:25:02 +0200 Subject: [PATCH 078/293] 8010722: assert: failed: heap size is too big for compressed oops Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation. Reviewed-by: stefank, dholmes --- hotspot/src/os/bsd/vm/os_bsd.cpp | 2 - hotspot/src/os/linux/vm/os_linux.cpp | 2 - hotspot/src/os/solaris/vm/os_solaris.cpp | 4 +- hotspot/src/os/windows/vm/os_windows.cpp | 2 - .../gc_implementation/g1/g1CollectedHeap.cpp | 4 + .../gc_implementation/g1/g1CollectedHeap.hpp | 3 + .../vm/gc_implementation/g1/heapRegion.cpp | 6 +- .../vm/gc_implementation/g1/heapRegion.hpp | 4 +- .../parallelScavenge/parallelScavengeHeap.hpp | 7 +- .../src/share/vm/memory/collectorPolicy.cpp | 47 ++--- .../src/share/vm/memory/collectorPolicy.hpp | 6 +- .../src/share/vm/memory/genCollectedHeap.hpp | 7 +- hotspot/src/share/vm/memory/universe.cpp | 3 + hotspot/src/share/vm/prims/whitebox.cpp | 8 + hotspot/src/share/vm/runtime/arguments.cpp | 39 +++- hotspot/src/share/vm/runtime/arguments.hpp | 12 +- hotspot/src/share/vm/runtime/os.cpp | 5 + hotspot/src/share/vm/runtime/os.hpp | 8 + hotspot/src/share/vm/runtime/thread.cpp | 5 + .../arguments/TestUseCompressedOopsErgo.java | 50 +++++ .../TestUseCompressedOopsErgoTools.java | 179 ++++++++++++++++++ .../whitebox/sun/hotspot/WhiteBox.java | 2 + 22 files changed, 363 insertions(+), 42 deletions(-) create mode 100644 hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java create mode 100644 hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp index 6b636d379de..58c961b43eb 100644 --- a/hotspot/src/os/bsd/vm/os_bsd.cpp +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp @@ -3589,8 +3589,6 @@ jint os::init_2(void) #endif } - os::large_page_init(); - // initialize suspend/resume support - must do this before signal_sets_init() if (SR_initialize() != 0) { perror("SR_initialize failed"); diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 70837a850d8..5b3d6b31116 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -4755,8 +4755,6 @@ jint os::init_2(void) #endif } - os::large_page_init(); - // initialize suspend/resume support - must do this before signal_sets_init() if (SR_initialize() != 0) { perror("SR_initialize failed"); diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index c3e6e879077..8e5984ffa3d 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -5178,9 +5178,7 @@ jint os::init_2(void) { if(Verbose && PrintMiscellaneous) tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); #endif -} - - os::large_page_init(); + } // Check minimum allowable stack size for thread creation and to initialize // the java system classes, including StackOverflowError - depends on page diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 985cbd6230f..e55281af4c9 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -3920,8 +3920,6 @@ jint os::init_2(void) { #endif } - os::large_page_init(); - // Setup Windows Exceptions // for debugging float code generation bugs diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index bd01ec3b602..1d8ff8a26dc 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() { return JNI_OK; } +size_t G1CollectedHeap::conservative_max_heap_alignment() { + return HeapRegion::max_region_size(); +} + void G1CollectedHeap::ref_processing_init() { // Reference processing in G1 currently works as follows: // diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index aecaa5e97ac..747b2326236 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -1092,6 +1092,9 @@ public: // specified by the policy object. jint initialize(); + // Return the (conservative) maximum heap alignment for any G1 heap + static size_t conservative_max_heap_alignment(); + // Initialize weak reference processing. virtual void ref_processing_init(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index e66268885e3..726acbfcdc0 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -149,6 +149,10 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, // many regions in the heap (based on the min heap size). #define TARGET_REGION_NUMBER 2048 +size_t HeapRegion::max_region_size() { + return (size_t)MAX_REGION_SIZE; +} + void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) { uintx region_size = G1HeapRegionSize; if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp index 097c0b54380..ad2b0649795 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace { ~((1 << (size_t) LogOfHRGrainBytes) - 1); } + static size_t max_region_size(); + // It sets up the heap region size (GrainBytes / GrainWords), as // well as other related fields that are based on the heap region // size (LogOfHRGrainBytes / LogOfHRGrainWords / diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp index 11ef5325120..4e458efa903 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp @@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap { set_alignment(_old_gen_alignment, intra_heap_alignment()); } + // Return the (conservative) maximum heap alignment + static size_t conservative_max_heap_alignment() { + return intra_heap_alignment(); + } + // For use by VM operations enum CollectionType { Scavenge, @@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap { // 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 * HeapWordSize; } + static size_t intra_heap_alignment() { return 64 * K * HeapWordSize; } size_t capacity() const; size_t used() const; diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 6a1967daeda..a5b4aa61894 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -145,6 +145,30 @@ void CollectorPolicy::cleared_all_soft_refs() { _all_soft_refs_clear = true; } +size_t CollectorPolicy::compute_max_alignment() { + // The card marking array and the offset arrays for old generations are + // committed in os pages as well. Make sure they are entirely full (to + // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 + // byte entry and the os page size is 4096, the maximum heap size should + // be 512*4096 = 2MB aligned. + + // There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable + // is supported. + // Requirements of any new remembered set implementations must be added here. + size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable); + + // Parallel GC does its own alignment of the generations to avoid requiring a + // large page (256M on some platforms) for the permanent generation. The + // other collectors should also be updated to do their own alignment and then + // this use of lcm() should be removed. + if (UseLargePages && !UseParallelGC) { + // in presence of large pages we have to make sure that our + // alignment is large page aware + alignment = lcm(os::large_page_size(), alignment); + } + + return alignment; +} // GenCollectorPolicy methods. @@ -175,29 +199,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, GCTimeRatio); } -size_t GenCollectorPolicy::compute_max_alignment() { - // The card marking array and the offset arrays for old generations are - // committed in os pages as well. Make sure they are entirely full (to - // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 - // byte entry and the os page size is 4096, the maximum heap size should - // be 512*4096 = 2MB aligned. - size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name()); - - // Parallel GC does its own alignment of the generations to avoid requiring a - // large page (256M on some platforms) for the permanent generation. The - // other collectors should also be updated to do their own alignment and then - // this use of lcm() should be removed. - if (UseLargePages && !UseParallelGC) { - // in presence of large pages we have to make sure that our - // alignment is large page aware - alignment = lcm(os::large_page_size(), alignment); - } - - assert(alignment >= min_alignment(), "Must be"); - - return alignment; -} - void GenCollectorPolicy::initialize_flags() { // All sizes must be multiples of the generation granularity. set_min_alignment((uintx) Generation::GenGrain); diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp index 4acf7ba780c..73fd177d7ba 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.hpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp @@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj { {} public: + // Return maximum heap alignment that may be imposed by the policy + static size_t compute_max_alignment(); + void set_min_alignment(size_t align) { _min_alignment = align; } size_t min_alignment() { return _min_alignment; } void set_max_alignment(size_t align) { _max_alignment = align; } @@ -234,9 +237,6 @@ class GenCollectorPolicy : public CollectorPolicy { // Try to allocate space by expanding the heap. virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab); - // 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() diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp index 9ab9d1991df..8f814132a78 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -148,6 +148,11 @@ public: return gen_policy()->size_policy(); } + // Return the (conservative) maximum heap alignment + static size_t conservative_max_heap_alignment() { + return Generation::GenGrain; + } + size_t capacity() const; size_t used() const; diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index d0f34b33ae1..54d6851d16d 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -872,6 +872,9 @@ jint Universe::initialize_heap() { // Reserve the Java heap, which is now the same for all GCs. ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { + assert(alignment <= Arguments::conservative_max_heap_alignment(), + err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT, + alignment, Arguments::conservative_max_heap_alignment())); size_t total_reserved = align_size_up(heap_size, alignment); assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), "heap size is too big for compressed oops"); diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp index 0f5607e22b2..6f6a2000a3f 100644 --- a/hotspot/src/share/vm/prims/whitebox.cpp +++ b/hotspot/src/share/vm/prims/whitebox.cpp @@ -33,6 +33,7 @@ #include "prims/whitebox.hpp" #include "prims/wbtestmethods/parserTests.hpp" +#include "runtime/arguments.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" @@ -94,6 +95,11 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name)) return closure.found(); WB_END +WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { + return (jlong)Arguments::max_heap_for_compressed_oops(); +} +WB_END + WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) { CollectorPolicy * p = Universe::heap()->collector_policy(); gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap " @@ -436,6 +442,8 @@ static JNINativeMethod methods[] = { CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", (void*) &WB_ParseCommandLine }, + {CC"getCompressedOopsMaxHeapSize", CC"()J", + (void*)&WB_GetCompressedOopsMaxHeapSize}, {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes }, #if INCLUDE_ALL_GCS {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index fbce8b6b695..9751c552233 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -28,6 +28,7 @@ #include "compiler/compilerOracle.hpp" #include "memory/allocation.inline.hpp" #include "memory/cardTableRS.hpp" +#include "memory/genCollectedHeap.hpp" #include "memory/referenceProcessor.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" @@ -54,6 +55,8 @@ #endif #if INCLUDE_ALL_GCS #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" +#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #endif // INCLUDE_ALL_GCS // Note: This is a special bug reporting site for the JVM @@ -90,6 +93,7 @@ char* Arguments::_java_command = NULL; SystemProperty* Arguments::_system_properties = NULL; const char* Arguments::_gc_log_filename = NULL; bool Arguments::_has_profile = false; +size_t Arguments::_conservative_max_heap_alignment = 0; uintx Arguments::_min_heap_size = 0; Arguments::Mode Arguments::_mode = _mixed; bool Arguments::_java_compiler = false; @@ -1391,10 +1395,17 @@ bool verify_object_alignment() { return true; } -inline uintx max_heap_for_compressed_oops() { +uintx Arguments::max_heap_for_compressed_oops() { // Avoid sign flip. assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size"); - LP64_ONLY(return OopEncodingHeapMax - os::vm_page_size()); + // We need to fit both the NULL page and the heap into the memory budget, while + // keeping alignment constraints of the heap. To guarantee the latter, as the + // NULL page is located before the heap, we pad the NULL page to the conservative + // maximum alignment that the GC may ever impose upon the heap. + size_t displacement_due_to_null_page = align_size_up_(os::vm_page_size(), + Arguments::conservative_max_heap_alignment()); + + LP64_ONLY(return OopEncodingHeapMax - displacement_due_to_null_page); NOT_LP64(ShouldNotReachHere(); return 0); } @@ -1475,6 +1486,23 @@ void Arguments::set_use_compressed_klass_ptrs() { #endif // !ZERO } +void Arguments::set_conservative_max_heap_alignment() { + // The conservative maximum required alignment for the heap is the maximum of + // the alignments imposed by several sources: any requirements from the heap + // itself, the collector policy and the maximum page size we may run the VM + // with. + size_t heap_alignment = GenCollectedHeap::conservative_max_heap_alignment(); +#if INCLUDE_ALL_GCS + if (UseParallelGC) { + heap_alignment = ParallelScavengeHeap::conservative_max_heap_alignment(); + } else if (UseG1GC) { + heap_alignment = G1CollectedHeap::conservative_max_heap_alignment(); + } +#endif // INCLUDE_ALL_GCS + _conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(), + CollectorPolicy::compute_max_alignment()); +} + void Arguments::set_ergonomics_flags() { if (os::is_server_class_machine()) { @@ -1503,6 +1531,8 @@ void Arguments::set_ergonomics_flags() { } } + set_conservative_max_heap_alignment(); + #ifndef ZERO #ifdef _LP64 set_use_compressed_oops(); @@ -3506,6 +3536,11 @@ jint Arguments::parse(const JavaVMInitArgs* args) { no_shared_spaces(); #endif // INCLUDE_CDS + return JNI_OK; +} + +jint Arguments::apply_ergo() { + // Set flags based on ergonomics. set_ergonomics_flags(); diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 43256b75082..c2f4c9883f1 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -280,6 +280,9 @@ class Arguments : AllStatic { // Option flags static bool _has_profile; static const char* _gc_log_filename; + // Value of the conservative maximum heap alignment needed + static size_t _conservative_max_heap_alignment; + static uintx _min_heap_size; // -Xrun arguments @@ -327,6 +330,7 @@ class Arguments : AllStatic { // Garbage-First (UseG1GC) static void set_g1_gc_flags(); // GC ergonomics + static void set_conservative_max_heap_alignment(); static void set_use_compressed_oops(); static void set_use_compressed_klass_ptrs(); static void set_ergonomics_flags(); @@ -430,8 +434,10 @@ class Arguments : AllStatic { static char* SharedArchivePath; public: - // Parses the arguments + // Parses the arguments, first phase static jint parse(const JavaVMInitArgs* args); + // Apply ergonomics + static jint apply_ergo(); // Adjusts the arguments after the OS have adjusted the arguments static jint adjust_after_os(); // Check for consistency in the selection of the garbage collector. @@ -445,6 +451,10 @@ class Arguments : AllStatic { // Used by os_solaris static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized); + static size_t conservative_max_heap_alignment() { return _conservative_max_heap_alignment; } + // Return the maximum size a heap with compressed oops can take + static size_t max_heap_for_compressed_oops(); + // return a char* array containing all options static char** jvm_flags_array() { return _jvm_flags_array; } static char** jvm_args_array() { return _jvm_args_array; } diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 0c83565195c..8f49f4a2edf 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -314,6 +314,11 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) { } } +void os::init_before_ergo() { + // We need to initialize large page support here because ergonomics takes some + // decisions depending on large page support and the calculated large page size. + large_page_init(); +} void os::signal_init() { if (!ReduceSignalUsage) { diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e43d68981cb..3438badb095 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -139,7 +139,10 @@ class os: AllStatic { public: static void init(void); // Called before command line parsing + static void init_before_ergo(void); // Called after command line parsing + // before VM ergonomics processing. static jint init_2(void); // Called after command line parsing + // and VM ergonomics processing static void init_globals(void) { // Called from init_globals() in init.cpp init_globals_ext(); } @@ -254,6 +257,11 @@ class os: AllStatic { static size_t page_size_for_region(size_t region_min_size, size_t region_max_size, uint min_pages); + // Return the largest page size that can be used + static size_t max_page_size() { + // The _page_sizes array is sorted in descending order. + return _page_sizes[0]; + } // Methods for tracing page sizes returned by the above method; enabled by // TracePageSizes. The region_{min,max}_size parameters should be the values diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index d5bc3a00006..02bd4b38f24 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -3329,6 +3329,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; + os::init_before_ergo(); + + jint ergo_result = Arguments::apply_ergo(); + if (ergo_result != JNI_OK) return ergo_result; + if (PauseAtStartup) { os::pause(); } diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java new file mode 100644 index 00000000000..852076e768e --- /dev/null +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* + * @test TestUseCompressedOopsErgo + * @key gc + * @bug 8010722 + * @summary Tests ergonomics for UseCompressedOops. + * @library /testlibrary /testlibrary/whitebox + * @build TestUseCompressedOopsErgo TestUseCompressedOopsErgoTools + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseG1GC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseParallelGC -XX:-UseParallelOldGC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseConcMarkSweepGC + * @run main/othervm TestUseCompressedOopsErgo -XX:+UseSerialGC + */ + +public class TestUseCompressedOopsErgo { + + public static void main(String args[]) throws Exception { + if (!TestUseCompressedOopsErgoTools.is64bitVM()) { + // this test is relevant for 64 bit VMs only + return; + } + final String[] gcFlags = args; + TestUseCompressedOopsErgoTools.checkCompressedOopsErgo(gcFlags); + } +} + diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java new file mode 100644 index 00000000000..49d0a8a1d21 --- /dev/null +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +import sun.management.ManagementFactoryHelper; +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.ArrayList; +import java.util.Arrays; + +import com.oracle.java.testlibrary.*; +import sun.hotspot.WhiteBox; + +class DetermineMaxHeapForCompressedOops { + public static void main(String[] args) throws Exception { + WhiteBox wb = WhiteBox.getWhiteBox(); + System.out.print(wb.getCompressedOopsMaxHeapSize()); + } +} + +class TestUseCompressedOopsErgoTools { + + private static long getClassMetaspaceSize() { + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + + VMOption option = diagnostic.getVMOption("ClassMetaspaceSize"); + return Long.parseLong(option.getValue()); + } + + + public static long getMaxHeapForCompressedOops(String[] vmargs) throws Exception { + OutputAnalyzer output = runWhiteBoxTest(vmargs, DetermineMaxHeapForCompressedOops.class.getName(), new String[] {}, false); + return Long.parseLong(output.getStdout()); + } + + public static boolean is64bitVM() { + String val = System.getProperty("sun.arch.data.model"); + if (val == null) { + throw new RuntimeException("Could not read sun.arch.data.model"); + } + if (val.equals("64")) { + return true; + } else if (val.equals("32")) { + return false; + } + throw new RuntimeException("Unexpected value " + val + " of sun.arch.data.model"); + } + + /** + * Executes a new VM process with the given class and parameters. + * @param vmargs Arguments to the VM to run + * @param classname Name of the class to run + * @param arguments Arguments to the class + * @param useTestDotJavaDotOpts Use test.java.opts as part of the VM argument string + * @return The OutputAnalyzer with the results for the invocation. + */ + public static OutputAnalyzer runWhiteBoxTest(String[] vmargs, String classname, String[] arguments, boolean useTestDotJavaDotOpts) throws Exception { + ArrayList finalargs = new ArrayList(); + + String[] whiteboxOpts = new String[] { + "-Xbootclasspath/a:.", + "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", + "-cp", System.getProperty("java.class.path"), + }; + + if (useTestDotJavaDotOpts) { + // System.getProperty("test.java.opts") is '' if no options is set, + // we need to skip such a result + String[] externalVMOpts = new String[0]; + if (System.getProperty("test.java.opts") != null && System.getProperty("test.java.opts").length() != 0) { + externalVMOpts = System.getProperty("test.java.opts").split(" "); + } + finalargs.addAll(Arrays.asList(externalVMOpts)); + } + + finalargs.addAll(Arrays.asList(vmargs)); + finalargs.addAll(Arrays.asList(whiteboxOpts)); + finalargs.add(classname); + finalargs.addAll(Arrays.asList(arguments)); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + return output; + } + + private static String[] join(String[] part1, String part2) { + ArrayList result = new ArrayList(); + result.addAll(Arrays.asList(part1)); + result.add(part2); + return result.toArray(new String[0]); + } + + public static void checkCompressedOopsErgo(String[] gcflags) throws Exception { + long maxHeapForCompressedOops = getMaxHeapForCompressedOops(gcflags); + + checkUseCompressedOops(gcflags, maxHeapForCompressedOops, true); + checkUseCompressedOops(gcflags, maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(gcflags, maxHeapForCompressedOops + 1, false); + + // the use of HeapBaseMinAddress should not change the outcome + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, "-XX:HeapBaseMinAddress=32G"), maxHeapForCompressedOops + 1, false); + + // use a different object alignment + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16")); + + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false); + + // use a different ClassMetaspaceSize + String classMetaspaceSizeArg = "-XX:ClassMetaspaceSize=" + 2 * getClassMetaspaceSize(); + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, classMetaspaceSizeArg)); + + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops + 1, false); + } + + private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception { + ArrayList finalargs = new ArrayList(); + finalargs.addAll(Arrays.asList(args)); + finalargs.add("-Xmx" + heapsize); + finalargs.add("-XX:+PrintFlagsFinal"); + finalargs.add("-version"); + + String output = expectValid(finalargs.toArray(new String[0])); + + boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output); + + if (expectUseCompressedOops != actualUseCompressedOops) { + throw new RuntimeException("Expected use of compressed oops: " + expectUseCompressedOops + " but was: " + actualUseCompressedOops); + } + } + + private static boolean getFlagBoolValue(String flag, String where) { + Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where); + if (!m.find()) { + throw new RuntimeException("Could not find value for flag " + flag + " in output string"); + } + String match = m.group(1).equals("true"); + } + + private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(errorcode); + return output.getStdout(); + } + + private static String expectValid(String[] flags) throws Exception { + return expect(flags, false, false, 0); + } +} + diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index c508b8f121a..091b5f7543b 100644 --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -61,6 +61,8 @@ public class WhiteBox { registerNatives(); } + // Get the maximum heap size supporting COOPs + public native long getCompressedOopsMaxHeapSize(); // Arguments public native void printHeapSizes(); From 091edb47c5295609b2b64ef32e7075d2008b656d Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Wed, 11 Sep 2013 20:03:34 -0400 Subject: [PATCH 079/293] 8024007: Misc. cleanup of static agent code Minor cleanup of static agent code from 8014135 Reviewed-by: dcubed, sspitsyn --- hotspot/src/os/windows/vm/os_windows.cpp | 2 +- hotspot/src/share/vm/prims/jvmti.xml | 6 ++++-- hotspot/src/share/vm/runtime/arguments.hpp | 2 +- hotspot/src/share/vm/runtime/os.cpp | 5 +++-- hotspot/src/share/vm/runtime/thread.cpp | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 015f94d6662..d6dbde4c929 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -5429,7 +5429,7 @@ char* os::build_agent_function_name(const char *sym_name, const char *lib_name, if ((start = strrchr(lib_name, *os::file_separator())) != NULL) { lib_name = ++start; } else { - // Need to check for C: + // Need to check for drive prefix if ((start = strchr(lib_name, ':')) != NULL) { lib_name = ++start; } diff --git a/hotspot/src/share/vm/prims/jvmti.xml b/hotspot/src/share/vm/prims/jvmti.xml index 87a28ae0cfc..98a0a0640aa 100644 --- a/hotspot/src/share/vm/prims/jvmti.xml +++ b/hotspot/src/share/vm/prims/jvmti.xml @@ -458,8 +458,10 @@ the same name from being loaded dynamically.

The VM will invoke the Agent_OnUnload_L function of the agent, if such - a function is exported, at the same point during startup as it would - have called the dynamic entry point Agent_OnUnLoad. + a function is exported, at the same point during VM execution as it would + have called the dynamic entry point Agent_OnUnLoad. A statically loaded + agent cannot be unloaded. The Agent_OnUnload_L function will still be + called to do any other agent shutdown related tasks. If a statically linked agent L exports a function called Agent_OnUnLoad_L and a function called Agent_OnUnLoad, the Agent_OnUnLoad function will be ignored. diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 43256b75082..6b8eb305aae 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -144,7 +144,7 @@ public: void set_os_lib(void* os_lib) { _os_lib = os_lib; } AgentLibrary* next() const { return _next; } bool is_static_lib() const { return _is_static_lib; } - void set_static_lib(bool static_lib) { _is_static_lib = static_lib; } + void set_static_lib(bool is_static_lib) { _is_static_lib = is_static_lib; } bool valid() { return (_state == agent_valid); } void set_valid() { _state = agent_valid; } void set_invalid() { _state = agent_invalid; } diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp index 0c83565195c..f85f1237f14 100644 --- a/hotspot/src/share/vm/runtime/os.cpp +++ b/hotspot/src/share/vm/runtime/os.cpp @@ -454,6 +454,7 @@ void* os::native_java_library() { */ void* os::find_agent_function(AgentLibrary *agent_lib, bool check_lib, const char *syms[], size_t syms_len) { + assert(agent_lib != NULL, "sanity check"); const char *lib_name; void *handle = agent_lib->os_lib(); void *entryName = NULL; @@ -484,6 +485,7 @@ bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[], void *proc_handle; void *save_handle; + assert(agent_lib != NULL, "sanity check"); if (agent_lib->name() == NULL) { return false; } @@ -493,14 +495,13 @@ bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[], // We want to look in this process' symbol table. agent_lib->set_os_lib(proc_handle); ret = find_agent_function(agent_lib, true, syms, syms_len); - agent_lib->set_os_lib(save_handle); if (ret != NULL) { // Found an entry point like Agent_OnLoad_lib_name so we have a static agent - agent_lib->set_os_lib(proc_handle); agent_lib->set_valid(); agent_lib->set_static_lib(true); return true; } + agent_lib->set_os_lib(save_handle); return false; } diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index d5bc3a00006..2745703b598 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -3714,7 +3714,7 @@ static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_sym const char *name = agent->name(); const char *msg = "Could not find agent library "; - // First check to see if agent is statcally linked into executable + // First check to see if agent is statically linked into executable if (os::find_builtin_agent(agent, on_load_symbols, num_symbol_entries)) { library = agent->os_lib(); } else if (agent->is_absolute_path()) { From dfd2d9a574dc868c3a9bd0515e61b04873b358f3 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Thu, 12 Sep 2013 10:15:30 +0200 Subject: [PATCH 080/293] 8023476: Metaspace capacity > reserved Reviewed-by: stefank, hseigel, mgerdin --- .../share/vm/gc_interface/collectedHeap.cpp | 6 +- hotspot/src/share/vm/memory/metaspace.cpp | 85 +++++++++++-------- hotspot/src/share/vm/memory/metaspace.hpp | 58 ++++--------- .../src/share/vm/memory/metaspaceCounters.cpp | 16 ++-- 4 files changed, 80 insertions(+), 85 deletions(-) diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp index 3af380049bb..3f5364b79c0 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp @@ -87,15 +87,15 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() { const MetaspaceSizes meta_space( MetaspaceAux::allocated_capacity_bytes(), MetaspaceAux::allocated_used_bytes(), - MetaspaceAux::reserved_in_bytes()); + MetaspaceAux::reserved_bytes()); const MetaspaceSizes data_space( MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType), MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType), - MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType)); + MetaspaceAux::reserved_bytes(Metaspace::NonClassType)); const MetaspaceSizes class_space( MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType), MetaspaceAux::allocated_used_bytes(Metaspace::ClassType), - MetaspaceAux::reserved_in_bytes(Metaspace::ClassType)); + MetaspaceAux::reserved_bytes(Metaspace::ClassType)); return MetaspaceSummary(meta_space, data_space, class_space); } diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 63e6be716da..e8117f7fae9 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -177,8 +177,8 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { void return_chunks(ChunkIndex index, Metachunk* chunks); // Total of the space in the free chunks list - size_t free_chunks_total(); - size_t free_chunks_total_in_bytes(); + size_t free_chunks_total_words(); + size_t free_chunks_total_bytes(); // Number of chunks in the free chunks list size_t free_chunks_count(); @@ -1080,12 +1080,12 @@ size_t VirtualSpaceList::used_words_sum() { // Sum used region [bottom, top) in each virtualspace allocated_by_vs += vsl->used_words_in_vs(); } - assert(allocated_by_vs >= chunk_manager()->free_chunks_total(), + assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(), err_msg("Total in free chunks " SIZE_FORMAT " greater than total from virtual_spaces " SIZE_FORMAT, - allocated_by_vs, chunk_manager()->free_chunks_total())); + allocated_by_vs, chunk_manager()->free_chunks_total_words())); size_t used = - allocated_by_vs - chunk_manager()->free_chunks_total(); + allocated_by_vs - chunk_manager()->free_chunks_total_words(); return used; } @@ -1526,7 +1526,7 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm, sm->sum_count_in_chunks_in_use()); dummy_chunk->print_on(gclog_or_tty); gclog_or_tty->print_cr(" Free chunks total %d count %d", - vsl->chunk_manager()->free_chunks_total(), + vsl->chunk_manager()->free_chunks_total_words(), vsl->chunk_manager()->free_chunks_count()); } } @@ -1583,12 +1583,12 @@ bool Metadebug::test_metadata_failure() { // ChunkManager methods -size_t ChunkManager::free_chunks_total() { +size_t ChunkManager::free_chunks_total_words() { return _free_chunks_total; } -size_t ChunkManager::free_chunks_total_in_bytes() { - return free_chunks_total() * BytesPerWord; +size_t ChunkManager::free_chunks_total_bytes() { + return free_chunks_total_words() * BytesPerWord; } size_t ChunkManager::free_chunks_count() { @@ -2567,13 +2567,13 @@ size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) { return used * BytesPerWord; } -size_t MetaspaceAux::free_in_bytes(Metaspace::MetadataType mdtype) { +size_t MetaspaceAux::free_bytes_slow(Metaspace::MetadataType mdtype) { size_t free = 0; ClassLoaderDataGraphMetaspaceIterator iter; while (iter.repeat()) { Metaspace* msp = iter.get_next(); if (msp != NULL) { - free += msp->free_words(mdtype); + free += msp->free_words_slow(mdtype); } } return free * BytesPerWord; @@ -2596,34 +2596,51 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) { return capacity * BytesPerWord; } -size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) { - VirtualSpaceList* list = Metaspace::get_space_list(mdtype); - return list == NULL ? 0 : list->virtual_space_total(); +size_t MetaspaceAux::capacity_bytes_slow() { +#ifdef PRODUCT + // Use allocated_capacity_bytes() in PRODUCT instead of this function. + guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT"); +#endif + size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType); + size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType); + assert(allocated_capacity_bytes() == class_capacity + non_class_capacity, + err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT + " class_capacity + non_class_capacity " SIZE_FORMAT + " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT, + allocated_capacity_bytes(), class_capacity + non_class_capacity, + class_capacity, non_class_capacity)); + + return class_capacity + non_class_capacity; } -size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); } +size_t MetaspaceAux::reserved_bytes(Metaspace::MetadataType mdtype) { + VirtualSpaceList* list = Metaspace::get_space_list(mdtype); + return list == NULL ? 0 : list->virtual_space_total() * BytesPerWord; +} -size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) { +size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } + +size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { VirtualSpaceList* list = Metaspace::get_space_list(mdtype); if (list == NULL) { return 0; } ChunkManager* chunk = list->chunk_manager(); chunk->slow_verify(); - return chunk->free_chunks_total(); + return chunk->free_chunks_total_words(); } -size_t MetaspaceAux::free_chunks_total_in_bytes(Metaspace::MetadataType mdtype) { - return free_chunks_total(mdtype) * BytesPerWord; +size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { + return free_chunks_total_words(mdtype) * BytesPerWord; } -size_t MetaspaceAux::free_chunks_total() { - return free_chunks_total(Metaspace::ClassType) + - free_chunks_total(Metaspace::NonClassType); +size_t MetaspaceAux::free_chunks_total_words() { + return free_chunks_total_words(Metaspace::ClassType) + + free_chunks_total_words(Metaspace::NonClassType); } -size_t MetaspaceAux::free_chunks_total_in_bytes() { - return free_chunks_total() * BytesPerWord; +size_t MetaspaceAux::free_chunks_total_bytes() { + return free_chunks_total_words() * BytesPerWord; } void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) { @@ -2634,14 +2651,14 @@ void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) { "(" SIZE_FORMAT ")", prev_metadata_used, allocated_used_bytes(), - reserved_in_bytes()); + reserved_bytes()); } else { gclog_or_tty->print(" " SIZE_FORMAT "K" "->" SIZE_FORMAT "K" "(" SIZE_FORMAT "K)", - prev_metadata_used / K, - allocated_used_bytes() / K, - reserved_in_bytes()/ K); + prev_metadata_used/K, + allocated_used_bytes()/K, + reserved_bytes()/K); } gclog_or_tty->print("]"); @@ -2654,14 +2671,14 @@ void MetaspaceAux::print_on(outputStream* out) { out->print_cr(" Metaspace total " SIZE_FORMAT "K, used " SIZE_FORMAT "K," " reserved " SIZE_FORMAT "K", - allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K); + allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_bytes()/K); out->print_cr(" data space " SIZE_FORMAT "K, used " SIZE_FORMAT "K," " reserved " SIZE_FORMAT "K", allocated_capacity_bytes(nct)/K, allocated_used_bytes(nct)/K, - reserved_in_bytes(nct)/K); + reserved_bytes(nct)/K); if (Metaspace::using_class_space()) { Metaspace::MetadataType ct = Metaspace::ClassType; out->print_cr(" class space " @@ -2669,17 +2686,17 @@ void MetaspaceAux::print_on(outputStream* out) { " reserved " SIZE_FORMAT "K", allocated_capacity_bytes(ct)/K, allocated_used_bytes(ct)/K, - reserved_in_bytes(ct)/K); + reserved_bytes(ct)/K); } } // Print information for class space and data space separately. // This is almost the same as above. void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { - size_t free_chunks_capacity_bytes = free_chunks_total_in_bytes(mdtype); + size_t free_chunks_capacity_bytes = free_chunks_total_bytes(mdtype); size_t capacity_bytes = capacity_bytes_slow(mdtype); size_t used_bytes = used_bytes_slow(mdtype); - size_t free_bytes = free_in_bytes(mdtype); + size_t free_bytes = free_bytes_slow(mdtype); size_t used_and_free = used_bytes + free_bytes + free_chunks_capacity_bytes; out->print_cr(" Chunk accounting: used in chunks " SIZE_FORMAT @@ -3132,7 +3149,7 @@ size_t Metaspace::used_words_slow(MetadataType mdtype) const { } } -size_t Metaspace::free_words(MetadataType mdtype) const { +size_t Metaspace::free_words_slow(MetadataType mdtype) const { if (mdtype == ClassType) { return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0; } else { diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 591acf30075..b51c80be0e6 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -182,9 +182,8 @@ class Metaspace : public CHeapObj { char* bottom() const; size_t used_words_slow(MetadataType mdtype) const; - size_t free_words(MetadataType mdtype) const; + size_t free_words_slow(MetadataType mdtype) const; size_t capacity_words_slow(MetadataType mdtype) const; - size_t waste_words(MetadataType mdtype) const; size_t used_bytes_slow(MetadataType mdtype) const; size_t capacity_bytes_slow(MetadataType mdtype) const; @@ -221,19 +220,14 @@ class Metaspace : public CHeapObj { }; class MetaspaceAux : AllStatic { - static size_t free_chunks_total(Metaspace::MetadataType mdtype); - - public: - // Statistics for class space and data space in metaspace. + static size_t free_chunks_total_words(Metaspace::MetadataType mdtype); // These methods iterate over the classloader data graph // for the given Metaspace type. These are slow. static size_t used_bytes_slow(Metaspace::MetadataType mdtype); - static size_t free_in_bytes(Metaspace::MetadataType mdtype); + static size_t free_bytes_slow(Metaspace::MetadataType mdtype); static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype); - - // Iterates over the virtual space list. - static size_t reserved_in_bytes(Metaspace::MetadataType mdtype); + static size_t capacity_bytes_slow(); // Running sum of space in all Metachunks that has been // allocated to a Metaspace. This is used instead of @@ -263,17 +257,16 @@ class MetaspaceAux : AllStatic { } // Used by MetaspaceCounters - static size_t free_chunks_total(); - static size_t free_chunks_total_in_bytes(); - static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); + static size_t free_chunks_total_words(); + static size_t free_chunks_total_bytes(); + static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype); static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) { return _allocated_capacity_words[mdtype]; } static size_t allocated_capacity_words() { - return _allocated_capacity_words[Metaspace::NonClassType] + - (Metaspace::using_class_space() ? - _allocated_capacity_words[Metaspace::ClassType] : 0); + return allocated_capacity_words(Metaspace::NonClassType) + + allocated_capacity_words(Metaspace::ClassType); } static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) { return allocated_capacity_words(mdtype) * BytesPerWord; @@ -286,9 +279,8 @@ class MetaspaceAux : AllStatic { return _allocated_used_words[mdtype]; } static size_t allocated_used_words() { - return _allocated_used_words[Metaspace::NonClassType] + - (Metaspace::using_class_space() ? - _allocated_used_words[Metaspace::ClassType] : 0); + return allocated_used_words(Metaspace::NonClassType) + + allocated_used_words(Metaspace::ClassType); } static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) { return allocated_used_words(mdtype) * BytesPerWord; @@ -301,31 +293,17 @@ class MetaspaceAux : AllStatic { static size_t free_bytes(Metaspace::MetadataType mdtype); // Total capacity in all Metaspaces - static size_t capacity_bytes_slow() { -#ifdef PRODUCT - // Use allocated_capacity_bytes() in PRODUCT instead of this function. - guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT"); -#endif - size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType); - size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType); - assert(allocated_capacity_bytes() == class_capacity + non_class_capacity, - err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT - " class_capacity + non_class_capacity " SIZE_FORMAT - " class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT, - allocated_capacity_bytes(), class_capacity + non_class_capacity, - class_capacity, non_class_capacity)); - - return class_capacity + non_class_capacity; + static size_t reserved_bytes(Metaspace::MetadataType mdtype); + static size_t reserved_bytes() { + return reserved_bytes(Metaspace::ClassType) + + reserved_bytes(Metaspace::NonClassType); } - // Total space reserved in all Metaspaces - static size_t reserved_in_bytes() { - return reserved_in_bytes(Metaspace::ClassType) + - reserved_in_bytes(Metaspace::NonClassType); + static size_t min_chunk_size_words(); + static size_t min_chunk_size_bytes() { + return min_chunk_size_words() * BytesPerWord; } - static size_t min_chunk_size(); - // Print change in used metadata. static void print_metaspace_change(size_t prev_metadata_used); static void print_on(outputStream * out); diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp index 32eda2b4ed8..6f443466ffb 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp @@ -71,7 +71,7 @@ size_t MetaspaceCounters::calculate_capacity() { // 2) unused space at the end of each Metachunk // 3) space in the freelist size_t total_capacity = MetaspaceAux::allocated_capacity_bytes() - + MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_in_bytes(); + + MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_bytes(); return total_capacity; } @@ -79,9 +79,9 @@ void MetaspaceCounters::initialize_performance_counters() { if (UsePerfData) { assert(_perf_counters == NULL, "Should only be initialized once"); - size_t min_capacity = MetaspaceAux::min_chunk_size(); + size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(); + size_t max_capacity = MetaspaceAux::reserved_bytes(); size_t used = MetaspaceAux::allocated_used_bytes(); _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used); @@ -93,7 +93,7 @@ void MetaspaceCounters::update_performance_counters() { assert(_perf_counters != NULL, "Should be initialized"); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(); + size_t max_capacity = MetaspaceAux::reserved_bytes(); size_t used = MetaspaceAux::allocated_used_bytes(); _perf_counters->update(capacity, max_capacity, used); @@ -105,7 +105,7 @@ MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL; size_t CompressedClassSpaceCounters::calculate_capacity() { return MetaspaceAux::allocated_capacity_bytes(_class_type) + MetaspaceAux::free_bytes(_class_type) + - MetaspaceAux::free_chunks_total_in_bytes(_class_type); + MetaspaceAux::free_chunks_total_bytes(_class_type); } void CompressedClassSpaceCounters::update_performance_counters() { @@ -113,7 +113,7 @@ void CompressedClassSpaceCounters::update_performance_counters() { assert(_perf_counters != NULL, "Should be initialized"); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type); + size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); size_t used = MetaspaceAux::allocated_used_bytes(_class_type); _perf_counters->update(capacity, max_capacity, used); @@ -126,9 +126,9 @@ void CompressedClassSpaceCounters::initialize_performance_counters() { const char* ns = "compressedclassspace"; if (UseCompressedClassPointers) { - size_t min_capacity = MetaspaceAux::min_chunk_size(); + size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type); + size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); size_t used = MetaspaceAux::allocated_used_bytes(_class_type); _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used); From 8a515de48c15b44fbbe2abef6bc50b4391d93788 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Thu, 12 Sep 2013 10:15:54 +0200 Subject: [PATCH 081/293] 8024638: Count and expose the amount of committed memory in the metaspaces Reviewed-by: brutisso, ehelin --- hotspot/src/share/vm/memory/metaspace.cpp | 182 +++++++++++++----- hotspot/src/share/vm/memory/metaspace.hpp | 7 +- hotspot/src/share/vm/prims/jni.cpp | 4 + hotspot/src/share/vm/runtime/virtualspace.cpp | 139 +++++++++++++ hotspot/src/share/vm/runtime/virtualspace.hpp | 13 +- 5 files changed, 289 insertions(+), 56 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index e8117f7fae9..1dd97842eb4 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -291,6 +291,10 @@ class VirtualSpaceNode : public CHeapObj { MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } + size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; } + size_t expanded_words() const { return _virtual_space.committed_size() / BytesPerWord; } + size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; } + // address of next available space in _virtual_space; // Accessors VirtualSpaceNode* next() { return _next; } @@ -327,12 +331,10 @@ class VirtualSpaceNode : public CHeapObj { // Allocate a chunk from the virtual space and return it. Metachunk* get_chunk_vs(size_t chunk_word_size); - Metachunk* get_chunk_vs_with_expand(size_t chunk_word_size); // Expands/shrinks the committed space in a virtual space. Delegates // to Virtualspace bool expand_by(size_t words, bool pre_touch = false); - bool shrink_by(size_t words); // In preparation for deleting this node, remove all the chunks // in the node from any freelist. @@ -340,8 +342,6 @@ class VirtualSpaceNode : public CHeapObj { #ifdef ASSERT // Debug support - static void verify_virtual_space_total(); - static void verify_virtual_space_count(); void mangle(); #endif @@ -429,8 +429,11 @@ class VirtualSpaceList : public CHeapObj { bool _is_class; bool can_grow() const { return !is_class() || !UseCompressedClassPointers; } - // Sum of space in all virtual spaces and number of virtual spaces - size_t _virtual_space_total; + // Sum of reserved and committed memory in the virtual spaces + size_t _reserved_words; + size_t _committed_words; + + // Number of virtual spaces size_t _virtual_space_count; ~VirtualSpaceList(); @@ -444,7 +447,7 @@ class VirtualSpaceList : public CHeapObj { _current_virtual_space = v; } - void link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size); + void link_vs(VirtualSpaceNode* new_entry); // Get another virtual space and add it to the list. This // is typically prompted by a failed attempt to allocate a chunk @@ -461,6 +464,8 @@ class VirtualSpaceList : public CHeapObj { size_t grow_chunks_by_words, size_t medium_chunk_bunch); + bool expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch = false); + // Get the first chunk for a Metaspace. Used for // special cases such as the boot class loader, reflection // class loader and anonymous class loader. @@ -476,10 +481,15 @@ class VirtualSpaceList : public CHeapObj { // Allocate the first virtualspace. void initialize(size_t word_size); - size_t virtual_space_total() { return _virtual_space_total; } + size_t reserved_words() { return _reserved_words; } + size_t reserved_bytes() { return reserved_words() * BytesPerWord; } + size_t committed_words() { return _committed_words; } + size_t committed_bytes() { return committed_words() * BytesPerWord; } - void inc_virtual_space_total(size_t v); - void dec_virtual_space_total(size_t v); + void inc_reserved_words(size_t v); + void dec_reserved_words(size_t v); + void inc_committed_words(size_t v); + void dec_committed_words(size_t v); void inc_virtual_space_count(); void dec_virtual_space_count(); @@ -901,15 +911,6 @@ bool VirtualSpaceNode::expand_by(size_t words, bool pre_touch) { return result; } -// Shrink the virtual space (commit more of the reserved space) -bool VirtualSpaceNode::shrink_by(size_t words) { - size_t bytes = words * BytesPerWord; - virtual_space()->shrink_by(bytes); - return true; -} - -// Add another chunk to the chunk list. - Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) { assert_lock_strong(SpaceManager::expand_lock()); Metachunk* result = take_from_committed(chunk_word_size); @@ -919,23 +920,6 @@ Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) { return result; } -Metachunk* VirtualSpaceNode::get_chunk_vs_with_expand(size_t chunk_word_size) { - assert_lock_strong(SpaceManager::expand_lock()); - - Metachunk* new_chunk = get_chunk_vs(chunk_word_size); - - if (new_chunk == NULL) { - // Only a small part of the virtualspace is committed when first - // allocated so committing more here can be expected. - size_t page_size_words = os::vm_page_size() / BytesPerWord; - size_t aligned_expand_vs_by_words = align_size_up(chunk_word_size, - page_size_words); - expand_by(aligned_expand_vs_by_words, false); - new_chunk = get_chunk_vs(chunk_word_size); - } - return new_chunk; -} - bool VirtualSpaceNode::initialize() { if (!_rs.is_reserved()) { @@ -995,13 +979,22 @@ VirtualSpaceList::~VirtualSpaceList() { } } -void VirtualSpaceList::inc_virtual_space_total(size_t v) { +void VirtualSpaceList::inc_reserved_words(size_t v) { assert_lock_strong(SpaceManager::expand_lock()); - _virtual_space_total = _virtual_space_total + v; + _reserved_words = _reserved_words + v; } -void VirtualSpaceList::dec_virtual_space_total(size_t v) { +void VirtualSpaceList::dec_reserved_words(size_t v) { assert_lock_strong(SpaceManager::expand_lock()); - _virtual_space_total = _virtual_space_total - v; + _reserved_words = _reserved_words - v; +} + +void VirtualSpaceList::inc_committed_words(size_t v) { + assert_lock_strong(SpaceManager::expand_lock()); + _committed_words = _committed_words + v; +} +void VirtualSpaceList::dec_committed_words(size_t v) { + assert_lock_strong(SpaceManager::expand_lock()); + _committed_words = _committed_words - v; } void VirtualSpaceList::inc_virtual_space_count() { @@ -1052,7 +1045,8 @@ void VirtualSpaceList::purge() { } vsl->purge(chunk_manager()); - dec_virtual_space_total(vsl->reserved()->word_size()); + dec_reserved_words(vsl->reserved_words()); + dec_committed_words(vsl->committed_words()); dec_virtual_space_count(); purged_vsl = vsl; delete vsl; @@ -1106,7 +1100,8 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) : _is_class(false), _virtual_space_list(NULL), _current_virtual_space(NULL), - _virtual_space_total(0), + _reserved_words(0), + _committed_words(0), _virtual_space_count(0) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); @@ -1123,7 +1118,8 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) : _is_class(true), _virtual_space_list(NULL), _current_virtual_space(NULL), - _virtual_space_total(0), + _reserved_words(0), + _committed_words(0), _virtual_space_count(0) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); @@ -1133,7 +1129,7 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) : _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk); _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk); assert(succeeded, " VirtualSpaceList initialization should not fail"); - link_vs(class_entry, rs.size()/BytesPerWord); + link_vs(class_entry); } size_t VirtualSpaceList::free_bytes() { @@ -1156,21 +1152,23 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) { delete new_entry; return false; } else { + assert(new_entry->reserved_words() == vs_word_size, "Must be"); // ensure lock-free iteration sees fully initialized node OrderAccess::storestore(); - link_vs(new_entry, vs_word_size); + link_vs(new_entry); return true; } } -void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) { +void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry) { if (virtual_space_list() == NULL) { set_virtual_space_list(new_entry); } else { current_virtual_space()->set_next(new_entry); } set_current_virtual_space(new_entry); - inc_virtual_space_total(vs_word_size); + inc_reserved_words(new_entry->reserved_words()); + inc_committed_words(new_entry->committed_words()); inc_virtual_space_count(); #ifdef ASSERT new_entry->mangle(); @@ -1181,6 +1179,20 @@ void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) } } +bool VirtualSpaceList::expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch) { + size_t before = node->committed_words(); + + bool result = node->expand_by(word_size, pre_touch); + + size_t after = node->committed_words(); + + // after and before can be the same if the memory was pre-committed. + assert(after >= before, "Must be"); + inc_committed_words(after - before); + + return result; +} + Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, size_t grow_chunks_by_words, size_t medium_chunk_bunch) { @@ -1204,7 +1216,7 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words, page_size_words); bool vs_expanded = - current_virtual_space()->expand_by(aligned_expand_vs_by_words, false); + expand_by(current_virtual_space(), aligned_expand_vs_by_words); if (!vs_expanded) { // Should the capacity of the metaspaces be expanded for // this allocation? If it's the virtual space for classes and is @@ -1215,7 +1227,14 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words); if (grow_vs(grow_vs_words)) { // Got it. It's on the list now. Get a chunk from it. - next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words); + assert(current_virtual_space()->expanded_words() == 0, + "New virtuals space nodes should not have expanded"); + + size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words, + page_size_words); + // We probably want to expand by aligned_expand_vs_by_words here. + expand_by(current_virtual_space(), grow_chunks_by_words_aligned); + next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); } } else { // Allocation will fail and induce a GC @@ -1325,7 +1344,7 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { // reserved space, because this is a larger space prereserved for compressed // class pointers. if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { - size_t real_allocated = Metaspace::space_list()->virtual_space_total() + + size_t real_allocated = Metaspace::space_list()->reserved_words() + MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); if (real_allocated >= MaxMetaspaceSize) { return false; @@ -2615,7 +2634,12 @@ size_t MetaspaceAux::capacity_bytes_slow() { size_t MetaspaceAux::reserved_bytes(Metaspace::MetadataType mdtype) { VirtualSpaceList* list = Metaspace::get_space_list(mdtype); - return list == NULL ? 0 : list->virtual_space_total() * BytesPerWord; + return list == NULL ? 0 : list->reserved_bytes(); +} + +size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) { + VirtualSpaceList* list = Metaspace::get_space_list(mdtype); + return list == NULL ? 0 : list->committed_bytes(); } size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } @@ -3357,3 +3381,59 @@ void Metaspace::dump(outputStream* const out) const { class_vsm()->dump(out); } } + +/////////////// Unit tests /////////////// + +#ifndef PRODUCT + +class MetaspaceAuxTest : AllStatic { + public: + static void test_reserved() { + size_t reserved = MetaspaceAux::reserved_bytes(); + + assert(reserved > 0, "assert"); + + size_t committed = MetaspaceAux::committed_bytes(); + assert(committed <= reserved, "assert"); + + size_t reserved_metadata = MetaspaceAux::reserved_bytes(Metaspace::NonClassType); + assert(reserved_metadata > 0, "assert"); + assert(reserved_metadata <= reserved, "assert"); + + if (UseCompressedClassPointers) { + size_t reserved_class = MetaspaceAux::reserved_bytes(Metaspace::ClassType); + assert(reserved_class > 0, "assert"); + assert(reserved_class < reserved, "assert"); + } + } + + static void test_committed() { + size_t committed = MetaspaceAux::committed_bytes(); + + assert(committed > 0, "assert"); + + size_t reserved = MetaspaceAux::reserved_bytes(); + assert(committed <= reserved, "assert"); + + size_t committed_metadata = MetaspaceAux::committed_bytes(Metaspace::NonClassType); + assert(committed_metadata > 0, "assert"); + assert(committed_metadata <= committed, "assert"); + + if (UseCompressedClassPointers) { + size_t committed_class = MetaspaceAux::committed_bytes(Metaspace::ClassType); + assert(committed_class > 0, "assert"); + assert(committed_class < committed, "assert"); + } + } + + static void test() { + test_reserved(); + test_committed(); + } +}; + +void MetaspaceAux_test() { + MetaspaceAuxTest::test(); +} + +#endif diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index b51c80be0e6..242fa61b1cc 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -292,13 +292,18 @@ class MetaspaceAux : AllStatic { static size_t free_bytes(); static size_t free_bytes(Metaspace::MetadataType mdtype); - // Total capacity in all Metaspaces static size_t reserved_bytes(Metaspace::MetadataType mdtype); static size_t reserved_bytes() { return reserved_bytes(Metaspace::ClassType) + reserved_bytes(Metaspace::NonClassType); } + static size_t committed_bytes(Metaspace::MetadataType mdtype); + static size_t committed_bytes() { + return committed_bytes(Metaspace::ClassType) + + committed_bytes(Metaspace::NonClassType); + } + static size_t min_chunk_size_words(); static size_t min_chunk_size_bytes() { return min_chunk_size_words() * BytesPerWord; diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index ea44e2c6679..16457a8cd6e 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5048,12 +5048,16 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) { // Forward declaration void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); +void TestVirtualSpace_test(); +void MetaspaceAux_test(); void execute_internal_vm_tests() { if (ExecuteInternalVMTests) { tty->print_cr("Running internal VM tests"); run_unit_test(TestReservedSpace_test()); run_unit_test(TestReserveMemorySpecial_test()); + run_unit_test(TestVirtualSpace_test()); + run_unit_test(MetaspaceAux_test()); run_unit_test(GlobalDefinitions::test_globals()); run_unit_test(GCTimerAllTest::all()); run_unit_test(arrayOopDesc::test_max_array_length()); diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index 9e01fe0292f..b7724a6a082 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -453,6 +453,42 @@ size_t VirtualSpace::uncommitted_size() const { return reserved_size() - committed_size(); } +size_t VirtualSpace::actual_committed_size() const { + // Special VirtualSpaces commit all reserved space up front. + if (special()) { + return reserved_size(); + } + + size_t committed_low = pointer_delta(_lower_high, _low_boundary, sizeof(char)); + size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary, sizeof(char)); + size_t committed_high = pointer_delta(_upper_high, _middle_high_boundary, sizeof(char)); + +#ifdef ASSERT + size_t lower = pointer_delta(_lower_high_boundary, _low_boundary, sizeof(char)); + size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary, sizeof(char)); + size_t upper = pointer_delta(_upper_high_boundary, _middle_high_boundary, sizeof(char)); + + if (committed_high > 0) { + assert(committed_low == lower, "Must be"); + assert(committed_middle == middle, "Must be"); + } + + if (committed_middle > 0) { + assert(committed_low == lower, "Must be"); + } + if (committed_middle < middle) { + assert(committed_high == 0, "Must be"); + } + + if (committed_low < lower) { + assert(committed_high == 0, "Must be"); + assert(committed_middle == 0, "Must be"); + } +#endif + + return committed_low + committed_middle + committed_high; +} + bool VirtualSpace::contains(const void* p) const { return low() <= (const char*) p && (const char*) p < high(); @@ -910,6 +946,109 @@ void TestReservedSpace_test() { TestReservedSpace::test_reserved_space(); } +#define assert_equals(actual, expected) \ + assert(actual == expected, \ + err_msg("Got " SIZE_FORMAT " expected " \ + SIZE_FORMAT, actual, expected)); + +#define assert_ge(value1, value2) \ + assert(value1 >= value2, \ + err_msg("'" #value1 "': " SIZE_FORMAT " '" \ + #value2 "': " SIZE_FORMAT, value1, value2)); + +#define assert_lt(value1, value2) \ + assert(value1 < value2, \ + err_msg("'" #value1 "': " SIZE_FORMAT " '" \ + #value2 "': " SIZE_FORMAT, value1, value2)); + + +class TestVirtualSpace : AllStatic { + public: + static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size) { + size_t granularity = os::vm_allocation_granularity(); + size_t reserve_size_aligned = align_size_up(reserve_size, granularity); + + ReservedSpace reserved(reserve_size_aligned); + + assert(reserved.is_reserved(), "Must be"); + + VirtualSpace vs; + bool initialized = vs.initialize(reserved, 0); + assert(initialized, "Failed to initialize VirtualSpace"); + + vs.expand_by(commit_size, false); + + if (vs.special()) { + assert_equals(vs.actual_committed_size(), reserve_size_aligned); + } else { + assert_ge(vs.actual_committed_size(), commit_size); + // Approximate the commit granularity. + size_t commit_granularity = UseLargePages ? os::large_page_size() : os::vm_page_size(); + assert_lt(vs.actual_committed_size(), commit_size + commit_granularity); + } + + reserved.release(); + } + + static void test_virtual_space_actual_committed_space_one_large_page() { + if (!UseLargePages) { + return; + } + + size_t large_page_size = os::large_page_size(); + + ReservedSpace reserved(large_page_size, large_page_size, true, false); + + assert(reserved.is_reserved(), "Must be"); + + VirtualSpace vs; + bool initialized = vs.initialize(reserved, 0); + assert(initialized, "Failed to initialize VirtualSpace"); + + vs.expand_by(large_page_size, false); + + assert_equals(vs.actual_committed_size(), large_page_size); + + reserved.release(); + } + + static void test_virtual_space_actual_committed_space() { + test_virtual_space_actual_committed_space(4 * K, 0); + test_virtual_space_actual_committed_space(4 * K, 4 * K); + test_virtual_space_actual_committed_space(8 * K, 0); + test_virtual_space_actual_committed_space(8 * K, 4 * K); + test_virtual_space_actual_committed_space(8 * K, 8 * K); + test_virtual_space_actual_committed_space(12 * K, 0); + test_virtual_space_actual_committed_space(12 * K, 4 * K); + test_virtual_space_actual_committed_space(12 * K, 8 * K); + test_virtual_space_actual_committed_space(12 * K, 12 * K); + test_virtual_space_actual_committed_space(64 * K, 0); + test_virtual_space_actual_committed_space(64 * K, 32 * K); + test_virtual_space_actual_committed_space(64 * K, 64 * K); + test_virtual_space_actual_committed_space(2 * M, 0); + test_virtual_space_actual_committed_space(2 * M, 4 * K); + test_virtual_space_actual_committed_space(2 * M, 64 * K); + test_virtual_space_actual_committed_space(2 * M, 1 * M); + test_virtual_space_actual_committed_space(2 * M, 2 * M); + test_virtual_space_actual_committed_space(10 * M, 0); + test_virtual_space_actual_committed_space(10 * M, 4 * K); + test_virtual_space_actual_committed_space(10 * M, 8 * K); + test_virtual_space_actual_committed_space(10 * M, 1 * M); + test_virtual_space_actual_committed_space(10 * M, 2 * M); + test_virtual_space_actual_committed_space(10 * M, 5 * M); + test_virtual_space_actual_committed_space(10 * M, 10 * M); + } + + static void test_virtual_space() { + test_virtual_space_actual_committed_space(); + test_virtual_space_actual_committed_space_one_large_page(); + } +}; + +void TestVirtualSpace_test() { + TestVirtualSpace::test_virtual_space(); +} + #endif // PRODUCT #endif diff --git a/hotspot/src/share/vm/runtime/virtualspace.hpp b/hotspot/src/share/vm/runtime/virtualspace.hpp index bca9b6c14fc..938a71a4a43 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.hpp +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp @@ -183,11 +183,16 @@ class VirtualSpace VALUE_OBJ_CLASS_SPEC { // Destruction ~VirtualSpace(); - // Testers (all sizes are byte sizes) - size_t committed_size() const; - size_t reserved_size() const; + // Reserved memory + size_t reserved_size() const; + // Actually committed OS memory + size_t actual_committed_size() const; + // Memory used/expanded in this virtual space + size_t committed_size() const; + // Memory left to use/expand in this virtual space size_t uncommitted_size() const; - bool contains(const void* p) const; + + bool contains(const void* p) const; // Operations // returns true on success, false otherwise From dc7c7c5e1361ab08d3c251f7fcaadf1aca4eff6c Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Thu, 12 Sep 2013 15:53:49 +0400 Subject: [PATCH 082/293] 8022617: Openjdk hotspot build is broken on BSD platforms using gcc Enforce of preprocessing of all assembly sources by assembler-with-cpp Reviewed-by: dholmes, erikj --- hotspot/make/bsd/makefiles/gcc.make | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index b98485f901d..0277bb66aa3 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -80,7 +80,7 @@ ifeq ($(SPEC),) HOSTCC = $(CC) endif - AS = $(CC) -c -x assembler-with-cpp + AS = $(CC) -c endif @@ -347,6 +347,13 @@ ifeq ($(OS_VENDOR), Darwin) LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN) endif + +#------------------------------------------------------------------------ +# Assembler flags + +# Enforce prerpocessing of .s files +ASFLAGS += -x assembler-with-cpp + #------------------------------------------------------------------------ # Linker flags From 350906807bf274a05000522a64e683da309dff94 Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Thu, 12 Sep 2013 23:13:45 +0200 Subject: [PATCH 083/293] 8024646: Remove LRG_List container, replace it with GrowableArray We already have GrowableArray, use it instead of LRG_List Reviewed-by: kvn --- hotspot/src/share/vm/opto/chaitin.cpp | 42 ++++++++------------------ hotspot/src/share/vm/opto/chaitin.hpp | 34 ++++++++++----------- hotspot/src/share/vm/opto/coalesce.hpp | 1 - hotspot/src/share/vm/opto/live.cpp | 10 +++--- hotspot/src/share/vm/opto/live.hpp | 22 +------------- 5 files changed, 36 insertions(+), 73 deletions(-) diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp index a1a0e1c1fb7..492bf384f2f 100644 --- a/hotspot/src/share/vm/opto/chaitin.cpp +++ b/hotspot/src/share/vm/opto/chaitin.cpp @@ -122,40 +122,23 @@ double LRG::score() const { return score; } -LRG_List::LRG_List( uint max ) : _cnt(max), _max(max), _lidxs(NEW_RESOURCE_ARRAY(uint,max)) { - memset( _lidxs, 0, sizeof(uint)*max ); -} - -void LRG_List::extend( uint nidx, uint lidx ) { - _nesting.check(); - if( nidx >= _max ) { - uint size = 16; - while( size <= nidx ) size <<=1; - _lidxs = REALLOC_RESOURCE_ARRAY( uint, _lidxs, _max, size ); - _max = size; - } - while( _cnt <= nidx ) - _lidxs[_cnt++] = 0; - _lidxs[nidx] = lidx; -} - #define NUMBUCKS 3 // Straight out of Tarjan's union-find algorithm uint LiveRangeMap::find_compress(uint lrg) { uint cur = lrg; - uint next = _uf_map[cur]; + uint next = _uf_map.at(cur); while (next != cur) { // Scan chain of equivalences assert( next < cur, "always union smaller"); cur = next; // until find a fixed-point - next = _uf_map[cur]; + next = _uf_map.at(cur); } // Core of union-find algorithm: update chain of // equivalences to be equal to the root. while (lrg != next) { - uint tmp = _uf_map[lrg]; - _uf_map.map(lrg, next); + uint tmp = _uf_map.at(lrg); + _uf_map.at_put(lrg, next); lrg = tmp; } return lrg; @@ -165,10 +148,10 @@ uint LiveRangeMap::find_compress(uint lrg) { void LiveRangeMap::reset_uf_map(uint max_lrg_id) { _max_lrg_id= max_lrg_id; // Force the Union-Find mapping to be at least this large - _uf_map.extend(_max_lrg_id, 0); + _uf_map.at_put_grow(_max_lrg_id, 0); // Initialize it to be the ID mapping. for (uint i = 0; i < _max_lrg_id; ++i) { - _uf_map.map(i, i); + _uf_map.at_put(i, i); } } @@ -176,12 +159,12 @@ void LiveRangeMap::reset_uf_map(uint max_lrg_id) { // the Union-Find mapping after this call. void LiveRangeMap::compress_uf_map_for_nodes() { // For all Nodes, compress mapping - uint unique = _names.Size(); + uint unique = _names.length(); for (uint i = 0; i < unique; ++i) { - uint lrg = _names[i]; + uint lrg = _names.at(i); uint compressed_lrg = find(lrg); if (lrg != compressed_lrg) { - _names.map(i, compressed_lrg); + _names.at_put(i, compressed_lrg); } } } @@ -198,11 +181,11 @@ uint LiveRangeMap::find_const(uint lrg) const { return lrg; } - uint next = _uf_map[lrg]; + uint next = _uf_map.at(lrg); while (next != lrg) { // Scan chain of equivalences assert(next < lrg, "always union smaller"); lrg = next; // until find a fixed-point - next = _uf_map[lrg]; + next = _uf_map.at(lrg); } return next; } @@ -215,7 +198,7 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher) NULL #endif ) - , _lrg_map(unique) + , _lrg_map(Thread::current()->resource_area(), unique) , _live(0) , _spilled_once(Thread::current()->resource_area()) , _spilled_twice(Thread::current()->resource_area()) @@ -692,6 +675,7 @@ void PhaseChaitin::de_ssa() { _lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0); } } + // Reset the Union-Find mapping to be identity _lrg_map.reset_uf_map(lr_counter); } diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp index c951024ee75..41276efa5ca 100644 --- a/hotspot/src/share/vm/opto/chaitin.hpp +++ b/hotspot/src/share/vm/opto/chaitin.hpp @@ -283,8 +283,8 @@ private: // Straight out of Tarjan's union-find algorithm uint find_compress(const Node *node) { - uint lrg_id = find_compress(_names[node->_idx]); - _names.map(node->_idx, lrg_id); + uint lrg_id = find_compress(_names.at(node->_idx)); + _names.at_put(node->_idx, lrg_id); return lrg_id; } @@ -305,40 +305,40 @@ public: } uint size() const { - return _names.Size(); + return _names.length(); } uint live_range_id(uint idx) const { - return _names[idx]; + return _names.at(idx); } uint live_range_id(const Node *node) const { - return _names[node->_idx]; + return _names.at(node->_idx); } uint uf_live_range_id(uint lrg_id) const { - return _uf_map[lrg_id]; + return _uf_map.at(lrg_id); } void map(uint idx, uint lrg_id) { - _names.map(idx, lrg_id); + _names.at_put(idx, lrg_id); } void uf_map(uint dst_lrg_id, uint src_lrg_id) { - _uf_map.map(dst_lrg_id, src_lrg_id); + _uf_map.at_put(dst_lrg_id, src_lrg_id); } void extend(uint idx, uint lrg_id) { - _names.extend(idx, lrg_id); + _names.at_put_grow(idx, lrg_id); } void uf_extend(uint dst_lrg_id, uint src_lrg_id) { - _uf_map.extend(dst_lrg_id, src_lrg_id); + _uf_map.at_put_grow(dst_lrg_id, src_lrg_id); } - LiveRangeMap(uint unique) - : _names(unique) - , _uf_map(unique) + LiveRangeMap(Arena* arena, uint unique) + : _names(arena, unique, unique, 0) + , _uf_map(arena, unique, unique, 0) , _max_lrg_id(0) {} uint find_id( const Node *n ) { @@ -355,14 +355,14 @@ public: void compress_uf_map_for_nodes(); uint find(uint lidx) { - uint uf_lidx = _uf_map[lidx]; + uint uf_lidx = _uf_map.at(lidx); return (uf_lidx == lidx) ? uf_lidx : find_compress(lidx); } // Convert a Node into a Live Range Index - a lidx uint find(const Node *node) { uint lidx = live_range_id(node); - uint uf_lidx = _uf_map[lidx]; + uint uf_lidx = _uf_map.at(lidx); return (uf_lidx == lidx) ? uf_lidx : find_compress(node); } @@ -371,10 +371,10 @@ public: // Like Find above, but no path compress, so bad asymptotic behavior uint find_const(const Node *node) const { - if(node->_idx >= _names.Size()) { + if(node->_idx >= (uint)_names.length()) { return 0; // not mapped, usual for debug dump } - return find_const(_names[node->_idx]); + return find_const(_names.at(node->_idx)); } }; diff --git a/hotspot/src/share/vm/opto/coalesce.hpp b/hotspot/src/share/vm/opto/coalesce.hpp index a6359af101c..3a361b25f11 100644 --- a/hotspot/src/share/vm/opto/coalesce.hpp +++ b/hotspot/src/share/vm/opto/coalesce.hpp @@ -29,7 +29,6 @@ class LoopTree; class LRG; -class LRG_List; class Matcher; class PhaseIFG; class PhaseCFG; diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index 280d22204c2..adbbc24f8fd 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -91,7 +91,7 @@ void PhaseLive::compute(uint maxlrg) { break; } - uint r = _names[n->_idx]; + uint r = _names.at(n->_idx); assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block"); def->insert( r ); use->remove( r ); @@ -100,7 +100,7 @@ void PhaseLive::compute(uint maxlrg) { Node *nk = n->in(k); uint nkidx = nk->_idx; if (_cfg.get_block_for_node(nk) != block) { - uint u = _names[nkidx]; + uint u = _names.at(nkidx); use->insert(u); DEBUG_ONLY(def_outside->insert(u);) } @@ -112,7 +112,7 @@ void PhaseLive::compute(uint maxlrg) { #endif // Remove anything defined by Phis and the block start instruction for (uint k = i; k > 0; k--) { - uint r = _names[block->get_node(k - 1)->_idx]; + uint r = _names.at(block->get_node(k - 1)->_idx); def->insert(r); use->remove(r); } @@ -124,7 +124,7 @@ void PhaseLive::compute(uint maxlrg) { // PhiNode uses go in the live-out set of prior blocks. for (uint k = i; k > 0; k--) { - add_liveout(p, _names[block->get_node(k-1)->in(l)->_idx], first_pass); + add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass); } } freeset(block); @@ -256,7 +256,7 @@ void PhaseLive::dump( const Block *b ) const { tty->print("LiveOut: "); _live[b->_pre_order-1].dump(); uint cnt = b->number_of_nodes(); for( uint i=0; iprint("L%d/", _names[b->get_node(i)->_idx] ); + tty->print("L%d/", _names.at(b->get_node(i)->_idx)); b->get_node(i)->dump(); } tty->print("\n"); diff --git a/hotspot/src/share/vm/opto/live.hpp b/hotspot/src/share/vm/opto/live.hpp index c2ebe758cf8..e449bb3f3a6 100644 --- a/hotspot/src/share/vm/opto/live.hpp +++ b/hotspot/src/share/vm/opto/live.hpp @@ -40,27 +40,7 @@ class IndexSet; //------------------------------LRG_List--------------------------------------- // Map Node indices to Live RanGe indices. // Array lookup in the optimized case. -class LRG_List : public ResourceObj { - friend class VMStructs; - uint _cnt, _max; - uint* _lidxs; - ReallocMark _nesting; // assertion check for reallocations -public: - LRG_List( uint max ); - - uint lookup( uint nidx ) const { - return _lidxs[nidx]; - } - uint operator[] (uint nidx) const { return lookup(nidx); } - - void map( uint nidx, uint lidx ) { - assert( nidx < _cnt, "oob" ); - _lidxs[nidx] = lidx; - } - void extend( uint nidx, uint lidx ); - - uint Size() const { return _cnt; } -}; +typedef GrowableArray LRG_List; //------------------------------PhaseLive-------------------------------------- // Compute live-in/live-out From bfe7c0bfc24b61d31ec87d3ebecb1aeec17c45f2 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Thu, 12 Sep 2013 14:53:44 -0700 Subject: [PATCH 084/293] 8024275: During CTW: assert(sig_bt[member_arg_pos] == T_OBJECT) failed: dispatch argument must be an object Reviewed-by: kvn, vlivanov --- .../src/share/vm/classfile/classLoader.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp index 35055b4cb41..0ab350d90f8 100644 --- a/hotspot/src/share/vm/classfile/classLoader.cpp +++ b/hotspot/src/share/vm/classfile/classLoader.cpp @@ -1319,6 +1319,25 @@ static void clear_pending_exception_if_not_oom(TRAPS) { // The CHECK at the caller will propagate the exception out } +/** + * Returns if the given method should be compiled when doing compile-the-world. + * + * TODO: This should be a private method in a CompileTheWorld class. + */ +static bool can_be_compiled(methodHandle m, int comp_level) { + assert(CompileTheWorld, "must be"); + + // It's not valid to compile a native wrapper for MethodHandle methods + // that take a MemberName appendix since the bytecode signature is not + // correct. + vmIntrinsics::ID iid = m->intrinsic_id(); + if (MethodHandles::is_signature_polymorphic(iid) && MethodHandles::has_member_arg(iid)) { + return false; + } + + return CompilationPolicy::can_be_compiled(m, comp_level); +} + void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { int len = (int)strlen(name); if (len > 6 && strcmp(".class", name + len - 6) == 0) { @@ -1362,8 +1381,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { int comp_level = CompilationPolicy::policy()->initial_compile_level(); for (int n = 0; n < k->methods()->length(); n++) { methodHandle m (THREAD, k->methods()->at(n)); - if (CompilationPolicy::can_be_compiled(m, comp_level)) { - + if (can_be_compiled(m, comp_level)) { if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) { // Give sweeper a chance to keep up with CTW VM_ForceSafepoint op; @@ -1375,7 +1393,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { methodHandle(), 0, "CTW", THREAD); if (HAS_PENDING_EXCEPTION) { clear_pending_exception_if_not_oom(CHECK); - tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string()); + tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); } else { _compile_the_world_method_counter++; } @@ -1391,11 +1409,13 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) { methodHandle(), 0, "CTW", THREAD); if (HAS_PENDING_EXCEPTION) { clear_pending_exception_if_not_oom(CHECK); - tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string()); + tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); } else { _compile_the_world_method_counter++; } } + } else { + tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string()); } nmethod* nm = m->code(); From d2d4036f85983c026b380005526361567c5f4455 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:21:06 +0200 Subject: [PATCH 085/293] 8024651: Remove the incorrect usage of Metablock::overhead() Reviewed-by: brutisso, mgerdin, coleenp, jmasa --- hotspot/src/share/vm/memory/metablock.cpp | 7 ------- hotspot/src/share/vm/memory/metablock.hpp | 2 -- hotspot/src/share/vm/memory/metaspace.cpp | 4 +--- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/memory/metablock.cpp b/hotspot/src/share/vm/memory/metablock.cpp index 450d2c3193d..b6c6947e1ac 100644 --- a/hotspot/src/share/vm/memory/metablock.cpp +++ b/hotspot/src/share/vm/memory/metablock.cpp @@ -50,13 +50,6 @@ // Chunks, change Chunks so that they can be allocated out of a VirtualSpace. size_t Metablock::_min_block_byte_size = sizeof(Metablock); -#ifdef ASSERT -size_t Metablock::_overhead = - Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord; -#else -size_t Metablock::_overhead = 0; -#endif - // New blocks returned by the Metaspace are zero initialized. // We should fix the constructors to not assume this instead. Metablock* Metablock::initialize(MetaWord* p, size_t word_size) { diff --git a/hotspot/src/share/vm/memory/metablock.hpp b/hotspot/src/share/vm/memory/metablock.hpp index 220d3614818..fa4c6c0b445 100644 --- a/hotspot/src/share/vm/memory/metablock.hpp +++ b/hotspot/src/share/vm/memory/metablock.hpp @@ -48,7 +48,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC { } _header; } _block; static size_t _min_block_byte_size; - static size_t _overhead; typedef union block_t Block; typedef struct header_t Header; @@ -73,7 +72,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC { void set_prev(Metablock* v) { _block._header._prev = v; } static size_t min_block_byte_size() { return _min_block_byte_size; } - static size_t overhead() { return _overhead; } bool is_free() { return header()->_word_size != 0; } void clear_next() { set_next(NULL); } diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 1dd97842eb4..9d7834a56fb 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -737,9 +737,7 @@ class SpaceManager : public CHeapObj { // MinChunkSize is a placeholder for the real minimum size JJJ size_t byte_size = word_size * BytesPerWord; - size_t byte_size_with_overhead = byte_size + Metablock::overhead(); - - size_t raw_bytes_size = MAX2(byte_size_with_overhead, + size_t raw_bytes_size = MAX2(byte_size, Metablock::min_block_byte_size()); raw_bytes_size = ARENA_ALIGN(raw_bytes_size); size_t raw_word_size = raw_bytes_size / BytesPerWord; From 860b5dcec78c71f5ad307b0732b2e23c38be82c7 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:22:14 +0200 Subject: [PATCH 086/293] 8024650: Don't adjust MaxMetaspaceSize up to MetaspaceSize Reviewed-by: jwilhelm, brutisso, tschatzl --- .../parallelScavenge/generationSizer.hpp | 5 +- .../src/share/vm/memory/collectorPolicy.cpp | 31 +++-- .../gc/metaspace/TestMetaspaceSizeFlags.java | 108 ++++++++++++++++++ .../test/testlibrary/OutputAnalyzerTest.java | 17 +++ .../java/testlibrary/OutputAnalyzer.java | 35 +++++- 5 files changed, 180 insertions(+), 16 deletions(-) create mode 100644 hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp index b4b8c1ae9bb..e5637687e84 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,9 +68,6 @@ class GenerationSizer : public TwoGenerationCollectorPolicy { size_t min_old_gen_size() { return _min_gen1_size; } size_t old_gen_size() { return _initial_gen1_size; } size_t max_old_gen_size() { return _max_gen1_size; } - - size_t metaspace_size() { return MetaspaceSize; } - size_t max_metaspace_size() { return MaxMetaspaceSize; } }; #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GENERATIONSIZER_HPP diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index a5b4aa61894..0728997b769 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -47,6 +47,11 @@ // CollectorPolicy methods. +// Align down. If the aligning result in 0, return 'alignment'. +static size_t restricted_align_down(size_t size, size_t alignment) { + return MAX2(alignment, align_size_down_(size, alignment)); +} + void CollectorPolicy::initialize_flags() { assert(max_alignment() >= min_alignment(), err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT, @@ -59,18 +64,24 @@ void CollectorPolicy::initialize_flags() { vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); } - if (MetaspaceSize > MaxMetaspaceSize) { - MaxMetaspaceSize = MetaspaceSize; - } - MetaspaceSize = MAX2(min_alignment(), align_size_down_(MetaspaceSize, min_alignment())); - // Don't increase Metaspace size limit above specified. - MaxMetaspaceSize = align_size_down(MaxMetaspaceSize, max_alignment()); - if (MetaspaceSize > MaxMetaspaceSize) { - MetaspaceSize = MaxMetaspaceSize; + if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) { + FLAG_SET_ERGO(uintx, MaxMetaspaceSize, + restricted_align_down(MaxMetaspaceSize, max_alignment())); } - MinMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MinMetaspaceExpansion, min_alignment())); - MaxMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MaxMetaspaceExpansion, min_alignment())); + if (MetaspaceSize > MaxMetaspaceSize) { + FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize); + } + + if (!is_size_aligned(MetaspaceSize, min_alignment())) { + FLAG_SET_ERGO(uintx, MetaspaceSize, + restricted_align_down(MetaspaceSize, min_alignment())); + } + + assert(MetaspaceSize <= MaxMetaspaceSize, "Must be"); + + MinMetaspaceExpansion = restricted_align_down(MinMetaspaceExpansion, min_alignment()); + MaxMetaspaceExpansion = restricted_align_down(MaxMetaspaceExpansion, min_alignment()); MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment()); diff --git a/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java new file mode 100644 index 00000000000..c67b8dc5ce9 --- /dev/null +++ b/hotspot/test/gc/metaspace/TestMetaspaceSizeFlags.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +/* + * @test TestMetaspaceSizeFlags + * @key gc + * @bug 8024650 + * @summary Test that metaspace size flags can be set correctly + * @library /testlibrary + */ +public class TestMetaspaceSizeFlags { + public static final long K = 1024L; + public static final long M = 1024L * K; + + // HotSpot uses a number of different values to align memory size flags. + // This is currently the largest alignment (unless huge large pages are used). + public static final long MAX_ALIGNMENT = 32 * M; + + public static void main(String [] args) throws Exception { + testMaxMetaspaceSizeEQMetaspaceSize(MAX_ALIGNMENT, MAX_ALIGNMENT); + // 8024650: MaxMetaspaceSize was adjusted instead of MetaspaceSize. + testMaxMetaspaceSizeLTMetaspaceSize(MAX_ALIGNMENT, MAX_ALIGNMENT * 2); + testMaxMetaspaceSizeGTMetaspaceSize(MAX_ALIGNMENT * 2, MAX_ALIGNMENT); + testTooSmallInitialMetaspace(0, 0); + testTooSmallInitialMetaspace(0, MAX_ALIGNMENT); + testTooSmallInitialMetaspace(MAX_ALIGNMENT, 0); + } + + private static void testMaxMetaspaceSizeEQMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception { + MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize); + Asserts.assertEQ(maxMetaspaceSize, metaspaceSize); + Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize); + Asserts.assertEQ(mf.metaspaceSize, metaspaceSize); + } + + private static void testMaxMetaspaceSizeLTMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception { + MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize); + Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize); + Asserts.assertEQ(mf.metaspaceSize, maxMetaspaceSize); + } + + private static void testMaxMetaspaceSizeGTMetaspaceSize(long maxMetaspaceSize, long metaspaceSize) throws Exception { + MetaspaceFlags mf = runAndGetValue(maxMetaspaceSize, metaspaceSize); + Asserts.assertGT(maxMetaspaceSize, metaspaceSize); + Asserts.assertGT(mf.maxMetaspaceSize, mf.metaspaceSize); + Asserts.assertEQ(mf.maxMetaspaceSize, maxMetaspaceSize); + Asserts.assertEQ(mf.metaspaceSize, metaspaceSize); + } + + private static void testTooSmallInitialMetaspace(long maxMetaspaceSize, long metaspaceSize) throws Exception { + OutputAnalyzer output = run(maxMetaspaceSize, metaspaceSize); + output.shouldContain("Too small initial Metaspace size"); + } + + private static MetaspaceFlags runAndGetValue(long maxMetaspaceSize, long metaspaceSize) throws Exception { + OutputAnalyzer output = run(maxMetaspaceSize, metaspaceSize); + output.shouldNotMatch("Error occurred during initialization of VM\n.*"); + + String stringMaxMetaspaceSize = output.firstMatch(".* MaxMetaspaceSize .* := (\\d+).*", 1); + String stringMetaspaceSize = output.firstMatch(".* MetaspaceSize .* := (\\d+).*", 1); + + return new MetaspaceFlags(Long.parseLong(stringMaxMetaspaceSize), + Long.parseLong(stringMetaspaceSize)); + } + + private static OutputAnalyzer run(long maxMetaspaceSize, long metaspaceSize) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:MaxMetaspaceSize=" + maxMetaspaceSize, + "-XX:MetaspaceSize=" + metaspaceSize, + "-XX:-UseLargePages", // Prevent us from using 2GB large pages on solaris + sparc. + "-XX:+PrintFlagsFinal", + "-version"); + return new OutputAnalyzer(pb.start()); + } + + private static class MetaspaceFlags { + public long maxMetaspaceSize; + public long metaspaceSize; + public MetaspaceFlags(long maxMetaspaceSize, long metaspaceSize) { + this.maxMetaspaceSize = maxMetaspaceSize; + this.metaspaceSize = metaspaceSize; + } + } +} diff --git a/hotspot/test/testlibrary/OutputAnalyzerTest.java b/hotspot/test/testlibrary/OutputAnalyzerTest.java index 6117e9000bd..2fd677783a8 100644 --- a/hotspot/test/testlibrary/OutputAnalyzerTest.java +++ b/hotspot/test/testlibrary/OutputAnalyzerTest.java @@ -172,5 +172,22 @@ public class OutputAnalyzerTest { } catch (RuntimeException e) { // expected } + + { + String aaaa = "aaaa"; + String result = output.firstMatch(aaaa); + if (!aaaa.equals(result)) { + throw new Exception("firstMatch(String) faild to match. Expected: " + aaaa + " got: " + result); + } + } + + { + String aa = "aa"; + String aa_grouped_aa = aa + "(" + aa + ")"; + String result = output.firstMatch(aa_grouped_aa, 1); + if (!aa.equals(result)) { + throw new Exception("firstMatch(String, int) failed to match. Expected: " + aa + " got: " + result); + } + } } } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java index b9e37128d23..73b65165e91 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java @@ -211,13 +211,13 @@ public final class OutputAnalyzer { if (matcher.find()) { reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stdout \n"); + + "' found in stdout: '" + matcher.group() + "' \n"); } matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); if (matcher.find()) { reportDiagnosticSummary(); throw new RuntimeException("'" + pattern - + "' found in stderr \n"); + + "' found in stderr: '" + matcher.group() + "' \n"); } } @@ -253,6 +253,37 @@ public final class OutputAnalyzer { } } + /** + * Get the captured group of the first string matching the pattern. + * stderr is searched before stdout. + * + * @param pattern The multi-line pattern to match + * @param group The group to capture + * @return The matched string or null if no match was found + */ + public String firstMatch(String pattern, int group) { + Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr); + Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout); + if (stderrMatcher.find()) { + return stderrMatcher.group(group); + } + if (stdoutMatcher.find()) { + return stdoutMatcher.group(group); + } + return null; + } + + /** + * Get the first string matching the pattern. + * stderr is searched before stdout. + * + * @param pattern The multi-line pattern to match + * @return The matched string or null if no match was found + */ + public String firstMatch(String pattern) { + return firstMatch(pattern, 0); + } + /** * Verify the exit value of the process * From 9784317e8a91e5642c9128c05d78dcd4e1e80f5d Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:23:48 +0200 Subject: [PATCH 087/293] 8024751: Fix bugs in TraceMetadata Reviewed-by: jmasa, brutisso --- hotspot/src/share/vm/memory/metaspace.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 9d7834a56fb..9b73b6303aa 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -2366,10 +2366,10 @@ Metachunk* SpaceManager::get_new_chunk(size_t word_size, grow_chunks_by_words, medium_chunk_bunch()); - if (TraceMetadataHumongousAllocation && + if (TraceMetadataHumongousAllocation && next != NULL && SpaceManager::is_humongous(next->word_size())) { - gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT, - next->word_size()); + gclog_or_tty->print_cr(" new humongous chunk word size " + PTR_FORMAT, next->word_size()); } return next; @@ -2487,9 +2487,6 @@ void SpaceManager::dump(outputStream* const out) const { curr = curr->next()) { out->print("%d) ", i++); curr->print_on(out); - if (TraceMetadataChunkAllocation && Verbose) { - block_freelists()->print_on(out); - } curr_total += curr->word_size(); used += curr->used_word_size(); capacity += curr->capacity_word_size(); @@ -2497,6 +2494,10 @@ void SpaceManager::dump(outputStream* const out) const { } } + if (TraceMetadataChunkAllocation && Verbose) { + block_freelists()->print_on(out); + } + size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size(); // Free space isn't wasted. waste -= free; From 4d3c6221b785cb307770a5113160babe21e6e999 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 13 Sep 2013 22:25:27 +0200 Subject: [PATCH 088/293] 8024752: Log TraceMetadata* output to gclog_or_tty instead of tty Reviewed-by: brutisso, mgerdin, coleenp --- hotspot/src/share/vm/memory/metaspace.cpp | 38 +++++++++---------- hotspot/src/share/vm/runtime/virtualspace.cpp | 19 ++++++---- hotspot/src/share/vm/runtime/virtualspace.hpp | 3 +- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 9b73b6303aa..c12c0b8637b 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -881,9 +881,9 @@ Metachunk* VirtualSpaceNode::take_from_committed(size_t chunk_word_size) { if (!is_available(chunk_word_size)) { if (TraceMetadataChunkAllocation) { - tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size); + gclog_or_tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size); // Dump some information about the virtual space that is nearly full - print_on(tty); + print_on(gclog_or_tty); } return NULL; } @@ -904,7 +904,7 @@ bool VirtualSpaceNode::expand_by(size_t words, bool pre_touch) { if (TraceMetavirtualspaceAllocation && !result) { gclog_or_tty->print_cr("VirtualSpaceNode::expand_by() failed " "for byte size " SIZE_FORMAT, bytes); - virtual_space()->print(); + virtual_space()->print_on(gclog_or_tty); } return result; } @@ -1173,7 +1173,7 @@ void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry) { #endif if (TraceMetavirtualspaceAllocation && Verbose) { VirtualSpaceNode* vsl = current_virtual_space(); - vsl->print_on(tty); + vsl->print_on(gclog_or_tty); } } @@ -1733,9 +1733,9 @@ void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) { assert_lock_strong(SpaceManager::expand_lock()); slow_locked_verify(); if (TraceMetadataChunkAllocation) { - tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " - PTR_FORMAT " size " SIZE_FORMAT, - chunk, chunk->word_size()); + gclog_or_tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk " + PTR_FORMAT " size " SIZE_FORMAT, + chunk, chunk->word_size()); } free_chunks_put(chunk); } @@ -1764,9 +1764,9 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { dec_free_chunks_total(chunk->capacity_word_size()); if (TraceMetadataChunkAllocation && Verbose) { - tty->print_cr("ChunkManager::free_chunks_get: free_list " - PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT, - free_list, chunk, chunk->word_size()); + gclog_or_tty->print_cr("ChunkManager::free_chunks_get: free_list " + PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT, + free_list, chunk, chunk->word_size()); } } else { chunk = humongous_dictionary()->get_chunk( @@ -1776,10 +1776,10 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { if (chunk != NULL) { if (TraceMetadataHumongousAllocation) { size_t waste = chunk->word_size() - word_size; - tty->print_cr("Free list allocate humongous chunk size " SIZE_FORMAT - " for requested size " SIZE_FORMAT - " waste " SIZE_FORMAT, - chunk->word_size(), word_size, waste); + gclog_or_tty->print_cr("Free list allocate humongous chunk size " + SIZE_FORMAT " for requested size " SIZE_FORMAT + " waste " SIZE_FORMAT, + chunk->word_size(), word_size, waste); } // Chunk is being removed from the chunks free list. dec_free_chunks_total(chunk->capacity_word_size()); @@ -1821,10 +1821,10 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { } else { list_count = humongous_dictionary()->total_count(); } - tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk " - PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ", - this, chunk, chunk->word_size(), list_count); - locked_print_free_chunks(tty); + gclog_or_tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk " + PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ", + this, chunk, chunk->word_size(), list_count); + locked_print_free_chunks(gclog_or_tty); } return chunk; @@ -2344,7 +2344,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { sum_count_in_chunks_in_use()); new_chunk->print_on(gclog_or_tty); if (vs_list() != NULL) { - vs_list()->chunk_manager()->locked_print_free_chunks(tty); + vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty); } } } diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp index b7724a6a082..98ee7635002 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.cpp +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp @@ -754,16 +754,19 @@ void VirtualSpace::check_for_contiguity() { assert(high() <= upper_high(), "upper high"); } -void VirtualSpace::print() { - tty->print ("Virtual space:"); - if (special()) tty->print(" (pinned in memory)"); - tty->cr(); - tty->print_cr(" - committed: " SIZE_FORMAT, committed_size()); - tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); - tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); - tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); +void VirtualSpace::print_on(outputStream* out) { + out->print ("Virtual space:"); + if (special()) out->print(" (pinned in memory)"); + out->cr(); + out->print_cr(" - committed: " SIZE_FORMAT, committed_size()); + out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); + out->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); + out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); } +void VirtualSpace::print() { + print_on(tty); +} /////////////// Unit tests /////////////// diff --git a/hotspot/src/share/vm/runtime/virtualspace.hpp b/hotspot/src/share/vm/runtime/virtualspace.hpp index 938a71a4a43..02b14734a00 100644 --- a/hotspot/src/share/vm/runtime/virtualspace.hpp +++ b/hotspot/src/share/vm/runtime/virtualspace.hpp @@ -203,7 +203,8 @@ class VirtualSpace VALUE_OBJ_CLASS_SPEC { void check_for_contiguity() PRODUCT_RETURN; // Debugging - void print() PRODUCT_RETURN; + void print_on(outputStream* out) PRODUCT_RETURN; + void print(); }; #endif // SHARE_VM_RUNTIME_VIRTUALSPACE_HPP From 403a37663ac616a849f35d855519d84c134ff46a Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 13 Sep 2013 07:57:13 +0200 Subject: [PATCH 089/293] 8024671: G1 generates assert error messages in product builds Reviewed-by: brutisso, tschatzl --- .../share/vm/gc_implementation/g1/g1CardCounts.cpp | 4 ++-- .../share/vm/gc_implementation/g1/g1CardCounts.hpp | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp index f75e518facc..31972bf3c4e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @@ -33,8 +33,8 @@ void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) { if (has_count_table()) { - check_card_num(from_card_num, - err_msg("from card num out of range: "SIZE_FORMAT, from_card_num)); + assert(from_card_num >= 0 && from_card_num < _committed_max_card_num, + err_msg("from card num out of range: "SIZE_FORMAT, from_card_num)); assert(from_card_num < to_card_num, err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT, from_card_num, to_card_num)); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp index fd516c0b90e..129b3b0d232 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.hpp @@ -72,25 +72,21 @@ class G1CardCounts: public CHeapObj { return has_reserved_count_table() && _committed_max_card_num > 0; } - void check_card_num(size_t card_num, const char* msg) { - assert(card_num >= 0 && card_num < _committed_max_card_num, msg); - } - size_t ptr_2_card_num(const jbyte* card_ptr) { assert(card_ptr >= _ct_bot, - err_msg("Inavalied card pointer: " + err_msg("Invalid card pointer: " "card_ptr: " PTR_FORMAT ", " "_ct_bot: " PTR_FORMAT, card_ptr, _ct_bot)); size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte)); - check_card_num(card_num, - err_msg("card pointer out of range: " PTR_FORMAT, card_ptr)); + assert(card_num >= 0 && card_num < _committed_max_card_num, + err_msg("card pointer out of range: " PTR_FORMAT, card_ptr)); return card_num; } jbyte* card_num_2_ptr(size_t card_num) { - check_card_num(card_num, - err_msg("card num out of range: "SIZE_FORMAT, card_num)); + assert(card_num >= 0 && card_num < _committed_max_card_num, + err_msg("card num out of range: "SIZE_FORMAT, card_num)); return (jbyte*) (_ct_bot + card_num); } From 4bc9598f85d15b28077287f8d33fda0e84830cb1 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 13 Sep 2013 00:43:01 -0700 Subject: [PATCH 090/293] 8024764: new hotspot build - hs25-b51 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index e1572121149..fa4d6554e16 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=50 +HS_BUILD_NUMBER=51 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From 13d322d70fa5dba35976acaa7236fd23371352e0 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Fri, 13 Sep 2013 04:16:54 -0700 Subject: [PATCH 091/293] 8023134: Rename VM LogFile to hotspot_pid{pid}.log (was hotspot.log) Reviewed-by: twisti, kvn, sla --- hotspot/src/share/tools/LogCompilation/README | 6 ++-- hotspot/src/share/vm/runtime/arguments.cpp | 35 ++++++++++++++++++- .../src/share/vm/runtime/deoptimization.cpp | 4 +-- hotspot/src/share/vm/runtime/globals.hpp | 11 +++--- hotspot/src/share/vm/utilities/ostream.cpp | 7 ++-- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/hotspot/src/share/tools/LogCompilation/README b/hotspot/src/share/tools/LogCompilation/README index 90dc3b893bb..aa18fe891f6 100644 --- a/hotspot/src/share/tools/LogCompilation/README +++ b/hotspot/src/share/tools/LogCompilation/README @@ -4,14 +4,14 @@ It's main purpose is to recreate output similar to requires a 1.5 JDK to build and simply typing make should build it. It produces a jar file, logc.jar, that can be run on the -hotspot.log from LogCompilation output like this: +HotSpot log (by default, hotspot_pid{pid}.log) from LogCompilation output like this: - java -jar logc.jar hotspot.log + java -jar logc.jar hotspot_pid1234.log This will produce something like the normal PrintCompilation output. Adding the -i option with also report inlining like PrintInlining. -More information about the LogCompilation output can be found at +More information about the LogCompilation output can be found at https://wikis.oracle.com/display/HotSpotInternals/LogCompilation+overview https://wikis.oracle.com/display/HotSpotInternals/PrintCompilation diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 1287e811496..b2627fea1d1 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -3337,6 +3337,33 @@ static char* get_shared_archive_path() { return shared_archive_path; } +#ifndef PRODUCT +// Determine whether LogVMOutput should be implicitly turned on. +static bool use_vm_log() { + if (LogCompilation || !FLAG_IS_DEFAULT(LogFile) || + PrintCompilation || PrintInlining || PrintDependencies || PrintNativeNMethods || + PrintDebugInfo || PrintRelocations || PrintNMethods || PrintExceptionHandlers || + PrintAssembly || TraceDeoptimization || TraceDependencies || + (VerifyDependencies && FLAG_IS_CMDLINE(VerifyDependencies))) { + return true; + } + +#ifdef COMPILER1 + if (PrintC1Statistics) { + return true; + } +#endif // COMPILER1 + +#ifdef COMPILER2 + if (PrintOptoAssembly || PrintOptoStatistics) { + return true; + } +#endif // COMPILER2 + + return false; +} +#endif // PRODUCT + // Parse entry point called from JNI_CreateJavaVM jint Arguments::parse(const JavaVMInitArgs* args) { @@ -3630,7 +3657,13 @@ jint Arguments::parse(const JavaVMInitArgs* args) { NmethodSweepFraction = 1; } } -#endif + + if (!LogVMOutput && FLAG_IS_DEFAULT(LogVMOutput)) { + if (use_vm_log()) { + LogVMOutput = true; + } + } +#endif // PRODUCT if (PrintCommandLineFlags) { CommandLineFlags::printSetFlags(tty); diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 7f71c2d8b76..007bfe7aa13 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -1751,7 +1751,7 @@ int Deoptimization::trap_state_set_recompiled(int trap_state, bool z) { else return trap_state & ~DS_RECOMPILE_BIT; } //---------------------------format_trap_state--------------------------------- -// This is used for debugging and diagnostics, including hotspot.log output. +// This is used for debugging and diagnostics, including LogFile output. const char* Deoptimization::format_trap_state(char* buf, size_t buflen, int trap_state) { DeoptReason reason = trap_state_reason(trap_state); @@ -1828,7 +1828,7 @@ const char* Deoptimization::trap_action_name(int action) { return buf; } -// This is used for debugging and diagnostics, including hotspot.log output. +// This is used for debugging and diagnostics, including LogFile output. const char* Deoptimization::format_trap_request(char* buf, size_t buflen, int trap_request) { jint unloaded_class_index = trap_request_index(trap_request); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 7fdf668bac5..ed3e1e8ff5d 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -880,7 +880,7 @@ class CommandLineFlags { "stay alive at the expense of JVM performance") \ \ diagnostic(bool, LogCompilation, false, \ - "Log compilation activity in detail to hotspot.log or LogFile") \ + "Log compilation activity in detail to LogFile") \ \ product(bool, PrintCompilation, false, \ "Print compilations") \ @@ -2498,16 +2498,17 @@ class CommandLineFlags { "Print all VM flags with default values and descriptions and exit")\ \ diagnostic(bool, SerializeVMOutput, true, \ - "Use a mutex to serialize output to tty and hotspot.log") \ + "Use a mutex to serialize output to tty and LogFile") \ \ diagnostic(bool, DisplayVMOutput, true, \ "Display all VM output on the tty, independently of LogVMOutput") \ \ - diagnostic(bool, LogVMOutput, trueInDebug, \ - "Save VM output to hotspot.log, or to LogFile") \ + diagnostic(bool, LogVMOutput, false, \ + "Save VM output to LogFile") \ \ diagnostic(ccstr, LogFile, NULL, \ - "If LogVMOutput is on, save VM output to this file [hotspot.log]") \ + "If LogVMOutput or LogCompilation is on, save VM output to " \ + "this file [default: ./hotspot_pid%p.log] (%p replaced with pid)") \ \ product(ccstr, ErrorFile, NULL, \ "If an error occurs, save the error data to this file " \ diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index 2f04fa0e437..90532078652 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -592,7 +592,7 @@ static const char* make_log_name(const char* log_name, const char* force_directo void defaultStream::init_log() { // %%% Need a MutexLocker? - const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; + const char* log_name = LogFile != NULL ? LogFile : "hotspot_pid%p.log"; const char* try_name = make_log_name(log_name, NULL); fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); if (!file->is_open()) { @@ -603,14 +603,15 @@ void defaultStream::init_log() { // Note: This feature is for maintainer use only. No need for L10N. jio_print(warnbuf); FREE_C_HEAP_ARRAY(char, try_name, mtInternal); - try_name = make_log_name("hs_pid%p.log", os::get_temp_directory()); + try_name = make_log_name(log_name, os::get_temp_directory()); jio_snprintf(warnbuf, sizeof(warnbuf), "Warning: Forcing option -XX:LogFile=%s\n", try_name); jio_print(warnbuf); delete file; file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); - FREE_C_HEAP_ARRAY(char, try_name, mtInternal); } + FREE_C_HEAP_ARRAY(char, try_name, mtInternal); + if (file->is_open()) { _log_file = file; xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file); From dc42cb136dae4a66dc582ed312480c84c81c65d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Fri, 13 Sep 2013 17:47:00 +0200 Subject: [PATCH 092/293] 8021353: Event based tracing is missing thread exit Reviewed-by: allwin, acorn, dcubed, dholmes, egahlin --- hotspot/src/share/vm/runtime/thread.cpp | 2 ++ hotspot/src/share/vm/trace/traceMacros.hpp | 1 + 2 files changed, 3 insertions(+) diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 18b46c988e3..eab949297b3 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -333,6 +333,8 @@ Thread::~Thread() { // Reclaim the objectmonitors from the omFreeList of the moribund thread. ObjectSynchronizer::omFlush (this) ; + EVENT_THREAD_DESTRUCT(this); + // stack_base can be NULL if the thread is never started or exited before // record_stack_base_and_size called. Although, we would like to ensure // that all started threads do call record_stack_base_and_size(), there is diff --git a/hotspot/src/share/vm/trace/traceMacros.hpp b/hotspot/src/share/vm/trace/traceMacros.hpp index 1a6dd644935..4776e13507e 100644 --- a/hotspot/src/share/vm/trace/traceMacros.hpp +++ b/hotspot/src/share/vm/trace/traceMacros.hpp @@ -26,6 +26,7 @@ #define SHARE_VM_TRACE_TRACE_MACRO_HPP #define EVENT_THREAD_EXIT(thread) +#define EVENT_THREAD_DESTRUCT(thread) #define TRACE_INIT_ID(k) #define TRACE_DATA TraceThreadData From 5c11ecebfba784fda6007fda8447fc60d02224a8 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 13 Sep 2013 12:46:40 -0700 Subject: [PATCH 093/293] 8017230: Internal Error (jvmtiRedefineClasses.cpp:1662): guarantee(false) failed: insert_space_at() failed Handle pending exceptions instead of firing a guarantee() Reviewed-by: coleenp, dholmes --- .../share/vm/prims/jvmtiRedefineClasses.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 803cf9a7545..5330ab791b2 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1590,11 +1590,23 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_methods( for (int i = methods->length() - 1; i >= 0; i--) { methodHandle method(THREAD, methods->at(i)); methodHandle new_method; - rewrite_cp_refs_in_method(method, &new_method, CHECK_false); + rewrite_cp_refs_in_method(method, &new_method, THREAD); if (!new_method.is_null()) { // the method has been replaced so save the new method version + // even in the case of an exception. original method is on the + // deallocation list. methods->at_put(i, new_method()); } + if (HAS_PENDING_EXCEPTION) { + Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark + RC_TRACE_WITH_THREAD(0x00000002, THREAD, + ("rewrite_cp_refs_in_method exception: '%s'", ex_name->as_C_string())); + // Need to clear pending exception here as the super caller sets + // the JVMTI_ERROR_INTERNAL if the returned value is false. + CLEAR_PENDING_EXCEPTION; + return false; + } } return true; @@ -1674,10 +1686,7 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method, Pause_No_Safepoint_Verifier pnsv(&nsv); // ldc is 2 bytes and ldc_w is 3 bytes - m = rc.insert_space_at(bci, 3, inst_buffer, THREAD); - if (m.is_null() || HAS_PENDING_EXCEPTION) { - guarantee(false, "insert_space_at() failed"); - } + m = rc.insert_space_at(bci, 3, inst_buffer, CHECK); } // return the new method so that the caller can update From 47e8234251c09ec74d0de11f602b6c9a2c51d432 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 13 Sep 2013 12:47:44 -0700 Subject: [PATCH 094/293] 8024345: 'assert(_value != NULL) failed: resolving NULL _value' from VM_RedefineClasses::set_new_constant_pool The OOME's in the JVMTI merge_cp_and_rewrite and set_new_constant_pool must be handled correctly Reviewed-by: coleenp, dholmes --- .../share/vm/prims/jvmtiRedefineClasses.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 5330ab791b2..69e1c9f949c 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1395,8 +1395,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( ClassLoaderData* loader_data = the_class->class_loader_data(); ConstantPool* merge_cp_oop = ConstantPool::allocate(loader_data, - merge_cp_length, - THREAD); + merge_cp_length, + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); MergeCPCleaner cp_cleaner(loader_data, merge_cp_oop); HandleMark hm(THREAD); // make sure handles are cleared before @@ -1472,7 +1472,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( // Replace the new constant pool with a shrunken copy of the // merged constant pool - set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); + set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); // The new constant pool replaces scratch_cp so have cleaner clean it up. // It can't be cleaned up while there are handles to it. cp_cleaner.add_scratch_cp(scratch_cp()); @@ -1502,7 +1503,8 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( // merged constant pool so now the rewritten bytecodes have // valid references; the previous new constant pool will get // GCed. - set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); + set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, + CHECK_(JVMTI_ERROR_OUT_OF_MEMORY)); // The new constant pool replaces scratch_cp so have cleaner clean it up. // It can't be cleaned up while there are handles to it. cp_cleaner.add_scratch_cp(scratch_cp()); @@ -2496,8 +2498,8 @@ void VM_RedefineClasses::set_new_constant_pool( // scratch_cp is a merged constant pool and has enough space for a // worst case merge situation. We want to associate the minimum // sized constant pool with the klass to save space. - constantPoolHandle smaller_cp(THREAD, - ConstantPool::allocate(loader_data, scratch_cp_length, THREAD)); + ConstantPool* cp = ConstantPool::allocate(loader_data, scratch_cp_length, CHECK); + constantPoolHandle smaller_cp(THREAD, cp); // preserve version() value in the smaller copy int version = scratch_cp->version(); @@ -2509,6 +2511,11 @@ void VM_RedefineClasses::set_new_constant_pool( smaller_cp->set_pool_holder(scratch_class()); scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); + if (HAS_PENDING_EXCEPTION) { + // Exception is handled in the caller + loader_data->add_to_deallocate_list(smaller_cp()); + return; + } scratch_cp = smaller_cp; // attach new constant pool to klass From 2823ae69434df3acb2a94227539fd6f7038db557 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Fri, 13 Sep 2013 12:48:50 -0700 Subject: [PATCH 095/293] 8024346: ~CautiouslyPreserveExceptionMark - assert(!_thread->has_pending_exception()) failed: unexpected exception generated Pending exceptions must be handled properly after a call to the JVMTI merge_cp_and_rewrite Reviewed-by: coleenp, dholmes --- .../src/share/vm/prims/jvmtiRedefineClasses.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 69e1c9f949c..6894ec3f1f4 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -1072,8 +1072,17 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { } res = merge_cp_and_rewrite(the_class, scratch_class, THREAD); - if (res != JVMTI_ERROR_NONE) { - return res; + if (HAS_PENDING_EXCEPTION) { + Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark + RC_TRACE_WITH_THREAD(0x00000002, THREAD, + ("merge_cp_and_rewrite exception: '%s'", ex_name->as_C_string())); + CLEAR_PENDING_EXCEPTION; + if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { + return JVMTI_ERROR_OUT_OF_MEMORY; + } else { + return JVMTI_ERROR_INTERNAL; + } } if (VerifyMergedCPBytecodes) { @@ -1105,6 +1114,9 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { } if (HAS_PENDING_EXCEPTION) { Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); + // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark + RC_TRACE_WITH_THREAD(0x00000002, THREAD, + ("Rewriter::rewrite or link_methods exception: '%s'", ex_name->as_C_string())); CLEAR_PENDING_EXCEPTION; if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { return JVMTI_ERROR_OUT_OF_MEMORY; From 4fa99b3fc5fa1a52b1e7edd24076ab6d83e70e7d Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Fri, 13 Sep 2013 16:55:44 -0700 Subject: [PATCH 096/293] 8024760: add more types, fields and constants to VMStructs Reviewed-by: kvn, coleenp --- .../sun/jvm/hotspot/CommandProcessor.java | 2 + .../vm/gc_implementation/g1/ptrQueue.hpp | 1 + .../vm/gc_implementation/g1/vmStructs_g1.hpp | 3 +- hotspot/src/share/vm/memory/universe.cpp | 8 +- hotspot/src/share/vm/memory/universe.hpp | 2 + hotspot/src/share/vm/oops/klassVtable.hpp | 2 + hotspot/src/share/vm/oops/methodData.hpp | 2 + hotspot/src/share/vm/runtime/os.hpp | 2 + hotspot/src/share/vm/runtime/vmStructs.cpp | 119 ++++++++++++++++-- 9 files changed, 123 insertions(+), 18 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java index 1840caf9313..354f0b906b3 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -1213,6 +1213,7 @@ public class CommandProcessor { } HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase(); if (t.countTokens() == 1) { + String name = t.nextToken(); out.println("intConstant " + name + " " + db.lookupIntConstant(name)); } else if (t.countTokens() == 0) { Iterator i = db.getIntConstants(); @@ -1235,6 +1236,7 @@ public class CommandProcessor { } HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase(); if (t.countTokens() == 1) { + String name = t.nextToken(); out.println("longConstant " + name + " " + db.lookupLongConstant(name)); } else if (t.countTokens() == 0) { Iterator i = db.getLongConstants(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp index 1f6d9b21388..958317166ea 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp @@ -38,6 +38,7 @@ class PtrQueueSet; class PtrQueue VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; protected: // The ptr queue set to which this queue belongs. diff --git a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp index 5507dee5f80..736c2d75096 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp @@ -31,7 +31,8 @@ #define VM_STRUCTS_G1(nonstatic_field, static_field) \ \ - static_field(HeapRegion, GrainBytes, size_t) \ + static_field(HeapRegion, GrainBytes, size_t) \ + static_field(HeapRegion, LogOfHRGrainBytes, int) \ \ nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \ nonstatic_field(HeapRegionSeq, _length, uint) \ diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 143c0c00c45..f00a10f74a4 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -602,7 +602,7 @@ oop Universe::gen_out_of_memory_error(oop default_err) { } } -static intptr_t non_oop_bits = 0; +intptr_t Universe::_non_oop_bits = 0; void* Universe::non_oop_word() { // Neither the high bits nor the low bits of this value is allowed @@ -616,11 +616,11 @@ void* Universe::non_oop_word() { // Using the OS-supplied non-memory-address word (usually 0 or -1) // will take care of the high bits, however many there are. - if (non_oop_bits == 0) { - non_oop_bits = (intptr_t)os::non_memory_address_word() | 1; + if (_non_oop_bits == 0) { + _non_oop_bits = (intptr_t)os::non_memory_address_word() | 1; } - return (void*)non_oop_bits; + return (void*)_non_oop_bits; } jint universe_init() { diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index a8b541d03a1..09b52c099f2 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -179,6 +179,8 @@ class Universe: AllStatic { // The particular choice of collected heap. static CollectedHeap* _collectedHeap; + static intptr_t _non_oop_bits; + // For UseCompressedOops. static struct NarrowPtrStruct _narrow_oop; // For UseCompressedKlassPointers. diff --git a/hotspot/src/share/vm/oops/klassVtable.hpp b/hotspot/src/share/vm/oops/klassVtable.hpp index 01495e35d90..8d8d6cf27c5 100644 --- a/hotspot/src/share/vm/oops/klassVtable.hpp +++ b/hotspot/src/share/vm/oops/klassVtable.hpp @@ -150,6 +150,8 @@ class klassVtable : public ResourceObj { // from_compiled_code_entry_point -> nmethod entry point // from_interpreter_entry_point -> i2cadapter class vtableEntry VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; + public: // size in words static int size() { diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 765b91c142c..7ff9b2bbb6d 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -72,6 +72,8 @@ class ProfileData; // // Overlay for generic profiling data. class DataLayout VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; + private: // Every data layout begins with a header. This header // contains a tag, which is used to indicate the size/layout diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e43d68981cb..b224a3d7427 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -91,6 +91,8 @@ const bool ExecMem = true; typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread); class os: AllStatic { + friend class VMStructs; + public: enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel) diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 7e0df23a3e1..448a8919f0e 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -330,11 +330,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(Klass, _java_mirror, oop) \ nonstatic_field(Klass, _modifier_flags, jint) \ nonstatic_field(Klass, _super, Klass*) \ + nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ nonstatic_field(Klass, _name, Symbol*) \ nonstatic_field(Klass, _access_flags, AccessFlags) \ - nonstatic_field(Klass, _subklass, Klass*) \ + nonstatic_field(Klass, _prototype_header, markOop) \ nonstatic_field(Klass, _next_sibling, Klass*) \ + nonstatic_field(vtableEntry, _method, Method*) \ nonstatic_field(MethodData, _size, int) \ nonstatic_field(MethodData, _method, Method*) \ nonstatic_field(MethodData, _data_size, int) \ @@ -342,10 +344,15 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(MethodData, _nof_decompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \ nonstatic_field(MethodData, _nof_overflow_traps, uint) \ + nonstatic_field(MethodData, _trap_hist._array[0], u1) \ nonstatic_field(MethodData, _eflags, intx) \ nonstatic_field(MethodData, _arg_local, intx) \ nonstatic_field(MethodData, _arg_stack, intx) \ nonstatic_field(MethodData, _arg_returned, intx) \ + nonstatic_field(DataLayout, _header._struct._tag, u1) \ + nonstatic_field(DataLayout, _header._struct._flags, u1) \ + nonstatic_field(DataLayout, _header._struct._bci, u2) \ + nonstatic_field(DataLayout, _cells[0], intptr_t) \ nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \ nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \ nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \ @@ -357,6 +364,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(Method, _access_flags, AccessFlags) \ nonstatic_field(Method, _vtable_index, int) \ nonstatic_field(Method, _method_size, u2) \ + nonstatic_field(Method, _intrinsic_id, u1) \ nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \ volatile_nonstatic_field(Method, _code, nmethod*) \ nonstatic_field(Method, _i2i_entry, address) \ @@ -443,12 +451,19 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; static_field(Universe, _bootstrapping, bool) \ static_field(Universe, _fully_initialized, bool) \ static_field(Universe, _verify_count, int) \ + static_field(Universe, _non_oop_bits, intptr_t) \ static_field(Universe, _narrow_oop._base, address) \ static_field(Universe, _narrow_oop._shift, int) \ static_field(Universe, _narrow_oop._use_implicit_null_checks, bool) \ static_field(Universe, _narrow_klass._base, address) \ static_field(Universe, _narrow_klass._shift, int) \ \ + /******/ \ + /* os */ \ + /******/ \ + \ + static_field(os, _polling_page, address) \ + \ /**********************************************************************************/ \ /* Generation and Space hierarchies */ \ /**********************************************************************************/ \ @@ -456,6 +471,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; unchecked_nonstatic_field(ageTable, sizes, sizeof(ageTable::sizes)) \ \ nonstatic_field(BarrierSet, _max_covered_regions, int) \ + nonstatic_field(BarrierSet, _kind, BarrierSet::Name) \ nonstatic_field(BlockOffsetTable, _bottom, HeapWord*) \ nonstatic_field(BlockOffsetTable, _end, HeapWord*) \ \ @@ -495,6 +511,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(CollectedHeap, _barrier_set, BarrierSet*) \ nonstatic_field(CollectedHeap, _defer_initial_card_mark, bool) \ nonstatic_field(CollectedHeap, _is_gc_active, bool) \ + nonstatic_field(CollectedHeap, _total_collections, unsigned int) \ nonstatic_field(CompactibleSpace, _compaction_top, HeapWord*) \ nonstatic_field(CompactibleSpace, _first_dead, HeapWord*) \ nonstatic_field(CompactibleSpace, _end_of_live, HeapWord*) \ @@ -505,7 +522,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(ContiguousSpace, _saved_mark_word, HeapWord*) \ \ nonstatic_field(DefNewGeneration, _next_gen, Generation*) \ - nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \ + nonstatic_field(DefNewGeneration, _tenuring_threshold, uint) \ nonstatic_field(DefNewGeneration, _age_table, ageTable) \ nonstatic_field(DefNewGeneration, _eden_space, EdenSpace*) \ nonstatic_field(DefNewGeneration, _from_space, ContiguousSpace*) \ @@ -552,6 +569,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(ThreadLocalAllocBuffer, _desired_size, size_t) \ nonstatic_field(ThreadLocalAllocBuffer, _refill_waste_limit, size_t) \ static_field(ThreadLocalAllocBuffer, _target_refills, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _number_of_refills, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _fast_refill_waste, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _slow_refill_waste, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _gc_waste, unsigned) \ + nonstatic_field(ThreadLocalAllocBuffer, _slow_allocations, unsigned) \ nonstatic_field(VirtualSpace, _low_boundary, char*) \ nonstatic_field(VirtualSpace, _high_boundary, char*) \ nonstatic_field(VirtualSpace, _low, char*) \ @@ -713,6 +735,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; \ static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \ \ + /**********/ \ + /* Arrays */ \ + /**********/ \ + \ + nonstatic_field(Array, _length, int) \ + nonstatic_field(Array, _data[0], Klass*) \ + \ /*******************/ \ /* GrowableArrays */ \ /*******************/ \ @@ -720,7 +749,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(GenericGrowableArray, _len, int) \ nonstatic_field(GenericGrowableArray, _max, int) \ nonstatic_field(GenericGrowableArray, _arena, Arena*) \ - nonstatic_field(GrowableArray, _data, int*) \ + nonstatic_field(GrowableArray, _data, int*) \ \ /********************************/ \ /* CodeCache (NOTE: incomplete) */ \ @@ -763,7 +792,20 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* StubRoutines (NOTE: incomplete) */ \ /***********************************/ \ \ + static_field(StubRoutines, _verify_oop_count, jint) \ static_field(StubRoutines, _call_stub_return_address, address) \ + static_field(StubRoutines, _aescrypt_encryptBlock, address) \ + static_field(StubRoutines, _aescrypt_decryptBlock, address) \ + static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \ + static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \ + static_field(StubRoutines, _updateBytesCRC32, address) \ + static_field(StubRoutines, _crc_table_adr, address) \ + \ + /*****************/ \ + /* SharedRuntime */ \ + /*****************/ \ + \ + static_field(SharedRuntime, _ic_miss_blob, RuntimeStub*) \ \ /***************************************/ \ /* PcDesc and other compiled code info */ \ @@ -853,6 +895,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; volatile_nonstatic_field(Thread, _suspend_flags, uint32_t) \ nonstatic_field(Thread, _active_handles, JNIHandleBlock*) \ nonstatic_field(Thread, _tlab, ThreadLocalAllocBuffer) \ + nonstatic_field(Thread, _allocated_bytes, jlong) \ nonstatic_field(Thread, _current_pending_monitor, ObjectMonitor*) \ nonstatic_field(Thread, _current_pending_monitor_is_from_java, bool) \ nonstatic_field(Thread, _current_waiting_monitor, ObjectMonitor*) \ @@ -866,6 +909,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(JavaThread, _pending_async_exception, oop) \ volatile_nonstatic_field(JavaThread, _exception_oop, oop) \ volatile_nonstatic_field(JavaThread, _exception_pc, address) \ + volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \ nonstatic_field(JavaThread, _is_compiling, bool) \ nonstatic_field(JavaThread, _special_runtime_exit_condition, JavaThread::AsyncRequests) \ nonstatic_field(JavaThread, _saved_exception_pc, address) \ @@ -875,6 +919,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(JavaThread, _stack_size, size_t) \ nonstatic_field(JavaThread, _vframe_array_head, vframeArray*) \ nonstatic_field(JavaThread, _vframe_array_last, vframeArray*) \ + nonstatic_field(JavaThread, _satb_mark_queue, ObjPtrQueue) \ + nonstatic_field(JavaThread, _dirty_card_queue, DirtyCardQueue) \ nonstatic_field(Thread, _resource_area, ResourceArea*) \ nonstatic_field(CompilerThread, _env, ciEnv*) \ \ @@ -1187,7 +1233,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; unchecked_nonstatic_field(Array, _data, sizeof(int)) \ unchecked_nonstatic_field(Array, _data, sizeof(u1)) \ unchecked_nonstatic_field(Array, _data, sizeof(u2)) \ - unchecked_nonstatic_field(Array, _data, sizeof(Method*)) \ + unchecked_nonstatic_field(Array, _data, sizeof(Method*)) \ unchecked_nonstatic_field(Array, _data, sizeof(Klass*)) \ \ /*********************************/ \ @@ -1203,7 +1249,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* Miscellaneous fields */ \ /************************/ \ \ - nonstatic_field(CompileTask, _method, Method*) \ + nonstatic_field(CompileTask, _method, Method*) \ nonstatic_field(CompileTask, _osr_bci, int) \ nonstatic_field(CompileTask, _comp_level, int) \ nonstatic_field(CompileTask, _compile_id, uint) \ @@ -1217,7 +1263,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; \ nonstatic_field(vframeArrayElement, _frame, frame) \ nonstatic_field(vframeArrayElement, _bci, int) \ - nonstatic_field(vframeArrayElement, _method, Method*) \ + nonstatic_field(vframeArrayElement, _method, Method*) \ + \ + nonstatic_field(PtrQueue, _active, bool) \ + nonstatic_field(PtrQueue, _buf, void**) \ + nonstatic_field(PtrQueue, _index, size_t) \ \ nonstatic_field(AccessFlags, _flags, jint) \ nonstatic_field(elapsedTimer, _counter, jlong) \ @@ -1363,7 +1413,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* MetadataOopDesc hierarchy (NOTE: some missing) */ \ /**************************************************/ \ \ - declare_toplevel_type(CompiledICHolder) \ + declare_toplevel_type(CompiledICHolder) \ declare_toplevel_type(MetaspaceObj) \ declare_type(Metadata, MetaspaceObj) \ declare_type(Klass, Metadata) \ @@ -1374,17 +1424,20 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_type(InstanceClassLoaderKlass, InstanceKlass) \ declare_type(InstanceMirrorKlass, InstanceKlass) \ declare_type(InstanceRefKlass, InstanceKlass) \ - declare_type(ConstantPool, Metadata) \ - declare_type(ConstantPoolCache, MetaspaceObj) \ - declare_type(MethodData, Metadata) \ - declare_type(Method, Metadata) \ - declare_type(MethodCounters, MetaspaceObj) \ - declare_type(ConstMethod, MetaspaceObj) \ + declare_type(ConstantPool, Metadata) \ + declare_type(ConstantPoolCache, MetaspaceObj) \ + declare_type(MethodData, Metadata) \ + declare_type(Method, Metadata) \ + declare_type(MethodCounters, MetaspaceObj) \ + declare_type(ConstMethod, MetaspaceObj) \ + \ + declare_toplevel_type(vtableEntry) \ \ declare_toplevel_type(Symbol) \ declare_toplevel_type(Symbol*) \ declare_toplevel_type(volatile Metadata*) \ \ + declare_toplevel_type(DataLayout) \ declare_toplevel_type(nmethodBucket) \ \ /********/ \ @@ -1432,6 +1485,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_type(ModRefBarrierSet, BarrierSet) \ declare_type(CardTableModRefBS, ModRefBarrierSet) \ declare_type(CardTableModRefBSForCTRS, CardTableModRefBS) \ + declare_toplevel_type(BarrierSet::Name) \ declare_toplevel_type(GenRemSet) \ declare_type(CardTableRS, GenRemSet) \ declare_toplevel_type(BlockOffsetSharedArray) \ @@ -1450,6 +1504,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_toplevel_type(ThreadLocalAllocBuffer) \ declare_toplevel_type(VirtualSpace) \ declare_toplevel_type(WaterMark) \ + declare_toplevel_type(ObjPtrQueue) \ + declare_toplevel_type(DirtyCardQueue) \ \ /* Pointers to Garbage Collection types */ \ \ @@ -2068,6 +2124,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_toplevel_type(StubQueue*) \ declare_toplevel_type(Thread*) \ declare_toplevel_type(Universe) \ + declare_toplevel_type(os) \ declare_toplevel_type(vframeArray) \ declare_toplevel_type(vframeArrayElement) \ declare_toplevel_type(Annotations*) \ @@ -2076,6 +2133,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* Miscellaneous types */ \ /***************/ \ \ + declare_toplevel_type(PtrQueue) \ + \ /* freelist */ \ declare_toplevel_type(FreeChunk*) \ declare_toplevel_type(Metablock*) \ @@ -2106,6 +2165,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* Useful globals */ \ /******************/ \ \ + declare_preprocessor_constant("ASSERT", DEBUG_ONLY(1) NOT_DEBUG(0)) \ \ /**************/ \ /* Stack bias */ \ @@ -2122,6 +2182,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(BytesPerWord) \ declare_constant(BytesPerLong) \ \ + declare_constant(LogKlassAlignmentInBytes) \ + \ /********************************************/ \ /* Generation and Space Hierarchy Constants */ \ /********************************************/ \ @@ -2130,6 +2192,9 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; \ declare_constant(BarrierSet::ModRef) \ declare_constant(BarrierSet::CardTableModRef) \ + declare_constant(BarrierSet::CardTableExtension) \ + declare_constant(BarrierSet::G1SATBCT) \ + declare_constant(BarrierSet::G1SATBCTLogging) \ declare_constant(BarrierSet::Other) \ \ declare_constant(BlockOffsetSharedArray::LogN) \ @@ -2248,8 +2313,11 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(Klass::_primary_super_limit) \ declare_constant(Klass::_lh_instance_slow_path_bit) \ declare_constant(Klass::_lh_log2_element_size_shift) \ + declare_constant(Klass::_lh_log2_element_size_mask) \ declare_constant(Klass::_lh_element_type_shift) \ + declare_constant(Klass::_lh_element_type_mask) \ declare_constant(Klass::_lh_header_size_shift) \ + declare_constant(Klass::_lh_header_size_mask) \ declare_constant(Klass::_lh_array_tag_shift) \ declare_constant(Klass::_lh_array_tag_type_value) \ declare_constant(Klass::_lh_array_tag_obj_value) \ @@ -2268,6 +2336,12 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(ConstMethod::_has_default_annotations) \ declare_constant(ConstMethod::_has_type_annotations) \ \ + /**************/ \ + /* DataLayout */ \ + /**************/ \ + \ + declare_constant(DataLayout::cell_size) \ + \ /*************************************/ \ /* InstanceKlass enum */ \ /*************************************/ \ @@ -2402,6 +2476,13 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(Deoptimization::Reason_LIMIT) \ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \ \ + declare_constant(Deoptimization::Action_none) \ + declare_constant(Deoptimization::Action_maybe_recompile) \ + declare_constant(Deoptimization::Action_reinterpret) \ + declare_constant(Deoptimization::Action_make_not_entrant) \ + declare_constant(Deoptimization::Action_make_not_compilable) \ + declare_constant(Deoptimization::Action_LIMIT) \ + \ /*********************/ \ /* Matcher (C2 only) */ \ /*********************/ \ @@ -2468,6 +2549,16 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(vmSymbols::FIRST_SID) \ declare_constant(vmSymbols::SID_LIMIT) \ \ + /****************/ \ + /* vmIntrinsics */ \ + /****************/ \ + \ + declare_constant(vmIntrinsics::_invokeBasic) \ + declare_constant(vmIntrinsics::_linkToVirtual) \ + declare_constant(vmIntrinsics::_linkToStatic) \ + declare_constant(vmIntrinsics::_linkToSpecial) \ + declare_constant(vmIntrinsics::_linkToInterface) \ + \ /********************************/ \ /* Calling convention constants */ \ /********************************/ \ @@ -2515,6 +2606,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_constant(markOopDesc::biased_lock_bit_in_place) \ declare_constant(markOopDesc::age_mask) \ declare_constant(markOopDesc::age_mask_in_place) \ + declare_constant(markOopDesc::epoch_mask) \ + declare_constant(markOopDesc::epoch_mask_in_place) \ declare_constant(markOopDesc::hash_mask) \ declare_constant(markOopDesc::hash_mask_in_place) \ declare_constant(markOopDesc::biased_lock_alignment) \ From 7b2ffab30e57a21afe0ee70a801d4faa68d03b07 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Fri, 13 Sep 2013 21:36:27 -0400 Subject: [PATCH 097/293] 8024505: [TESTBUG] update test groups for additional tests that can't run on the minimal VM Reviewed-by: coleenp, hseigel --- hotspot/test/TEST.groups | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index bf5e3f088fb..d2ad0c7ea18 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -84,6 +84,7 @@ needs_jdk = \ runtime/NMT/ThreadedVirtualAllocTestType.java \ runtime/NMT/VirtualAllocTestType.java \ runtime/RedefineObject/TestRedefineObject.java \ + runtime/XCheckJniJsig/XCheckJSig.java \ serviceability/attach/AttachWithStalePidFile.java # JRE adds further tests to compact3 @@ -159,7 +160,18 @@ needs_full_vm_compact1 = \ gc/g1/TestRegionAlignment.java \ gc/g1/TestShrinkToOneRegion.java \ gc/metaspace/G1AddMetaspaceDependency.java \ - runtime/6929067/Test6929067.sh + gc/startup_warnings/TestCMS.java \ + gc/startup_warnings/TestCMSIncrementalMode.java \ + gc/startup_warnings/TestCMSNoIncrementalMode.java \ + gc/startup_warnings/TestDefaultMaxRAMFraction.java \ + gc/startup_warnings/TestDefNewCMS.java \ + gc/startup_warnings/TestIncGC.java \ + gc/startup_warnings/TestParallelGC.java \ + gc/startup_warnings/TestParallelScavengeSerialOld.java \ + gc/startup_warnings/TestParNewCMS.java \ + gc/startup_warnings/TestParNewSerialOld.java \ + runtime/6929067/Test6929067.sh \ + runtime/SharedArchiveFile/SharedArchiveFile.java # Minimal VM on Compact 2 adds in some compact2 tests # From 222c7354581b068ba6ff99d041084b481b08960f Mon Sep 17 00:00:00 2001 From: David Chase Date: Fri, 13 Sep 2013 22:38:02 -0400 Subject: [PATCH 098/293] 8014013: CallInfo structure no longer accurately reports the result of a LinkResolver operation Enhance method resolution and resulting data structures, plus some refactoring. Reviewed-by: twisti, acorn, jrose --- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 12 +- hotspot/src/share/vm/ci/ciField.cpp | 18 +- hotspot/src/share/vm/ci/ciField.hpp | 5 +- hotspot/src/share/vm/ci/ciInstanceKlass.cpp | 5 +- hotspot/src/share/vm/ci/ciMethod.cpp | 9 +- hotspot/src/share/vm/ci/ciSymbol.hpp | 3 +- .../share/vm/classfile/classFileParser.cpp | 5 +- hotspot/src/share/vm/code/compiledIC.cpp | 27 +- hotspot/src/share/vm/code/vtableStubs.cpp | 2 +- hotspot/src/share/vm/code/vtableStubs.hpp | 4 +- .../vm/interpreter/interpreterRuntime.cpp | 52 +++- .../src/share/vm/interpreter/linkResolver.cpp | 213 ++++++++++------ .../src/share/vm/interpreter/linkResolver.hpp | 111 ++++---- hotspot/src/share/vm/oops/constantPool.cpp | 26 -- hotspot/src/share/vm/oops/constantPool.hpp | 2 - hotspot/src/share/vm/oops/cpCache.cpp | 28 +- hotspot/src/share/vm/oops/cpCache.hpp | 22 +- hotspot/src/share/vm/oops/fieldStreams.hpp | 13 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 119 ++------- hotspot/src/share/vm/oops/instanceKlass.hpp | 10 - hotspot/src/share/vm/oops/klass.cpp | 16 +- hotspot/src/share/vm/oops/klass.hpp | 3 +- hotspot/src/share/vm/oops/klassVtable.cpp | 239 +++++++++++------- hotspot/src/share/vm/oops/klassVtable.hpp | 6 +- hotspot/src/share/vm/oops/method.cpp | 34 ++- hotspot/src/share/vm/oops/method.hpp | 19 +- hotspot/src/share/vm/oops/symbol.hpp | 2 +- hotspot/src/share/vm/opto/library_call.cpp | 4 + hotspot/src/share/vm/prims/jni.cpp | 8 +- hotspot/src/share/vm/prims/jvm.cpp | 2 +- .../share/vm/prims/jvmtiRedefineClasses.cpp | 2 +- hotspot/src/share/vm/prims/methodHandles.cpp | 235 +++++++---------- hotspot/src/share/vm/prims/methodHandles.hpp | 13 +- .../src/share/vm/runtime/fieldDescriptor.cpp | 18 +- .../src/share/vm/runtime/fieldDescriptor.hpp | 12 +- hotspot/src/share/vm/runtime/mutexLocker.cpp | 2 - hotspot/src/share/vm/runtime/mutexLocker.hpp | 3 +- hotspot/src/share/vm/runtime/reflection.cpp | 3 +- .../src/share/vm/runtime/reflectionUtils.hpp | 8 + hotspot/src/share/vm/runtime/vmStructs.cpp | 1 - 40 files changed, 715 insertions(+), 601 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 037bc31f658..080eaf67088 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -709,10 +709,10 @@ static Klass* resolve_field_return_klass(methodHandle caller, int bci, TRAPS) { Bytecodes::Code code = field_access.code(); // We must load class, initialize class and resolvethe field - FieldAccessInfo result; // initialize class if needed + fieldDescriptor result; // initialize class if needed constantPoolHandle constants(THREAD, caller->constants()); - LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK_NULL); - return result.klass()(); + LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK_NULL); + return result.field_holder(); } @@ -826,11 +826,11 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i if (stub_id == Runtime1::access_field_patching_id) { Bytecode_field field_access(caller_method, bci); - FieldAccessInfo result; // initialize class if needed + fieldDescriptor result; // initialize class if needed Bytecodes::Code code = field_access.code(); constantPoolHandle constants(THREAD, caller_method->constants()); - LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK); - patch_field_offset = result.field_offset(); + LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK); + patch_field_offset = result.offset(); // If we're patching a field which is volatile then at compile it // must not have been know to be volatile, so the generated code diff --git a/hotspot/src/share/vm/ci/ciField.cpp b/hotspot/src/share/vm/ci/ciField.cpp index 1a711ae522a..b08ec3616fa 100644 --- a/hotspot/src/share/vm/ci/ciField.cpp +++ b/hotspot/src/share/vm/ci/ciField.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool"); - _cp_index = index; constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); // Get the field's name, signature, and type. @@ -116,7 +115,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL // The declared holder of this field may not have been loaded. // Bail out with partial field information. if (!holder_is_accessible) { - // _cp_index and _type have already been set. + // _type has already been set. // The default values for _flags and _constant_value will suffice. // We need values for _holder, _offset, and _is_constant, _holder = declared_holder; @@ -146,8 +145,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { ASSERT_IN_VM; - _cp_index = -1; - // Get the field's name, signature, and type. ciEnv* env = CURRENT_ENV; _name = env->get_symbol(fd->name()); @@ -351,12 +348,11 @@ bool ciField::will_link(ciInstanceKlass* accessing_klass, } } - FieldAccessInfo result; - constantPoolHandle c_pool(THREAD, - accessing_klass->get_instanceKlass()->constants()); - LinkResolver::resolve_field(result, c_pool, _cp_index, - Bytecodes::java_code(bc), - true, false, KILL_COMPILE_ON_FATAL_(false)); + fieldDescriptor result; + LinkResolver::resolve_field(result, _holder->get_instanceKlass(), + _name->get_symbol(), _signature->get_symbol(), + accessing_klass->get_Klass(), bc, true, false, + KILL_COMPILE_ON_FATAL_(false)); // update the hit-cache, unless there is a problem with memory scoping: if (accessing_klass->is_shared() || !is_shared()) { diff --git a/hotspot/src/share/vm/ci/ciField.hpp b/hotspot/src/share/vm/ci/ciField.hpp index 81af9ca79a9..75263e3f217 100644 --- a/hotspot/src/share/vm/ci/ciField.hpp +++ b/hotspot/src/share/vm/ci/ciField.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,9 +53,6 @@ private: ciInstanceKlass* _known_to_link_with_get; ciConstant _constant_value; - // Used for will_link - int _cp_index; - ciType* compute_type(); ciType* compute_type_impl(); diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp index d74e484c66e..c689efa46d6 100644 --- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp +++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -522,8 +522,7 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray* for (JavaFieldStream fs(k); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) continue; - fieldDescriptor fd; - fd.initialize(k, fs.index()); + fieldDescriptor& fd = fs.field_descriptor(); ciField* field = new (arena) ciField(&fd); fields->append(field); } diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp index d0363250ee6..486d8c499b6 100644 --- a/hotspot/src/share/vm/ci/ciMethod.cpp +++ b/hotspot/src/share/vm/ci/ciMethod.cpp @@ -286,7 +286,10 @@ int ciMethod::itable_index() { check_is_loaded(); assert(holder()->is_linked(), "must be linked"); VM_ENTRY_MARK; - return klassItable::compute_itable_index(get_Method()); + Method* m = get_Method(); + if (!m->has_itable_index()) + return Method::nonvirtual_vtable_index; + return m->itable_index(); } #endif // SHARK @@ -1137,6 +1140,10 @@ bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const { // ------------------------------------------------------------------ // ciMethod::check_call bool ciMethod::check_call(int refinfo_index, bool is_static) const { + // This method is used only in C2 from InlineTree::ok_to_inline, + // and is only used under -Xcomp or -XX:CompileTheWorld. + // It appears to fail when applied to an invokeinterface call site. + // FIXME: Remove this method and resolve_method_statically; refactor to use the other LinkResolver entry points. VM_ENTRY_MARK; { EXCEPTION_MARK; diff --git a/hotspot/src/share/vm/ci/ciSymbol.hpp b/hotspot/src/share/vm/ci/ciSymbol.hpp index d54b54009be..3c974cf272e 100644 --- a/hotspot/src/share/vm/ci/ciSymbol.hpp +++ b/hotspot/src/share/vm/ci/ciSymbol.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ class ciSymbol : public ciBaseObject { friend class ciInstanceKlass; friend class ciSignature; friend class ciMethod; + friend class ciField; friend class ciObjArrayKlass; private: diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 8972bceb434..dc00790869c 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -3954,9 +3954,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, this_klass->set_has_final_method(); } this_klass->copy_method_ordering(method_ordering, CHECK_NULL); - // The InstanceKlass::_methods_jmethod_ids cache and the - // InstanceKlass::_methods_cached_itable_indices cache are - // both managed on the assumption that the initial cache + // The InstanceKlass::_methods_jmethod_ids cache + // is managed on the assumption that the initial cache // size is equal to the number of methods in the class. If // that changes, then InstanceKlass::idnum_can_increment() // has to be changed accordingly. diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index e9a63b86623..b9db323e5b2 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,31 +161,36 @@ address CompiledIC::stub_address() const { void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { - methodHandle method = call_info->selected_method(); - bool is_invoke_interface = (bytecode == Bytecodes::_invokeinterface && !call_info->has_vtable_index()); assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); address entry; - if (is_invoke_interface) { - int index = klassItable::compute_itable_index(call_info->resolved_method()()); - entry = VtableStubs::create_stub(false, index, method()); + if (call_info->call_kind() == CallInfo::itable_call) { + assert(bytecode == Bytecodes::_invokeinterface, ""); + int itable_index = call_info->itable_index(); + entry = VtableStubs::find_itable_stub(itable_index); +#ifdef ASSERT assert(entry != NULL, "entry not computed"); + int index = call_info->resolved_method()->itable_index(); + assert(index == itable_index, "CallInfo pre-computes this"); +#endif //ASSERT InstanceKlass* k = call_info->resolved_method()->method_holder(); - assert(k->is_interface(), "sanity check"); + assert(k->verify_itable_index(itable_index), "sanity check"); InlineCacheBuffer::create_transition_stub(this, k, entry); } else { - // Can be different than method->vtable_index(), due to package-private etc. + assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable"); + // Can be different than selected_method->vtable_index(), due to package-private etc. int vtable_index = call_info->vtable_index(); - entry = VtableStubs::create_stub(true, vtable_index, method()); - InlineCacheBuffer::create_transition_stub(this, method(), entry); + assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); + entry = VtableStubs::find_vtable_stub(vtable_index); + InlineCacheBuffer::create_transition_stub(this, NULL, entry); } if (TraceICs) { ResourceMark rm; tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT, - instruction_address(), method->print_value_string(), entry); + instruction_address(), call_info->selected_method()->print_value_string(), entry); } // We can't check this anymore. With lazy deopt we could have already diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp index 0d7b39a0241..7d9d7efaf67 100644 --- a/hotspot/src/share/vm/code/vtableStubs.cpp +++ b/hotspot/src/share/vm/code/vtableStubs.cpp @@ -111,7 +111,7 @@ void VtableStubs::initialize() { } -address VtableStubs::create_stub(bool is_vtable_stub, int vtable_index, Method* method) { +address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) { assert(vtable_index >= 0, "must be positive"); VtableStub* s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL; diff --git a/hotspot/src/share/vm/code/vtableStubs.hpp b/hotspot/src/share/vm/code/vtableStubs.hpp index aa95fee763c..06f2a67a857 100644 --- a/hotspot/src/share/vm/code/vtableStubs.hpp +++ b/hotspot/src/share/vm/code/vtableStubs.hpp @@ -121,9 +121,11 @@ class VtableStubs : AllStatic { static VtableStub* lookup (bool is_vtable_stub, int vtable_index); static void enter (bool is_vtable_stub, int vtable_index, VtableStub* s); static inline uint hash (bool is_vtable_stub, int vtable_index); + static address find_stub (bool is_vtable_stub, int vtable_index); public: - static address create_stub(bool is_vtable_stub, int vtable_index, Method* method); // return the entry point of a stub for this call + static address find_vtable_stub(int vtable_index) { return find_stub(true, vtable_index); } + static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); } static bool is_entry_point(address pc); // is pc a vtable stub entry point? static bool contains(address pc); // is pc within any stub? static VtableStub* stub_containing(address pc); // stub containing pc or NULL diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp index 4a3019f867f..4c082597b22 100644 --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp @@ -496,15 +496,15 @@ IRT_END IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode)) // resolve field - FieldAccessInfo info; + fieldDescriptor info; constantPoolHandle pool(thread, method(thread)->constants()); bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); { JvmtiHideSingleStepping jhss(thread); - LinkResolver::resolve_field(info, pool, get_index_u2_cpcache(thread, bytecode), - bytecode, false, CHECK); + LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode), + bytecode, CHECK); } // end JvmtiHideSingleStepping // check if link resolution caused cpCache to be updated @@ -524,7 +524,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode // class is intitialized. This is required so that access to the static // field will call the initialization function every time until the class // is completely initialized ala. in 2.17.5 in JVM Specification. - InstanceKlass *klass = InstanceKlass::cast(info.klass()()); + InstanceKlass* klass = InstanceKlass::cast(info.field_holder()); bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) && !klass->is_initialized()); Bytecodes::Code get_code = (Bytecodes::Code)0; @@ -539,9 +539,9 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode cache_entry(thread)->set_field( get_code, put_code, - info.klass(), - info.field_index(), - info.field_offset(), + info.field_holder(), + info.index(), + info.offset(), state, info.access_flags().is_final(), info.access_flags().is_volatile(), @@ -686,29 +686,55 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes if (already_resolved(thread)) return; if (bytecode == Bytecodes::_invokeinterface) { - if (TraceItables && Verbose) { ResourceMark rm(thread); tty->print_cr("Resolving: klass: %s to method: %s", info.resolved_klass()->name()->as_C_string(), info.resolved_method()->name()->as_C_string()); } + } +#ifdef ASSERT + if (bytecode == Bytecodes::_invokeinterface) { if (info.resolved_method()->method_holder() == SystemDictionary::Object_klass()) { // NOTE: THIS IS A FIX FOR A CORNER CASE in the JVM spec - // (see also cpCacheOop.cpp for details) + // (see also CallInfo::set_interface for details) + assert(info.call_kind() == CallInfo::vtable_call || + info.call_kind() == CallInfo::direct_call, ""); methodHandle rm = info.resolved_method(); assert(rm->is_final() || info.has_vtable_index(), "should have been set already"); - cache_entry(thread)->set_method(bytecode, rm, info.vtable_index()); + } else if (!info.resolved_method()->has_itable_index()) { + // Resolved something like CharSequence.toString. Use vtable not itable. + assert(info.call_kind() != CallInfo::itable_call, ""); } else { // Setup itable entry - int index = klassItable::compute_itable_index(info.resolved_method()()); - cache_entry(thread)->set_interface_call(info.resolved_method(), index); + assert(info.call_kind() == CallInfo::itable_call, ""); + int index = info.resolved_method()->itable_index(); + assert(info.itable_index() == index, ""); } } else { - cache_entry(thread)->set_method( + assert(info.call_kind() == CallInfo::direct_call || + info.call_kind() == CallInfo::vtable_call, ""); + } +#endif + switch (info.call_kind()) { + case CallInfo::direct_call: + cache_entry(thread)->set_direct_call( + bytecode, + info.resolved_method()); + break; + case CallInfo::vtable_call: + cache_entry(thread)->set_vtable_call( bytecode, info.resolved_method(), info.vtable_index()); + break; + case CallInfo::itable_call: + cache_entry(thread)->set_itable_call( + bytecode, + info.resolved_method(), + info.itable_index()); + break; + default: ShouldNotReachHere(); } } IRT_END diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index b0bd678b597..44ac9e0862d 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -46,19 +46,6 @@ #include "runtime/thread.inline.hpp" #include "runtime/vmThread.hpp" -//------------------------------------------------------------------------------------------------------------------------ -// Implementation of FieldAccessInfo - -void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset, -BasicType field_type, AccessFlags access_flags) { - _klass = klass; - _name = name; - _field_index = field_index; - _field_offset = field_offset; - _field_type = field_type; - _access_flags = access_flags; -} - //------------------------------------------------------------------------------------------------------------------------ // Implementation of CallInfo @@ -66,26 +53,25 @@ BasicType field_type, AccessFlags access_flags) { void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) { int vtable_index = Method::nonvirtual_vtable_index; - set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); + set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK); } -void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) { +void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index, TRAPS) { // This is only called for interface methods. If the resolved_method // comes from java/lang/Object, it can be the subject of a virtual call, so // we should pick the vtable index from the resolved method. - // Other than that case, there is no valid vtable index to specify. - int vtable_index = Method::invalid_vtable_index; - if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { - assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check"); - vtable_index = resolved_method->vtable_index(); - } - set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); + // In that case, the caller must call set_virtual instead of set_interface. + assert(resolved_method->method_holder()->is_interface(), ""); + assert(itable_index == resolved_method()->itable_index(), ""); + set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK); } void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index"); - set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); + assert(vtable_index < 0 || !resolved_method->has_vtable_index() || vtable_index == resolved_method->vtable_index(), ""); + CallKind kind = (vtable_index >= 0 && !resolved_method->can_be_statically_bound() ? CallInfo::vtable_call : CallInfo::direct_call); + set_common(resolved_klass, selected_klass, resolved_method, selected_method, kind, vtable_index, CHECK); assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call"); } @@ -98,20 +84,29 @@ void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix resolved_method->is_compiled_lambda_form(), "linkMethod must return one of these"); int vtable_index = Method::nonvirtual_vtable_index; - assert(resolved_method->vtable_index() == vtable_index, ""); - set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); + assert(!resolved_method->has_vtable_index(), ""); + set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK); _resolved_appendix = resolved_appendix; _resolved_method_type = resolved_method_type; } -void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { +void CallInfo::set_common(KlassHandle resolved_klass, + KlassHandle selected_klass, + methodHandle resolved_method, + methodHandle selected_method, + CallKind kind, + int index, + TRAPS) { assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond"); _resolved_klass = resolved_klass; _selected_klass = selected_klass; _resolved_method = resolved_method; _selected_method = selected_method; - _vtable_index = vtable_index; + _call_kind = kind; + _call_index = index; _resolved_appendix = Handle(); + DEBUG_ONLY(verify()); // verify before making side effects + if (CompilationPolicy::must_be_compiled(selected_method)) { // This path is unusual, mostly used by the '-Xcomp' stress test mode. @@ -138,6 +133,65 @@ void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass } } +// utility query for unreflecting a method +CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) { + Klass* resolved_method_holder = resolved_method->method_holder(); + if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st + resolved_klass = resolved_method_holder; + } + _resolved_klass = resolved_klass; + _selected_klass = resolved_klass; + _resolved_method = resolved_method; + _selected_method = resolved_method; + // classify: + CallKind kind = CallInfo::unknown_kind; + int index = resolved_method->vtable_index(); + if (resolved_method->can_be_statically_bound()) { + kind = CallInfo::direct_call; + } else if (!resolved_method_holder->is_interface()) { + // Could be an Object method inherited into an interface, but still a vtable call. + kind = CallInfo::vtable_call; + } else if (!resolved_klass->is_interface()) { + // A miranda method. Compute the vtable index. + ResourceMark rm; + klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable(); + index = vt->index_of_miranda(resolved_method->name(), + resolved_method->signature()); + kind = CallInfo::vtable_call; + } else { + // A regular interface call. + kind = CallInfo::itable_call; + index = resolved_method->itable_index(); + } + assert(index == Method::nonvirtual_vtable_index || index >= 0, err_msg("bad index %d", index)); + _call_kind = kind; + _call_index = index; + _resolved_appendix = Handle(); + DEBUG_ONLY(verify()); +} + +#ifdef ASSERT +void CallInfo::verify() { + switch (call_kind()) { // the meaning and allowed value of index depends on kind + case CallInfo::direct_call: + if (_call_index == Method::nonvirtual_vtable_index) break; + // else fall through to check vtable index: + case CallInfo::vtable_call: + assert(resolved_klass()->verify_vtable_index(_call_index), ""); + break; + case CallInfo::itable_call: + assert(resolved_method()->method_holder()->verify_itable_index(_call_index), ""); + break; + case CallInfo::unknown_kind: + assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set"); + break; + default: + fatal(err_msg_res("Unexpected call kind %d", call_kind())); + } +} +#endif //ASSERT + + //------------------------------------------------------------------------------------------------------------------------ // Klass resolution @@ -163,13 +217,6 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i result = KlassHandle(THREAD, result_oop); } -void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { - Klass* result_oop = - ConstantPool::klass_ref_at_if_loaded_check(pool, index, CHECK); - result = KlassHandle(THREAD, result_oop); -} - - //------------------------------------------------------------------------------------------------------------------------ // Method resolution // @@ -360,7 +407,12 @@ void LinkResolver::check_method_accessability(KlassHandle ref_klass, void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass, Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) { - + // This method is used only + // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call), + // and + // (2) in Bytecode_invoke::static_target + // It appears to fail when applied to an invokeinterface call site. + // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points. // resolve klass if (code == Bytecodes::_invokedynamic) { resolved_klass = SystemDictionary::MethodHandle_klass(); @@ -580,45 +632,49 @@ void LinkResolver::check_field_accessability(KlassHandle ref_klass, } } -void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) { - resolve_field(result, pool, index, byte, check_only, true, CHECK); +void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { + // Load these early in case the resolve of the containing klass fails + Symbol* field = pool->name_ref_at(index); + Symbol* sig = pool->signature_ref_at(index); + + // resolve specified klass + KlassHandle resolved_klass; + resolve_klass(resolved_klass, pool, index, CHECK); + + KlassHandle current_klass(THREAD, pool->pool_holder()); + resolve_field(result, resolved_klass, field, sig, current_klass, byte, true, true, CHECK); } -void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) { +void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass, Symbol* field, Symbol* sig, + KlassHandle current_klass, Bytecodes::Code byte, bool check_access, bool initialize_class, + TRAPS) { assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic || - byte == Bytecodes::_getfield || byte == Bytecodes::_putfield, "bad bytecode"); + byte == Bytecodes::_getfield || byte == Bytecodes::_putfield || + (byte == Bytecodes::_nop && !check_access), "bad field access bytecode"); bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic); bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic); - // resolve specified klass - KlassHandle resolved_klass; - if (update_pool) { - resolve_klass(resolved_klass, pool, index, CHECK); - } else { - resolve_klass_no_update(resolved_klass, pool, index, CHECK); - } - // Load these early in case the resolve of the containing klass fails - Symbol* field = pool->name_ref_at(index); - Symbol* sig = pool->signature_ref_at(index); // Check if there's a resolved klass containing the field - if( resolved_klass.is_null() ) { + if (resolved_klass.is_null()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); } // Resolve instance field - fieldDescriptor fd; // find_field initializes fd if found KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); // check if field exists; i.e., if a klass containing the field def has been selected - if (sel_klass.is_null()){ + if (sel_klass.is_null()) { ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); } + if (!check_access) + // Access checking may be turned off when calling from within the VM. + return; + // check access - KlassHandle ref_klass(THREAD, pool->pool_holder()); - check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK); + check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK); // check for errors if (is_static != fd.is_static()) { @@ -629,7 +685,7 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo } // Final fields can only be accessed from its own class. - if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) { + if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) { THROW(vmSymbols::java_lang_IllegalAccessError()); } @@ -639,19 +695,18 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo // // note 2: we don't want to force initialization if we are just checking // if the field access is legal; e.g., during compilation - if (is_static && !check_only) { + if (is_static && initialize_class) { sel_klass->initialize(CHECK); } - { + if (sel_klass() != current_klass()) { HandleMark hm(THREAD); - Handle ref_loader (THREAD, InstanceKlass::cast(ref_klass())->class_loader()); + Handle ref_loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader()); - Symbol* signature_ref = pool->signature_ref_at(index); { ResourceMark rm(THREAD); Symbol* failed_type_symbol = - SystemDictionary::check_signature_loaders(signature_ref, + SystemDictionary::check_signature_loaders(sig, ref_loader, sel_loader, false, CHECK); @@ -677,9 +732,6 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo // return information. note that the klass is set to the actual klass containing the // field, otherwise access of static fields in superclasses will not work. - KlassHandle holder (THREAD, fd.field_holder()); - Symbol* name = fd.name(); - result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags()); } @@ -906,10 +958,6 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, THROW(vmSymbols::java_lang_NullPointerException()); } - // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s - // has not been rewritten, and the vtable initialized. - assert(resolved_method->method_holder()->is_linked(), "must be linked"); - // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since // a missing receiver might result in a bogus lookup. @@ -920,6 +968,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, vtable_index = vtable_index_of_miranda_method(resolved_klass, resolved_method->name(), resolved_method->signature(), CHECK); + assert(vtable_index >= 0 , "we should have valid vtable index at this point"); InstanceKlass* inst = InstanceKlass::cast(recv_klass()); @@ -927,6 +976,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, } else { // at this point we are sure that resolved_method is virtual and not // a miranda method; therefore, it must have a valid vtable index. + assert(!resolved_method->has_itable_index(), ""); vtable_index = resolved_method->vtable_index(); // We could get a negative vtable_index for final methods, // because as an optimization they are they are never put in the vtable, @@ -1006,6 +1056,12 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand lookup_instance_method_in_klasses(sel_method, recv_klass, resolved_method->name(), resolved_method->signature(), CHECK); + if (sel_method.is_null() && !check_null_and_abstract) { + // In theory this is a harmless placeholder value, but + // in practice leaving in null affects the nsk default method tests. + // This needs further study. + sel_method = resolved_method; + } // check if method exists if (sel_method.is_null()) { ResourceMark rm(THREAD); @@ -1046,7 +1102,14 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand sel_method->signature())); } // setup result - result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK); + if (!resolved_method->has_itable_index()) { + int vtable_index = resolved_method->vtable_index(); + assert(vtable_index == sel_method->vtable_index(), "sanity check"); + result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK); + return; + } + int itable_index = resolved_method()->itable_index(); + result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); } @@ -1293,7 +1356,8 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po } if (TraceMethodHandles) { - tty->print_cr("resolve_invokedynamic #%d %s %s", + ResourceMark rm(THREAD); + tty->print_cr("resolve_invokedynamic #%d %s %s", ConstantPool::decode_invokedynamic_index(index), method_name->as_C_string(), method_signature->as_C_string()); tty->print(" BSM info: "); bootstrap_specifier->print(); @@ -1342,9 +1406,16 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result, //------------------------------------------------------------------------------------------------------------------------ #ifndef PRODUCT -void FieldAccessInfo::print() { +void CallInfo::print() { ResourceMark rm; - tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset()); + const char* kindstr = "unknown"; + switch (_call_kind) { + case direct_call: kindstr = "direct"; break; + case vtable_call: kindstr = "vtable"; break; + case itable_call: kindstr = "itable"; break; + } + tty->print_cr("Call %s@%d %s", kindstr, _call_index, + _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string()); } #endif diff --git a/hotspot/src/share/vm/interpreter/linkResolver.hpp b/hotspot/src/share/vm/interpreter/linkResolver.hpp index 4054eeb35ef..0fb551a23a8 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.hpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,63 +30,54 @@ // All the necessary definitions for run-time link resolution. -// LinkInfo & its subclasses provide all the information gathered -// for a particular link after resolving it. A link is any reference +// CallInfo provides all the information gathered for a particular +// linked call site after resolving it. A link is any reference // made from within the bytecodes of a method to an object outside of // that method. If the info is invalid, the link has not been resolved // successfully. -class LinkInfo VALUE_OBJ_CLASS_SPEC { -}; - - -// Link information for getfield/putfield & getstatic/putstatic bytecodes. - -class FieldAccessInfo: public LinkInfo { - protected: - KlassHandle _klass; - Symbol* _name; - AccessFlags _access_flags; - int _field_index; // original index in the klass - int _field_offset; - BasicType _field_type; - +class CallInfo VALUE_OBJ_CLASS_SPEC { public: - void set(KlassHandle klass, Symbol* name, int field_index, int field_offset, - BasicType field_type, AccessFlags access_flags); - KlassHandle klass() const { return _klass; } - Symbol* name() const { return _name; } - int field_index() const { return _field_index; } - int field_offset() const { return _field_offset; } - BasicType field_type() const { return _field_type; } - AccessFlags access_flags() const { return _access_flags; } - - // debugging - void print() PRODUCT_RETURN; -}; - - -// Link information for all calls. - -class CallInfo: public LinkInfo { + // Ways that a method call might be selected (or not) based on receiver type. + // Note that an invokevirtual instruction might be linked with no_dispatch, + // and an invokeinterface instruction might be linked with any of the three options + enum CallKind { + direct_call, // jump into resolved_method (must be concrete) + vtable_call, // select recv.klass.method_at_vtable(index) + itable_call, // select recv.klass.method_at_itable(resolved_method.holder, index) + unknown_kind = -1 + }; private: - KlassHandle _resolved_klass; // static receiver klass + KlassHandle _resolved_klass; // static receiver klass, resolved from a symbolic reference KlassHandle _selected_klass; // dynamic receiver class (same as static, or subklass) methodHandle _resolved_method; // static target method methodHandle _selected_method; // dynamic (actual) target method - int _vtable_index; // vtable index of selected method + CallKind _call_kind; // kind of call (static(=bytecode static/special + + // others inferred), vtable, itable) + int _call_index; // vtable or itable index of selected class method (if any) Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix) Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites) void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS); - void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS); + void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS); void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS); void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS); - void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS); + void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS); friend class LinkResolver; public: + CallInfo() { +#ifndef PRODUCT + _call_kind = CallInfo::unknown_kind; + _call_index = Method::garbage_vtable_index; +#endif //PRODUCT + } + + // utility to extract an effective CallInfo from a method and an optional receiver limit + // does not queue the method for compilation + CallInfo(Method* resolved_method, Klass* resolved_klass = NULL); + KlassHandle resolved_klass() const { return _resolved_klass; } KlassHandle selected_klass() const { return _selected_klass; } methodHandle resolved_method() const { return _resolved_method; } @@ -95,21 +86,43 @@ class CallInfo: public LinkInfo { Handle resolved_method_type() const { return _resolved_method_type; } BasicType result_type() const { return selected_method()->result_type(); } - bool has_vtable_index() const { return _vtable_index >= 0; } - bool is_statically_bound() const { return _vtable_index == Method::nonvirtual_vtable_index; } + CallKind call_kind() const { return _call_kind; } + int call_index() const { return _call_index; } int vtable_index() const { // Even for interface calls the vtable index could be non-negative. // See CallInfo::set_interface. assert(has_vtable_index() || is_statically_bound(), ""); - return _vtable_index; + assert(call_kind() == vtable_call || call_kind() == direct_call, ""); + // The returned value is < 0 if the call is statically bound. + // But, the returned value may be >= 0 even if the kind is direct_call. + // It is up to the caller to decide which way to go. + return _call_index; } + int itable_index() const { + assert(call_kind() == itable_call, ""); + // The returned value is always >= 0, a valid itable index. + return _call_index; + } + + // debugging +#ifdef ASSERT + bool has_vtable_index() const { return _call_index >= 0 && _call_kind != CallInfo::itable_call; } + bool is_statically_bound() const { return _call_index == Method::nonvirtual_vtable_index; } +#endif //ASSERT + void verify() PRODUCT_RETURN; + void print() PRODUCT_RETURN; }; +// Link information for getfield/putfield & getstatic/putstatic bytecodes +// is represented using a fieldDescriptor. // The LinkResolver is used to resolve constant-pool references at run-time. // It does all necessary link-time checks & throws exceptions if necessary. class LinkResolver: AllStatic { + friend class klassVtable; + friend class klassItable; + private: static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); @@ -120,7 +133,6 @@ class LinkResolver: AllStatic { static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); - static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS); @@ -148,9 +160,16 @@ class LinkResolver: AllStatic { Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS); // runtime/static resolving for fields - static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS); - // takes an extra bool argument "update_pool" to decide whether to update the constantPool during klass resolution. - static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS); + static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS); + static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature, + KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS); + + // source of access_kind codes: + static Bytecodes::Code field_access_kind(bool is_static, bool is_put) { + return (is_static + ? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic) + : (is_put ? Bytecodes::_putfield : Bytecodes::_getfield )); + } // runtime resolving: // resolved_klass = specified class (i.e., static receiver class) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 8033d7e3850..673da4dd622 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -396,32 +396,6 @@ Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_oop, int whi } -// This is an interface for the compiler that allows accessing non-resolved entries -// in the constant pool - but still performs the validations tests. Must be used -// in a pre-parse of the compiler - to determine what it can do and not do. -// Note: We cannot update the ConstantPool from the vm_thread. -Klass* ConstantPool::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) { - int which = this_oop->klass_ref_index_at(index); - CPSlot entry = this_oop->slot_at(which); - if (entry.is_resolved()) { - assert(entry.get_klass()->is_klass(), "must be"); - return entry.get_klass(); - } else { - assert(entry.is_unresolved(), "must be either symbol or klass"); - Symbol* name = entry.get_symbol(); - oop loader = this_oop->pool_holder()->class_loader(); - oop protection_domain = this_oop->pool_holder()->protection_domain(); - Handle h_loader(THREAD, loader); - Handle h_prot (THREAD, protection_domain); - KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD)); - - // Do access check for klasses - if( k.not_null() ) verify_constant_pool_resolve(this_oop, k, CHECK_NULL); - return k(); - } -} - - Method* ConstantPool::method_at_if_loaded(constantPoolHandle cpool, int which) { if (cpool->cache() == NULL) return NULL; // nothing to load yet diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index eca2dcd9c56..b7d607d763a 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -730,8 +730,6 @@ class ConstantPool : public Metadata { static oop method_type_at_if_loaded (constantPoolHandle this_oop, int which); static Klass* klass_at_if_loaded (constantPoolHandle this_oop, int which); static Klass* klass_ref_at_if_loaded (constantPoolHandle this_oop, int which); - // Same as above - but does LinkResolving. - static Klass* klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS); // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the // future by other Java code. These take constant pool indices rather than diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index 9e2b83c2caf..9d358955025 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -140,9 +140,10 @@ void ConstantPoolCacheEntry::set_parameter_size(int value) { err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value)); } -void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, - methodHandle method, - int vtable_index) { +void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, + methodHandle method, + int vtable_index) { + bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); @@ -160,7 +161,8 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, // ...and fall through as if we were handling invokevirtual: case Bytecodes::_invokevirtual: { - if (method->can_be_statically_bound()) { + if (!is_vtable_call) { + assert(method->can_be_statically_bound(), ""); // set_f2_as_vfinal_method checks if is_vfinal flag is true. set_method_flags(as_TosState(method->result_type()), ( 1 << is_vfinal_shift) | @@ -169,6 +171,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, method()->size_of_parameters()); set_f2_as_vfinal_method(method()); } else { + assert(!method->can_be_statically_bound(), ""); assert(vtable_index >= 0, "valid index"); assert(!method->is_final_method(), "sanity"); set_method_flags(as_TosState(method->result_type()), @@ -182,6 +185,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: + assert(!is_vtable_call, ""); // Note: Read and preserve the value of the is_vfinal flag on any // invokevirtual bytecode shared with this constant pool cache entry. // It is cheap and safe to consult is_vfinal() at all times. @@ -232,8 +236,22 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code, NOT_PRODUCT(verify(tty)); } +void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) { + int index = Method::nonvirtual_vtable_index; + // index < 0; FIXME: inline and customize set_direct_or_vtable_call + set_direct_or_vtable_call(invoke_code, method, index); +} -void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { +void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) { + // either the method is a miranda or its holder should accept the given index + assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); + // index >= 0; FIXME: inline and customize set_direct_or_vtable_call + set_direct_or_vtable_call(invoke_code, method, index); +} + +void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) { + assert(method->method_holder()->verify_itable_index(index), ""); + assert(invoke_code == Bytecodes::_invokeinterface, ""); InstanceKlass* interf = method->method_holder(); assert(interf->is_interface(), "must be an interface"); assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); diff --git a/hotspot/src/share/vm/oops/cpCache.hpp b/hotspot/src/share/vm/oops/cpCache.hpp index c15b4a54bd6..77c0deb9d8f 100644 --- a/hotspot/src/share/vm/oops/cpCache.hpp +++ b/hotspot/src/share/vm/oops/cpCache.hpp @@ -219,15 +219,29 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC { Klass* root_klass // needed by the GC to dirty the klass ); - void set_method( // sets entry to resolved method entry + private: + void set_direct_or_vtable_call( Bytecodes::Code invoke_code, // the bytecode used for invoking the method methodHandle method, // the method/prototype if any (NULL, otherwise) int vtable_index // the vtable index if any, else negative ); - void set_interface_call( - methodHandle method, // Resolved method - int index // Method index into interface + public: + void set_direct_call( // sets entry to exact concrete method entry + Bytecodes::Code invoke_code, // the bytecode used for invoking the method + methodHandle method // the method to call + ); + + void set_vtable_call( // sets entry to vtable index + Bytecodes::Code invoke_code, // the bytecode used for invoking the method + methodHandle method, // resolved method which declares the vtable index + int vtable_index // the vtable index + ); + + void set_itable_call( + Bytecodes::Code invoke_code, // the bytecode used; must be invokeinterface + methodHandle method, // the resolved interface method + int itable_index // index into itable for the method ); void set_method_handle( diff --git a/hotspot/src/share/vm/oops/fieldStreams.hpp b/hotspot/src/share/vm/oops/fieldStreams.hpp index acc590c970c..17f1b0a8585 100644 --- a/hotspot/src/share/vm/oops/fieldStreams.hpp +++ b/hotspot/src/share/vm/oops/fieldStreams.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "oops/instanceKlass.hpp" #include "oops/fieldInfo.hpp" +#include "runtime/fieldDescriptor.hpp" // The is the base class for iteration over the fields array // describing the declared fields in the class. Several subclasses @@ -43,8 +44,10 @@ class FieldStreamBase : public StackObj { int _index; int _limit; int _generic_signature_slot; + fieldDescriptor _fd_buf; FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); } + InstanceKlass* field_holder() const { return _constants->pool_holder(); } int init_generic_signature_start_slot() { int length = _fields->length(); @@ -102,6 +105,7 @@ class FieldStreamBase : public StackObj { _index = 0; _limit = klass->java_fields_count(); init_generic_signature_start_slot(); + assert(klass == field_holder(), ""); } FieldStreamBase(instanceKlassHandle klass) { _fields = klass->fields(); @@ -109,6 +113,7 @@ class FieldStreamBase : public StackObj { _index = 0; _limit = klass->java_fields_count(); init_generic_signature_start_slot(); + assert(klass == field_holder(), ""); } // accessors @@ -180,6 +185,12 @@ class FieldStreamBase : public StackObj { return field()->contended_group(); } + // bridge to a heavier API: + fieldDescriptor& field_descriptor() const { + fieldDescriptor& field = const_cast(_fd_buf); + field.reinitialize(field_holder(), _index); + return field; + } }; // Iterate over only the internal fields diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 29c77a07ccb..cf77300dcf0 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -286,7 +286,6 @@ InstanceKlass::InstanceKlass(int vtable_len, init_previous_versions(); set_generic_signature_index(0); release_set_methods_jmethod_ids(NULL); - release_set_methods_cached_itable_indices(NULL); set_annotations(NULL); set_jvmti_cached_class_field_map(NULL); set_initial_method_idnum(0); @@ -1149,7 +1148,7 @@ bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor* Symbol* f_name = fs.name(); Symbol* f_sig = fs.signature(); if (f_name == name && f_sig == sig) { - fd->initialize(const_cast(this), fs.index()); + fd->reinitialize(const_cast(this), fs.index()); return true; } } @@ -1218,7 +1217,7 @@ Klass* InstanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fiel bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const { for (JavaFieldStream fs(this); !fs.done(); fs.next()) { if (fs.offset() == offset) { - fd->initialize(const_cast(this), fs.index()); + fd->reinitialize(const_cast(this), fs.index()); if (fd->is_static() == is_static) return true; } } @@ -1251,8 +1250,7 @@ void InstanceKlass::methods_do(void f(Method* method)) { void InstanceKlass::do_local_static_fields(FieldClosure* cl) { for (JavaFieldStream fs(this); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { - fieldDescriptor fd; - fd.initialize(this, fs.index()); + fieldDescriptor& fd = fs.field_descriptor(); cl->do_field(&fd); } } @@ -1268,8 +1266,7 @@ void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAP void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) { for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { - fieldDescriptor fd; - fd.initialize(this_oop(), fs.index()); + fieldDescriptor& fd = fs.field_descriptor(); f(&fd, CHECK); } } @@ -1291,7 +1288,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) { int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass); int j = 0; for (int i = 0; i < length; i += 1) { - fd.initialize(this, i); + fd.reinitialize(this, i); if (!fd.is_static()) { fields_sorted[j + 0] = fd.offset(); fields_sorted[j + 1] = i; @@ -1303,7 +1300,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) { // _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(this, fields_sorted[i + 1]); + fd.reinitialize(this, fields_sorted[i + 1]); assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields"); cl->do_field(&fd); } @@ -1686,87 +1683,6 @@ jmethodID InstanceKlass::jmethod_id_or_null(Method* method) { } -// Cache an itable index -void InstanceKlass::set_cached_itable_index(size_t idnum, int index) { - int* indices = methods_cached_itable_indices_acquire(); - int* to_dealloc_indices = NULL; - - // We use a double-check locking idiom here because this cache is - // performance sensitive. In the normal system, this cache only - // transitions from NULL to non-NULL which is safe because we use - // release_set_methods_cached_itable_indices() to advertise the - // new cache. A partially constructed cache should never be seen - // by a racing thread. Cache reads and writes proceed without a - // lock, but creation of the cache itself requires no leaks so a - // lock is generally acquired in that case. - // - // If the RedefineClasses() API has been used, then this cache can - // grow and we'll have transitions from non-NULL to bigger non-NULL. - // Cache creation requires no leaks and we require safety between all - // cache accesses and freeing of the old cache so a lock is generally - // acquired when the RedefineClasses() API has been used. - - if (indices == NULL || idnum_can_increment()) { - // we need a cache or the cache can grow - MutexLocker ml(JNICachedItableIndex_lock); - // reacquire the cache to see if another thread already did the work - indices = methods_cached_itable_indices_acquire(); - size_t length = 0; - // cache size is stored in element[0], other elements offset by one - if (indices == NULL || (length = (size_t)indices[0]) <= idnum) { - size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count()); - int* new_indices = NEW_C_HEAP_ARRAY(int, size+1, mtClass); - new_indices[0] = (int)size; - // copy any existing entries - size_t i; - for (i = 0; i < length; i++) { - new_indices[i+1] = indices[i+1]; - } - // Set all the rest to -1 - for (i = length; i < size; i++) { - new_indices[i+1] = -1; - } - if (indices != NULL) { - // We have an old cache to delete so save it for after we - // drop the lock. - to_dealloc_indices = indices; - } - release_set_methods_cached_itable_indices(indices = new_indices); - } - - if (idnum_can_increment()) { - // this cache can grow so we have to write to it safely - indices[idnum+1] = index; - } - } else { - CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); - } - - if (!idnum_can_increment()) { - // The cache cannot grow and this JNI itable index value does not - // have to be unique like a jmethodID. If there is a race to set it, - // it doesn't matter. - indices[idnum+1] = index; - } - - if (to_dealloc_indices != NULL) { - // we allocated a new cache so free the old one - FreeHeap(to_dealloc_indices); - } -} - - -// Retrieve a cached itable index -int InstanceKlass::cached_itable_index(size_t idnum) { - int* indices = methods_cached_itable_indices_acquire(); - if (indices != NULL && ((size_t)indices[0]) > idnum) { - // indices exist and are long enough, retrieve possible cached - return indices[idnum+1]; - } - return -1; -} - - // // Walk the list of dependent nmethods searching for nmethods which // are dependent on the changes that were passed in and mark them for @@ -2326,12 +2242,6 @@ void InstanceKlass::release_C_heap_structures() { } } - int* indices = methods_cached_itable_indices_acquire(); - if (indices != (int*)NULL) { - release_set_methods_cached_itable_indices(NULL); - FreeHeap(indices); - } - // release dependencies nmethodBucket* b = _dependencies; _dependencies = NULL; @@ -2782,6 +2692,18 @@ static const char* state_names[] = { "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" }; +static void print_vtable(intptr_t* start, int len, outputStream* st) { + for (int i = 0; i < len; i++) { + intptr_t e = start[i]; + st->print("%d : " INTPTR_FORMAT, i, e); + if (e != 0 && ((Metadata*)e)->is_metaspace_object()) { + st->print(" "); + ((Metadata*)e)->print_value_on(st); + } + st->cr(); + } +} + void InstanceKlass::print_on(outputStream* st) const { assert(is_klass(), "must be klass"); Klass::print_on(st); @@ -2816,7 +2738,7 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr(); st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); - if (Verbose) { + if (Verbose || WizardMode) { Array* method_array = methods(); for(int i = 0; i < method_array->length(); i++) { st->print("%d : ", i); method_array->at(i)->print_value(); st->cr(); @@ -2874,7 +2796,9 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr(); + if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st); st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr(); + if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st); st->print_cr(BULLET"---- static fields (%d words):", static_field_size()); FieldPrinter print_static_field(st); ((InstanceKlass*)this)->do_local_static_fields(&print_static_field); @@ -2896,6 +2820,7 @@ void InstanceKlass::print_on(outputStream* st) const { void InstanceKlass::print_value_on(outputStream* st) const { assert(is_klass(), "must be klass"); + if (Verbose || WizardMode) access_flags().print_on(st); name()->print_value_on(st); } diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 123f6b17911..3bd4e9de40c 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -245,7 +245,6 @@ class InstanceKlass: public Klass { MemberNameTable* _member_names; // Member names JNIid* _jni_ids; // First JNI identifier for static fields in this class jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none - int* _methods_cached_itable_indices; // itable_index cache for JNI invoke corresponding to methods idnum, or NULL nmethodBucket* _dependencies; // list of dependent nmethods nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class BreakpointInfo* _breakpoints; // bpt lists, managed by Method* @@ -690,10 +689,6 @@ class InstanceKlass: public Klass { size_t *length_p, jmethodID* id_p); jmethodID jmethod_id_or_null(Method* method); - // cached itable index support - void set_cached_itable_index(size_t idnum, int index); - int cached_itable_index(size_t idnum); - // annotations support Annotations* annotations() const { return _annotations; } void set_annotations(Annotations* anno) { _annotations = anno; } @@ -994,11 +989,6 @@ private: void release_set_methods_jmethod_ids(jmethodID* jmeths) { OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths); } - int* methods_cached_itable_indices_acquire() const - { return (int*)OrderAccess::load_ptr_acquire(&_methods_cached_itable_indices); } - void release_set_methods_cached_itable_indices(int* indices) - { OrderAccess::release_store_ptr(&_methods_cached_itable_indices, indices); } - // Lock during initialization public: // Lock for (1) initialization; (2) access to the ConstantPool of this class. diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp index cf24783fbf8..22b570bbff3 100644 --- a/hotspot/src/share/vm/oops/klass.cpp +++ b/hotspot/src/share/vm/oops/klass.cpp @@ -674,13 +674,23 @@ void Klass::oop_verify_on(oop obj, outputStream* st) { #ifndef PRODUCT -void Klass::verify_vtable_index(int i) { +bool Klass::verify_vtable_index(int i) { if (oop_is_instance()) { - assert(i>=0 && i<((InstanceKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds"); + int limit = ((InstanceKlass*)this)->vtable_length()/vtableEntry::size(); + assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit)); } else { assert(oop_is_array(), "Must be"); - assert(i>=0 && i<((ArrayKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds"); + int limit = ((ArrayKlass*)this)->vtable_length()/vtableEntry::size(); + assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit)); } + return true; +} + +bool Klass::verify_itable_index(int i) { + assert(oop_is_instance(), ""); + int method_count = klassItable::method_count_for_interface(this); + assert(i >= 0 && i < method_count, "index out of bounds"); + return true; } #endif diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp index 83bf44561b2..9855fdd3233 100644 --- a/hotspot/src/share/vm/oops/klass.hpp +++ b/hotspot/src/share/vm/oops/klass.hpp @@ -699,7 +699,8 @@ class Klass : public Metadata { void verify(bool check_dictionary = true) { verify_on(tty, check_dictionary); } #ifndef PRODUCT - void verify_vtable_index(int index); + bool verify_vtable_index(int index); + bool verify_itable_index(int index); #endif virtual void oop_verify_on(oop obj, outputStream* st); diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index ebc6e0aea88..7105368840f 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -47,11 +47,12 @@ inline InstanceKlass* klassVtable::ik() const { // this function computes the vtable size (including the size needed for miranda -// methods) and the number of miranda methods in this class +// methods) and the number of miranda methods in this class. // Note on Miranda methods: Let's say there is a class C that implements -// interface I. Let's say there is a method m in I that neither C nor any -// of its super classes implement (i.e there is no method of any access, with -// the same name and signature as m), then m is a Miranda method which is +// interface I, and none of C's superclasses implements I. +// Let's say there is an abstract method m in I that neither C +// nor any of its super classes implement (i.e there is no method of any access, +// with the same name and signature as m), then m is a Miranda method which is // entered as a public abstract method in C's vtable. From then on it should // treated as any other public method in C for method over-ride purposes. void klassVtable::compute_vtable_size_and_num_mirandas( @@ -111,10 +112,13 @@ void klassVtable::compute_vtable_size_and_num_mirandas( } int klassVtable::index_of(Method* m, int len) const { - assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods"); + assert(m->has_vtable_index(), "do not ask this of non-vtable methods"); return m->vtable_index(); } +// Copy super class's vtable to the first part (prefix) of this class's vtable, +// and return the number of entries copied. Expects that 'super' is the Java +// super class (arrays can have "array" super classes that must be skipped). int klassVtable::initialize_from_super(KlassHandle super) { if (super.is_null()) { return 0; @@ -139,14 +143,14 @@ int klassVtable::initialize_from_super(KlassHandle super) { } } -// Revised lookup semantics introduced 1.3 (Kestral beta) +// +// Revised lookup semantics introduced 1.3 (Kestrel beta) void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { // Note: Arrays can have intermediate array supers. Use java_super to skip them. KlassHandle super (THREAD, klass()->java_super()); int nofNewEntries = 0; - if (PrintVtables && !klass()->oop_is_array()) { ResourceMark rm(THREAD); tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); @@ -174,8 +178,10 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { int len = methods->length(); int initialized = super_vtable_len; - // update_inherited_vtable can stop for gc - ensure using handles + // Check each of this class's methods against super; + // if override, replace in copy of super vtable, otherwise append to end for (int i = 0; i < len; i++) { + // update_inherited_vtable can stop for gc - ensure using handles HandleMark hm(THREAD); assert(methods->at(i)->is_method(), "must be a Method*"); methodHandle mh(THREAD, methods->at(i)); @@ -189,11 +195,11 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { } } - // add miranda methods; it will also update the value of initialized - fill_in_mirandas(&initialized); + // add miranda methods to end of vtable. + initialized = fill_in_mirandas(initialized); // In class hierarchies where the accessibility is not increasing (i.e., going from private -> - // package_private -> publicprotected), the vtable might actually be smaller than our initial + // package_private -> public/protected), the vtable might actually be smaller than our initial // calculation. assert(initialized <= _length, "vtable initialization failed"); for(;initialized < _length; initialized++) { @@ -248,14 +254,8 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper return superk; } -// Methods that are "effectively" final don't need vtable entries. -bool method_is_effectively_final( - AccessFlags klass_flags, methodHandle target) { - return target->is_final() || klass_flags.is_final() && !target->is_overpass(); -} - // Update child's copy of super vtable for overrides -// OR return true if a new vtable entry is required +// OR return true if a new vtable entry is required. // Only called for InstanceKlass's, i.e. not for arrays // If that changed, could not use _klass as handle for klass bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len, @@ -263,6 +263,7 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar ResourceMark rm; bool allocate_new = true; assert(klass->oop_is_instance(), "must be InstanceKlass"); + assert(klass == target_method()->method_holder(), "caller resp."); // Initialize the method's vtable index to "nonvirtual". // If we allocate a vtable entry, we will update it to a non-negative number. @@ -273,11 +274,17 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar return false; } - if (method_is_effectively_final(klass->access_flags(), target_method)) { + if (target_method->is_final_method(klass->access_flags())) { // a final method never needs a new entry; final methods can be statically // resolved and they have to be present in the vtable only if they override // a super's method, in which case they re-use its entry allocate_new = false; + } else if (klass->is_interface()) { + allocate_new = false; // see note below in needs_new_vtable_entry + // An interface never allocates new vtable slots, only inherits old ones. + // This method will either be assigned its own itable index later, + // or be assigned an inherited vtable index in the loop below. + target_method()->set_vtable_index(Method::pending_itable_index); } // we need a new entry if there is no superclass @@ -411,8 +418,14 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, Symbol* classname, AccessFlags class_flags, TRAPS) { + if (class_flags.is_interface()) { + // Interfaces do not use vtables, so there is no point to assigning + // a vtable index to any of their methods. If we refrain from doing this, + // we can use Method::_vtable_index to hold the itable index + return false; + } - if (method_is_effectively_final(class_flags, target_method) || + if (target_method->is_final_method(class_flags) || // a final method never needs a new entry; final methods can be statically // resolved and they have to be present in the vtable only if they override // a super's method, in which case they re-use its entry @@ -500,7 +513,8 @@ int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) { return Method::invalid_vtable_index; } -// check if an entry is miranda +// check if an entry at an index is miranda +// requires that method m at entry be declared ("held") by an interface. bool klassVtable::is_miranda_entry_at(int i) { Method* m = method_at(i); Klass* method_holder = m->method_holder(); @@ -516,7 +530,9 @@ bool klassVtable::is_miranda_entry_at(int i) { return false; } -// check if a method is a miranda method, given a class's methods table and it's super +// check if a method is a miranda method, given a class's methods table and its super +// "miranda" means not static, not defined by this class, and not defined +// in super unless it is private and therefore inaccessible to this class. // the caller must make sure that the method belongs to an interface implemented by the class bool klassVtable::is_miranda(Method* m, Array* class_methods, Klass* super) { if (m->is_static()) { @@ -541,6 +557,14 @@ bool klassVtable::is_miranda(Method* m, Array* class_methods, Klass* su return false; } +// Scans current_interface_methods for miranda methods that do not +// already appear in new_mirandas and are also not defined-and-non-private +// in super (superclass). These mirandas are added to all_mirandas if it is +// not null; in addition, those that are not duplicates of miranda methods +// inherited by super from its interfaces are added to new_mirandas. +// Thus, new_mirandas will be the set of mirandas that this class introduces, +// all_mirandas will be the set of all mirandas applicable to this class +// including all defined in superclasses. void klassVtable::add_new_mirandas_to_lists( GrowableArray* new_mirandas, GrowableArray* all_mirandas, Array* current_interface_methods, Array* class_methods, @@ -599,17 +623,22 @@ void klassVtable::get_mirandas(GrowableArray* new_mirandas, } } -// fill in mirandas -void klassVtable::fill_in_mirandas(int* initialized) { +// Discover miranda methods ("miranda" = "interface abstract, no binding"), +// and append them into the vtable starting at index initialized, +// return the new value of initialized. +int klassVtable::fill_in_mirandas(int initialized) { GrowableArray mirandas(20); get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), ik()->local_interfaces()); for (int i = 0; i < mirandas.length(); i++) { - put_method_at(mirandas.at(i), *initialized); - ++(*initialized); + put_method_at(mirandas.at(i), initialized); + ++initialized; } + return initialized; } +// Copy this class's vtable to the vtable beginning at start. +// Used to copy superclass vtable to prefix of subclass's vtable. void klassVtable::copy_vtable_to(vtableEntry* start) { Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size()); } @@ -723,6 +752,12 @@ static int initialize_count = 0; // Initialization void klassItable::initialize_itable(bool checkconstraints, TRAPS) { + if (_klass->is_interface()) { + // This needs to go after vtable indexes are assigned but + // before implementors need to know the number of itable indexes. + assign_itable_indexes_for_interface(_klass()); + } + // Cannot be setup doing bootstrapping, interfaces don't have // itables, and klass with only ones entry have empty itables if (Universe::is_bootstrapping() || @@ -754,45 +789,89 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) { } +inline bool interface_method_needs_itable_index(Method* m) { + if (m->is_static()) return false; // e.g., Stream.empty + if (m->is_initializer()) return false; // or + // If an interface redeclares a method from java.lang.Object, + // it should already have a vtable index, don't touch it. + // e.g., CharSequence.toString (from initialize_vtable) + // if (m->has_vtable_index()) return false; // NO! + return true; +} + +int klassItable::assign_itable_indexes_for_interface(Klass* klass) { + // an interface does not have an itable, but its methods need to be numbered + if (TraceItables) tty->print_cr("%3d: Initializing itable for interface %s", ++initialize_count, + klass->name()->as_C_string()); + Array* methods = InstanceKlass::cast(klass)->methods(); + int nof_methods = methods->length(); + int ime_num = 0; + for (int i = 0; i < nof_methods; i++) { + Method* m = methods->at(i); + if (interface_method_needs_itable_index(m)) { + assert(!m->is_final_method(), "no final interface methods"); + // If m is already assigned a vtable index, do not disturb it. + if (!m->has_vtable_index()) { + assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); + m->set_itable_index(ime_num); + // Progress to next itable entry + ime_num++; + } + } + } + assert(ime_num == method_count_for_interface(klass), "proper sizing"); + return ime_num; +} + +int klassItable::method_count_for_interface(Klass* interf) { + assert(interf->oop_is_instance(), "must be"); + assert(interf->is_interface(), "must be"); + Array* methods = InstanceKlass::cast(interf)->methods(); + int nof_methods = methods->length(); + while (nof_methods > 0) { + Method* m = methods->at(nof_methods-1); + if (m->has_itable_index()) { + int length = m->itable_index() + 1; +#ifdef ASSERT + while (nof_methods = 0) { + m = methods->at(--nof_methods); + assert(!m->has_itable_index() || m->itable_index() < length, ""); + } +#endif //ASSERT + return length; // return the rightmost itable index, plus one + } + nof_methods -= 1; + } + // no methods have itable indexes + return 0; +} + + void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) { Array* methods = InstanceKlass::cast(interf_h())->methods(); int nof_methods = methods->length(); HandleMark hm; - KlassHandle klass = _klass; assert(nof_methods > 0, "at least one method must exist for interface to be in vtable"); Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader()); - int ime_num = 0; - // Skip first Method* if it is a class initializer - int i = methods->at(0)->is_static_initializer() ? 1 : 0; - - // m, method_name, method_signature, klass reset each loop so they - // don't need preserving across check_signature_loaders call - // methods needs a handle in case of gc from check_signature_loaders - for(; i < nof_methods; i++) { + int ime_count = method_count_for_interface(interf_h()); + for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); - Symbol* method_name = m->name(); - Symbol* method_signature = m->signature(); - - // This is same code as in Linkresolver::lookup_instance_method_in_klasses - Method* target = klass->uncached_lookup_method(method_name, method_signature); - while (target != NULL && target->is_static()) { - // continue with recursive lookup through the superclass - Klass* super = target->method_holder()->super(); - target = (super == NULL) ? (Method*)NULL : super->uncached_lookup_method(method_name, method_signature); + methodHandle target; + if (m->has_itable_index()) { + LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK); } if (target == NULL || !target->is_public() || target->is_abstract()) { // Entry do not resolve. Leave it empty } else { // Entry did resolve, check loader constraints before initializing // if checkconstraints requested - methodHandle target_h (THREAD, target); // preserve across gc if (checkconstraints) { Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); if (method_holder_loader() != interface_loader()) { ResourceMark rm(THREAD); Symbol* failed_type_symbol = - SystemDictionary::check_signature_loaders(method_signature, + SystemDictionary::check_signature_loaders(m->signature(), method_holder_loader, interface_loader, true, CHECK); @@ -803,9 +882,9 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass "and the class loader (instance of %s) for interface " "%s have different Class objects for the type %s " "used in the signature"; - char* sig = target_h()->name_and_sig_as_C_string(); + char* sig = target()->name_and_sig_as_C_string(); const char* loader1 = SystemDictionary::loader_name(method_holder_loader()); - char* current = klass->name()->as_C_string(); + char* current = _klass->name()->as_C_string(); const char* loader2 = SystemDictionary::loader_name(interface_loader()); char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string(); char* failed_type_name = failed_type_symbol->as_C_string(); @@ -821,10 +900,10 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass } // ime may have moved during GC so recalculate address - itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target_h()); + int ime_num = m->itable_index(); + assert(ime_num < ime_count, "oob"); + itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target()); } - // Progress to next entry - ime_num++; } } @@ -913,20 +992,22 @@ class InterfaceVisiterClosure : public StackObj { virtual void doit(Klass* intf, int method_count) = 0; }; -// Visit all interfaces with at-least one method (excluding ) +// Visit all interfaces with at least one itable method void visit_all_interfaces(Array* transitive_intf, InterfaceVisiterClosure *blk) { // Handle array argument for(int i = 0; i < transitive_intf->length(); i++) { Klass* intf = transitive_intf->at(i); assert(intf->is_interface(), "sanity check"); - // Find no. of methods excluding a - int method_count = InstanceKlass::cast(intf)->methods()->length(); - if (method_count > 0) { - Method* m = InstanceKlass::cast(intf)->methods()->at(0); - assert(m != NULL && m->is_method(), "sanity check"); - if (m->name() == vmSymbols::object_initializer_name()) { - method_count--; + // Find no. of itable methods + int method_count = 0; + // method_count = klassItable::method_count_for_interface(intf); + Array* methods = InstanceKlass::cast(intf)->methods(); + if (methods->length() > 0) { + for (int i = methods->length(); --i >= 0; ) { + if (interface_method_needs_itable_index(methods->at(i))) { + method_count++; + } } } @@ -1024,40 +1105,26 @@ void klassItable::setup_itable_offset_table(instanceKlassHandle klass) { } -// m must be a method in an interface -int klassItable::compute_itable_index(Method* m) { - InstanceKlass* intf = m->method_holder(); - assert(intf->is_interface(), "sanity check"); - Array* methods = intf->methods(); - int index = 0; - while(methods->at(index) != m) { - index++; - assert(index < methods->length(), "should find index for resolve_invoke"); - } - // Adjust for , which is left out of table if first method - if (methods->length() > 0 && methods->at(0)->is_static_initializer()) { - index--; - } - return index; -} - - -// inverse to compute_itable_index +// inverse to itable_index Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) { assert(InstanceKlass::cast(intf)->is_interface(), "sanity check"); + assert(intf->verify_itable_index(itable_index), ""); Array* methods = InstanceKlass::cast(intf)->methods(); - int index = itable_index; - // Adjust for , which is left out of table if first method - if (methods->length() > 0 && methods->at(0)->is_static_initializer()) { - index++; - } - - if (itable_index < 0 || index >= methods->length()) + if (itable_index < 0 || itable_index >= method_count_for_interface(intf)) return NULL; // help caller defend against bad indexes + int index = itable_index; Method* m = methods->at(index); - assert(compute_itable_index(m) == itable_index, "correct inverse"); + int index2 = -1; + while (!m->has_itable_index() || + (index2 = m->itable_index()) != itable_index) { + assert(index2 < itable_index, "monotonic"); + if (++index == methods->length()) + return NULL; + m = methods->at(index); + } + assert(m->itable_index() == itable_index, "correct inverse"); return m; } diff --git a/hotspot/src/share/vm/oops/klassVtable.hpp b/hotspot/src/share/vm/oops/klassVtable.hpp index 8d8d6cf27c5..06d55af2566 100644 --- a/hotspot/src/share/vm/oops/klassVtable.hpp +++ b/hotspot/src/share/vm/oops/klassVtable.hpp @@ -124,7 +124,7 @@ class klassVtable : public ResourceObj { // support for miranda methods bool is_miranda_entry_at(int i); - void fill_in_mirandas(int* initialized); + int fill_in_mirandas(int initialized); static bool is_miranda(Method* m, Array* class_methods, Klass* super); static void add_new_mirandas_to_lists( GrowableArray* new_mirandas, @@ -290,12 +290,12 @@ class klassItable : public ResourceObj { #endif // INCLUDE_JVMTI // Setup of itable + static int assign_itable_indexes_for_interface(Klass* klass); + static int method_count_for_interface(Klass* klass); static int compute_itable_size(Array* transitive_interfaces); static void setup_itable_offset_table(instanceKlassHandle klass); // Resolving of method to index - static int compute_itable_index(Method* m); - // ...and back again: static Method* method_for_itable_index(Klass* klass, int itable_index); // Debugging/Statistics diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index b8e60a774f3..30631fa3b61 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -509,24 +509,31 @@ bool Method::compute_has_loops_flag() { return _access_flags.has_loops(); } +bool Method::is_final_method(AccessFlags class_access_flags) const { + // or "does_not_require_vtable_entry" + // overpass can occur, is not final (reuses vtable entry) + // private methods get vtable entries for backward class compatibility. + if (is_overpass()) return false; + return is_final() || class_access_flags.is_final(); +} bool Method::is_final_method() const { - // %%% Should return true for private methods also, - // since there is no way to override them. - return is_final() || method_holder()->is_final(); + return is_final_method(method_holder()->access_flags()); } - -bool Method::is_strict_method() const { - return is_strict(); -} - - -bool Method::can_be_statically_bound() const { - if (is_final_method()) return true; +bool Method::can_be_statically_bound(AccessFlags class_access_flags) const { + if (is_final_method(class_access_flags)) return true; +#ifdef ASSERT + bool is_nonv = (vtable_index() == nonvirtual_vtable_index); + if (class_access_flags.is_interface()) assert(is_nonv == is_static(), err_msg("is_nonv=%s", is_nonv)); +#endif + assert(valid_vtable_index() || valid_itable_index(), "method must be linked before we ask this question"); return vtable_index() == nonvirtual_vtable_index; } +bool Method::can_be_statically_bound() const { + return can_be_statically_bound(method_holder()->access_flags()); +} bool Method::is_accessor() const { if (code_size() != 5) return false; @@ -967,7 +974,7 @@ bool Method::is_overridden_in(Klass* k) const { assert(ik->is_subclass_of(method_holder()), "should be subklass"); assert(ik->vtable() != NULL, "vtable should exist"); - if (vtable_index() == nonvirtual_vtable_index) { + if (!has_vtable_index()) { return false; } else { Method* vt_m = ik->method_at_vtable(vtable_index()); @@ -1959,7 +1966,7 @@ void Method::print_on(outputStream* st) const { void Method::print_value_on(outputStream* st) const { assert(is_method(), "must be method"); - st->print_cr(internal_name()); + st->print(internal_name()); print_address_on(st); st->print(" "); name()->print_value_on(st); @@ -1967,6 +1974,7 @@ void Method::print_value_on(outputStream* st) const { signature()->print_value_on(st); st->print(" in "); method_holder()->print_value_on(st); + if (WizardMode) st->print("#%d", _vtable_index); if (WizardMode) st->print("[%d,%d]", size_of_parameters(), max_locals()); if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code()); } diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp index faaf5105994..02d2253b80a 100644 --- a/hotspot/src/share/vm/oops/method.hpp +++ b/hotspot/src/share/vm/oops/method.hpp @@ -448,16 +448,22 @@ class Method : public Metadata { enum VtableIndexFlag { // Valid vtable indexes are non-negative (>= 0). // These few negative values are used as sentinels. - highest_unused_vtable_index_value = -5, + itable_index_max = -10, // first itable index, growing downward + pending_itable_index = -9, // itable index will be assigned invalid_vtable_index = -4, // distinct from any valid vtable index garbage_vtable_index = -3, // not yet linked; no vtable layout yet nonvirtual_vtable_index = -2 // there is no need for vtable dispatch // 6330203 Note: Do not use -1, which was overloaded with many meanings. }; DEBUG_ONLY(bool valid_vtable_index() const { return _vtable_index >= nonvirtual_vtable_index; }) - int vtable_index() const { assert(valid_vtable_index(), ""); - return _vtable_index; } + bool has_vtable_index() const { return _vtable_index >= 0; } + int vtable_index() const { return _vtable_index; } void set_vtable_index(int index) { _vtable_index = index; } + DEBUG_ONLY(bool valid_itable_index() const { return _vtable_index <= pending_itable_index; }) + bool has_itable_index() const { return _vtable_index <= itable_index_max; } + int itable_index() const { assert(valid_itable_index(), ""); + return itable_index_max - _vtable_index; } + void set_itable_index(int index) { _vtable_index = itable_index_max - index; assert(valid_itable_index(), ""); } // interpreter entry address interpreter_entry() const { return _i2i_entry; } @@ -560,10 +566,11 @@ class Method : public Metadata { // checks method and its method holder bool is_final_method() const; - bool is_strict_method() const; + bool is_final_method(AccessFlags class_access_flags) const; // true if method needs no dynamic dispatch (final and/or no vtable entry) bool can_be_statically_bound() const; + bool can_be_statically_bound(AccessFlags class_access_flags) const; // returns true if the method has any backward branches. bool has_loops() { @@ -740,10 +747,6 @@ class Method : public Metadata { // so handles are not used to avoid deadlock. jmethodID find_jmethod_id_or_null() { return method_holder()->jmethod_id_or_null(this); } - // JNI static invoke cached itable index accessors - int cached_itable_index() { return method_holder()->cached_itable_index(method_idnum()); } - void set_cached_itable_index(int index) { method_holder()->set_cached_itable_index(method_idnum(), index); } - // Support for inlining of intrinsic methods vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; } void set_intrinsic_id(vmIntrinsics::ID id) { _intrinsic_id = (u1) id; } diff --git a/hotspot/src/share/vm/oops/symbol.hpp b/hotspot/src/share/vm/oops/symbol.hpp index f9db8d39974..e747c464607 100644 --- a/hotspot/src/share/vm/oops/symbol.hpp +++ b/hotspot/src/share/vm/oops/symbol.hpp @@ -45,7 +45,7 @@ // in the SymbolTable bucket (the _literal field in HashtableEntry) // that points to the Symbol. All other stores of a Symbol* // to a field of a persistent variable (e.g., the _name filed in -// FieldAccessInfo or _ptr in a CPSlot) is reference counted. +// fieldDescriptor or _ptr in a CPSlot) is reference counted. // // 1) The lookup of a "name" in the SymbolTable either creates a Symbol F for // "name" and returns a pointer to F or finds a pre-existing Symbol F for diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index f7e09c3f89f..e0d68d9fc58 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -3734,6 +3734,8 @@ Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass, RegionNode* slow_region) { ciMethod* method = callee(); int vtable_index = method->vtable_index(); + assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, + err_msg_res("bad index %d", vtable_index)); // Get the Method* out of the appropriate vtable entry. int entry_offset = (InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size()) * wordSize + @@ -3784,6 +3786,8 @@ LibraryCallKit::generate_method_call(vmIntrinsics::ID method_id, bool is_virtual // so the vtable index is fixed. // No need to use the linkResolver to get it. vtable_index = method->vtable_index(); + assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, + err_msg_res("bad index %d", vtable_index)); } slow_call = new(C) CallDynamicJavaNode(tf, SharedRuntime::get_resolve_virtual_call_stub(), diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index ea44e2c6679..8367f5133b6 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -1336,6 +1336,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive if (call_type == JNI_VIRTUAL) { // jni_GetMethodID makes sure class is linked and initialized // so m should have a valid vtable index. + assert(!m->has_itable_index(), ""); int vtbl_index = m->vtable_index(); if (vtbl_index != Method::nonvirtual_vtable_index) { Klass* k = h_recv->klass(); @@ -1355,12 +1356,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive // interface call KlassHandle h_holder(THREAD, holder); - int itbl_index = m->cached_itable_index(); - if (itbl_index == -1) { - itbl_index = klassItable::compute_itable_index(m); - m->set_cached_itable_index(itbl_index); - // the above may have grabbed a lock, 'm' and anything non-handlized can't be used again - } + int itbl_index = m->itable_index(); Klass* k = h_recv->klass(); selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); } diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index caed2d13612..d7a961edfbb 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1824,7 +1824,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, } if (!publicOnly || fs.access_flags().is_public()) { - fd.initialize(k(), fs.index()); + fd.reinitialize(k(), fs.index()); oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); result->obj_at_put(out_idx, field); ++out_idx; diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 803cf9a7545..db009a43361 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -2930,7 +2930,7 @@ void VM_RedefineClasses::check_methods_and_mark_as_obsolete( for (int i = 0; i < _deleted_methods_length; ++i) { Method* old_method = _deleted_methods[i]; - assert(old_method->vtable_index() < 0, + assert(!old_method->has_vtable_index(), "cannot delete methods with vtable entries");; // Mark all deleted methods as old and obsolete diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index ac1c796eb31..88b82b358e6 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -127,25 +127,37 @@ Handle MethodHandles::new_MemberName(TRAPS) { } oop MethodHandles::init_MemberName(Handle mname, Handle target) { + // This method is used from java.lang.invoke.MemberName constructors. + // It fills in the new MemberName from a java.lang.reflect.Member. Thread* thread = Thread::current(); oop target_oop = target(); Klass* target_klass = target_oop->klass(); if (target_klass == SystemDictionary::reflect_Field_klass()) { oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() - int mods = java_lang_reflect_Field::modifiers(target_oop); - oop type = java_lang_reflect_Field::type(target_oop); - oop name = java_lang_reflect_Field::name(target_oop); KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); - intptr_t offset = InstanceKlass::cast(k())->field_offset(slot); - return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset); + if (!k.is_null() && k->oop_is_instance()) { + fieldDescriptor fd(InstanceKlass::cast(k()), slot); + oop mname2 = init_field_MemberName(mname, fd); + if (mname2 != NULL) { + // Since we have the reified name and type handy, add them to the result. + if (java_lang_invoke_MemberName::name(mname2) == NULL) + java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop)); + if (java_lang_invoke_MemberName::type(mname2) == NULL) + java_lang_invoke_MemberName::set_type(mname2, java_lang_reflect_Field::type(target_oop)); + } + return mname2; + } } else if (target_klass == SystemDictionary::reflect_Method_klass()) { oop clazz = java_lang_reflect_Method::clazz(target_oop); int slot = java_lang_reflect_Method::slot(target_oop); KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); if (!k.is_null() && k->oop_is_instance()) { Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); - return init_method_MemberName(mname, m, true, k); + if (m == NULL || is_signature_polymorphic(m->intrinsic_id())) + return NULL; // do not resolve unless there is a concrete signature + CallInfo info(m, k()); + return init_method_MemberName(mname, info); } } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { oop clazz = java_lang_reflect_Constructor::clazz(target_oop); @@ -153,65 +165,50 @@ oop MethodHandles::init_MemberName(Handle mname, Handle target) { KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); if (!k.is_null() && k->oop_is_instance()) { Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); - return init_method_MemberName(mname, m, false, k); - } - } else if (target_klass == SystemDictionary::MemberName_klass()) { - // Note: This only works if the MemberName has already been resolved. - oop clazz = java_lang_invoke_MemberName::clazz(target_oop); - int flags = java_lang_invoke_MemberName::flags(target_oop); - Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop); - intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop); - KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); - int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; - if (vmtarget == NULL) return NULL; // not resolved - if ((flags & IS_FIELD) != 0) { - assert(vmtarget->is_klass(), "field vmtarget is Klass*"); - int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0); - // FIXME: how does k (receiver_limit) contribute? - KlassHandle k_vmtarget(thread, (Klass*)vmtarget); - return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex); - } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { - assert(vmtarget->is_method(), "method or constructor vmtarget is Method*"); - return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k); - } else { - return NULL; + if (m == NULL) return NULL; + CallInfo info(m, k()); + return init_method_MemberName(mname, info); } } return NULL; } -oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch, - KlassHandle receiver_limit_h) { - Klass* receiver_limit = receiver_limit_h(); - AccessFlags mods = m->access_flags(); - int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); - int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch - Klass* mklass = m->method_holder(); - if (receiver_limit == NULL) - receiver_limit = mklass; - if (m->is_initializer()) { - flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); - } else if (mods.is_static()) { - flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); - } else if (receiver_limit != mklass && - !receiver_limit->is_subtype_of(mklass)) { - return NULL; // bad receiver limit - } else if (do_dispatch && receiver_limit->is_interface() && - mklass->is_interface()) { +oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { + assert(info.resolved_appendix().is_null(), "only normal methods here"); + KlassHandle receiver_limit = info.resolved_klass(); + methodHandle m = info.resolved_method(); + int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); + int vmindex = Method::invalid_vtable_index; + + switch (info.call_kind()) { + case CallInfo::itable_call: + vmindex = info.itable_index(); + // More importantly, the itable index only works with the method holder. + receiver_limit = m->method_holder(); + assert(receiver_limit->verify_itable_index(vmindex), ""); flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); - receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible - vmindex = klassItable::compute_itable_index(m); - } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) { + break; + + case CallInfo::vtable_call: + vmindex = info.vtable_index(); flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); - // it is a miranda method, so m->vtable_index is not what we want - ResourceMark rm; - klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable(); - vmindex = vt->index_of_miranda(m->name(), m->signature()); - } else if (!do_dispatch || m->can_be_statically_bound()) { - flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); - } else { - flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); - vmindex = m->vtable_index(); + assert(receiver_limit->is_subtype_of(m->method_holder()), "virtual call must be type-safe"); + break; + + case CallInfo::direct_call: + vmindex = Method::nonvirtual_vtable_index; + if (m->is_static()) { + flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); + } else if (m->is_initializer()) { + flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); + assert(receiver_limit == m->method_holder(), "constructor call must be exactly typed"); + } else { + flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); + assert(receiver_limit->is_subtype_of(m->method_holder()), "special call must be type-safe"); + } + break; + + default: assert(false, "bad CallInfo"); return NULL; } // @CallerSensitive annotation detected @@ -221,7 +218,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa oop mname_oop = mname(); java_lang_invoke_MemberName::set_flags( mname_oop, flags); - java_lang_invoke_MemberName::set_vmtarget(mname_oop, m); + java_lang_invoke_MemberName::set_vmtarget(mname_oop, m()); java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); // Note: name and type can be lazily computed by resolve_MemberName, @@ -237,59 +234,19 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa return mname(); } -Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) { - Handle empty; - if (info.resolved_appendix().not_null()) { - // The resolved MemberName must not be accompanied by an appendix argument, - // since there is no way to bind this value into the MemberName. - // Caller is responsible to prevent this from happening. - THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); - } - methodHandle m = info.resolved_method(); - KlassHandle defc = info.resolved_klass(); - int vmindex = Method::invalid_vtable_index; - if (defc->is_interface() && m->method_holder()->is_interface()) { - // static interface methods do not reference vtable or itable - if (m->is_static()) { - vmindex = Method::nonvirtual_vtable_index; - } - // interface methods invoked via invokespecial also - // do not reference vtable or itable. - int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >> - REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK); - if (ref_kind == JVM_REF_invokeSpecial) { - vmindex = Method::nonvirtual_vtable_index; - } - // If neither m is static nor ref_kind is invokespecial, - // set it to itable index. - if (vmindex == Method::invalid_vtable_index) { - // LinkResolver does not report itable indexes! (fix this?) - vmindex = klassItable::compute_itable_index(m()); - } - } else if (m->can_be_statically_bound()) { - // LinkResolver reports vtable index even for final methods! - vmindex = Method::nonvirtual_vtable_index; - } else { - vmindex = info.vtable_index(); - } - oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc()); - assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), ""); - return Handle(THREAD, res); -} - -oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder, - AccessFlags mods, oop type, oop name, - intptr_t offset, bool is_setter) { - int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); - flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); +oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { + int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); + flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); - Metadata* vmtarget = field_holder(); - int vmindex = offset; // determines the field uniquely when combined with static bit + Metadata* vmtarget = fd.field_holder(); + int vmindex = fd.offset(); // determines the field uniquely when combined with static bit oop mname_oop = mname(); java_lang_invoke_MemberName::set_flags(mname_oop, flags); java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); - java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror()); + java_lang_invoke_MemberName::set_clazz(mname_oop, fd.field_holder()->java_mirror()); + oop type = field_signature_type_or_null(fd.signature()); + oop name = field_name_or_null(fd.name()); if (name != NULL) java_lang_invoke_MemberName::set_name(mname_oop, name); if (type != NULL) @@ -305,19 +262,6 @@ oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder, return mname(); } -Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) { - return Handle(); -#if 0 // FIXME - KlassHandle field_holder = info.klass(); - intptr_t field_offset = info.field_offset(); - return init_field_MemberName(mname_oop, field_holder(), - info.access_flags(), - type, name, - field_offset, false /*is_setter*/); -#endif -} - - // JVM 2.9 Special Methods: // A method is signature polymorphic if and only if all of the following conditions hold : // * It is declared in the java.lang.invoke.MethodHandle class. @@ -573,12 +517,12 @@ static oop object_java_mirror() { return SystemDictionary::Object_klass()->java_mirror(); } -static oop field_name_or_null(Symbol* s) { +oop MethodHandles::field_name_or_null(Symbol* s) { if (s == NULL) return NULL; return StringTable::lookup(s); } -static oop field_signature_type_or_null(Symbol* s) { +oop MethodHandles::field_signature_type_or_null(Symbol* s) { if (s == NULL) return NULL; BasicType bt = FieldType::basic_type(s); if (is_java_primitive(bt)) { @@ -701,7 +645,14 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) { return empty; } } - return init_method_MemberName(mname, result, THREAD); + if (result.resolved_appendix().not_null()) { + // The resolved MemberName must not be accompanied by an appendix argument, + // since there is no way to bind this value into the MemberName. + // Caller is responsible to prevent this from happening. + THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); + } + oop mname2 = init_method_MemberName(mname, result); + return Handle(THREAD, mname2); } case IS_CONSTRUCTOR: { @@ -719,22 +670,21 @@ Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) { } } assert(result.is_statically_bound(), ""); - return init_method_MemberName(mname, result, THREAD); + oop mname2 = init_method_MemberName(mname, result); + return Handle(THREAD, mname2); } case IS_FIELD: { - // This is taken from LinkResolver::resolve_field, sans access checks. - fieldDescriptor fd; // find_field initializes fd if found - KlassHandle sel_klass(THREAD, InstanceKlass::cast(defc())->find_field(name, type, &fd)); - // check if field exists; i.e., if a klass containing the field def has been selected - if (sel_klass.is_null()) return empty; // should not happen - oop type = field_signature_type_or_null(fd.signature()); - oop name = field_name_or_null(fd.name()); - bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind)); - mname = Handle(THREAD, - init_field_MemberName(mname, sel_klass, - fd.access_flags(), type, name, fd.offset(), is_setter)); - return mname; + fieldDescriptor result; // find_field initializes fd if found + { + assert(!HAS_PENDING_EXCEPTION, ""); + LinkResolver::resolve_field(result, defc, name, type, KlassHandle(), Bytecodes::_nop, false, false, THREAD); + if (HAS_PENDING_EXCEPTION) { + return empty; + } + } + oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind)); + return Handle(THREAD, mname2); } default: THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty); @@ -793,7 +743,6 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { } case IS_FIELD: { - // This is taken from LinkResolver::resolve_field, sans access checks. assert(vmtarget->is_klass(), "field vmtarget is Klass*"); if (!((Klass*) vmtarget)->oop_is_instance()) break; instanceKlassHandle defc(THREAD, (Klass*) vmtarget); @@ -872,11 +821,7 @@ int MethodHandles::find_MemberNames(KlassHandle k, Handle result(thread, results->obj_at(rfill++)); if (!java_lang_invoke_MemberName::is_instance(result())) return -99; // caller bug! - oop type = field_signature_type_or_null(st.signature()); - oop name = field_name_or_null(st.name()); - oop saved = MethodHandles::init_field_MemberName(result, st.klass(), - st.access_flags(), type, name, - st.offset()); + oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor()); if (saved != result()) results->obj_at_put(rfill-1, saved); // show saved instance to user } else if (++overflow >= overflow_limit) { @@ -926,7 +871,8 @@ int MethodHandles::find_MemberNames(KlassHandle k, Handle result(thread, results->obj_at(rfill++)); if (!java_lang_invoke_MemberName::is_instance(result())) return -99; // caller bug! - oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL); + CallInfo info(m); + oop saved = MethodHandles::init_method_MemberName(result, info); if (saved != result()) results->obj_at_put(rfill-1, saved); // show saved instance to user } else if (++overflow >= overflow_limit) { @@ -1227,7 +1173,8 @@ JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname x = ((Klass*) vmtarget)->java_mirror(); } else if (vmtarget->is_method()) { Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL); - x = MethodHandles::init_method_MemberName(mname2, (Method*)vmtarget, false, NULL); + CallInfo info((Method*)vmtarget); + x = MethodHandles::init_method_MemberName(mname2, info); } result->obj_at_put(1, x); return JNIHandles::make_local(env, result()); diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp index 50ce7af86ea..7ae7bd36fb5 100644 --- a/hotspot/src/share/vm/prims/methodHandles.hpp +++ b/hotspot/src/share/vm/prims/methodHandles.hpp @@ -49,19 +49,18 @@ class MethodHandles: AllStatic { // Adapters. static MethodHandlesAdapterBlob* _adapter_code; + // utility functions for reifying names and types + static oop field_name_or_null(Symbol* s); + static oop field_signature_type_or_null(Symbol* s); + public: // working with member names static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing static Handle new_MemberName(TRAPS); // must be followed by init_MemberName static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target - static oop init_method_MemberName(Handle mname_h, Method* m, bool do_dispatch, - KlassHandle receiver_limit_h); - static oop init_field_MemberName(Handle mname_h, KlassHandle field_holder_h, - AccessFlags mods, oop type, oop name, - intptr_t offset, bool is_setter = false); - static Handle init_method_MemberName(Handle mname_h, CallInfo& info, TRAPS); - static Handle init_field_MemberName(Handle mname_h, FieldAccessInfo& info, TRAPS); + static oop init_field_MemberName(Handle mname_h, fieldDescriptor& fd, bool is_setter = false); + static oop init_method_MemberName(Handle mname_h, CallInfo& info); static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true); static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig, int mflags, KlassHandle caller, diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp index 23d679494ac..79e3ddcd85d 100644 --- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp +++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp @@ -97,18 +97,32 @@ oop fieldDescriptor::string_initial_value(TRAPS) const { return constants()->uncached_string_at(initial_value_index(), CHECK_0); } -void fieldDescriptor::initialize(InstanceKlass* ik, int index) { - _cp = ik->constants(); +void fieldDescriptor::reinitialize(InstanceKlass* ik, int index) { + if (_cp.is_null() || field_holder() != ik) { + _cp = constantPoolHandle(Thread::current(), ik->constants()); + // _cp should now reference ik's constant pool; i.e., ik is now field_holder. + assert(field_holder() == ik, "must be already initialized to this class"); + } FieldInfo* f = ik->field(index); assert(!f->is_internal(), "regular Java fields only"); _access_flags = accessFlags_from(f->access_flags()); guarantee(f->name_index() != 0 && f->signature_index() != 0, "bad constant pool index for fieldDescriptor"); _index = index; + verify(); } #ifndef PRODUCT +void fieldDescriptor::verify() const { + if (_cp.is_null()) { + assert(_index == badInt, "constructor must be called"); // see constructor + } else { + assert(_index >= 0, "good index"); + assert(_index < field_holder()->java_fields_count(), "oob"); + } +} + void fieldDescriptor::print_on(outputStream* st) const { access_flags().print_on(st); name()->print_value_on(st); diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp index 12b75cab144..9c3101b38ba 100644 --- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp +++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,13 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC { } public: + fieldDescriptor() { + DEBUG_ONLY(_index = badInt); + } + fieldDescriptor(InstanceKlass* ik, int index) { + DEBUG_ONLY(_index = badInt); + reinitialize(ik, index); + } Symbol* name() const { return field()->name(_cp); } @@ -112,12 +119,13 @@ class fieldDescriptor VALUE_OBJ_CLASS_SPEC { } // Initialization - void initialize(InstanceKlass* ik, int index); + void reinitialize(InstanceKlass* ik, int index); // Print void print() { print_on(tty); } void print_on(outputStream* st) const PRODUCT_RETURN; void print_on_for(outputStream* st, oop obj) PRODUCT_RETURN; + void verify() const PRODUCT_RETURN; }; #endif // SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp index f513b7b376c..19f98cc2e4f 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp @@ -45,7 +45,6 @@ Mutex* InlineCacheBuffer_lock = NULL; Mutex* VMStatistic_lock = NULL; Mutex* JNIGlobalHandle_lock = NULL; Mutex* JNIHandleBlockFreeList_lock = NULL; -Mutex* JNICachedItableIndex_lock = NULL; Mutex* MemberNameTable_lock = NULL; Mutex* JmethodIdCreation_lock = NULL; Mutex* JfieldIdCreation_lock = NULL; @@ -253,7 +252,6 @@ void mutex_init() { } def(Heap_lock , Monitor, nonleaf+1, false); def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation - def(JNICachedItableIndex_lock , Mutex , nonleaf+1, false); // Used to cache an itable index during JNI invoke def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp index d98b8d890fd..361febdcdb8 100644 --- a/hotspot/src/share/vm/runtime/mutexLocker.hpp +++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,6 @@ extern Mutex* InlineCacheBuffer_lock; // a lock used to guard the Inl extern Mutex* VMStatistic_lock; // a lock used to guard statistics count increment extern Mutex* JNIGlobalHandle_lock; // a lock on creating JNI global handles extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list -extern Mutex* JNICachedItableIndex_lock; // a lock on caching an itable index during JNI invoke extern Mutex* MemberNameTable_lock; // a lock on the MemberNameTable updates extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index f06a7f922aa..be29fdecfcf 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -952,7 +952,8 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, } } else { // if the method can be overridden, we resolve using the vtable index. - int index = reflected_method->vtable_index(); + assert(!reflected_method->has_itable_index(), ""); + int index = reflected_method->vtable_index(); method = reflected_method; if (index != Method::nonvirtual_vtable_index) { // target_klass might be an arrayKlassOop but all vtables start at diff --git a/hotspot/src/share/vm/runtime/reflectionUtils.hpp b/hotspot/src/share/vm/runtime/reflectionUtils.hpp index d51b2ab7874..71a500976a7 100644 --- a/hotspot/src/share/vm/runtime/reflectionUtils.hpp +++ b/hotspot/src/share/vm/runtime/reflectionUtils.hpp @@ -109,6 +109,8 @@ class FieldStream : public KlassStream { private: int length() const { return _klass->java_fields_count(); } + fieldDescriptor _fd_buf; + public: FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only) : KlassStream(klass, local_only, classes_only) { @@ -134,6 +136,12 @@ class FieldStream : public KlassStream { int offset() const { return _klass->field_offset( index() ); } + // bridge to a heavier API: + fieldDescriptor& field_descriptor() const { + fieldDescriptor& field = const_cast(_fd_buf); + field.reinitialize(_klass(), _index); + return field; + } }; class FilteredField : public CHeapObj { diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 448a8919f0e..55405b27fd4 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -315,7 +315,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(InstanceKlass, _breakpoints, BreakpointInfo*) \ nonstatic_field(InstanceKlass, _generic_signature_index, u2) \ nonstatic_field(InstanceKlass, _methods_jmethod_ids, jmethodID*) \ - nonstatic_field(InstanceKlass, _methods_cached_itable_indices, int*) \ volatile_nonstatic_field(InstanceKlass, _idnum_allocated_count, u2) \ nonstatic_field(InstanceKlass, _annotations, Annotations*) \ nonstatic_field(InstanceKlass, _dependencies, nmethodBucket*) \ From c492e4ef1fa7888cf1a5f69249c0fd87b2dcc4ed Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Sat, 14 Sep 2013 22:46:49 +0100 Subject: [PATCH 099/293] 8024835: Change until() to accept any compatible temporal Method until(Temporal,TemporalUnit) now uses from() to convert; Enhance from() methods where necessary Reviewed-by: sherman --- jdk/src/share/classes/java/time/Duration.java | 8 +- jdk/src/share/classes/java/time/Instant.java | 26 ++++--- .../share/classes/java/time/LocalDate.java | 28 ++++--- .../classes/java/time/LocalDateTime.java | 26 +++---- .../share/classes/java/time/LocalTime.java | 23 +++--- jdk/src/share/classes/java/time/MonthDay.java | 3 +- .../classes/java/time/OffsetDateTime.java | 22 +++--- .../share/classes/java/time/OffsetTime.java | 22 +++--- jdk/src/share/classes/java/time/Year.java | 23 +++--- .../share/classes/java/time/YearMonth.java | 23 +++--- .../share/classes/java/time/ZoneOffset.java | 1 + .../classes/java/time/ZonedDateTime.java | 26 +++---- .../java/time/chrono/ChronoLocalDate.java | 17 +++-- .../java/time/chrono/ChronoLocalDateImpl.java | 21 ++---- .../java/time/chrono/ChronoLocalDateTime.java | 1 + .../time/chrono/ChronoLocalDateTimeImpl.java | 15 ++-- .../java/time/chrono/ChronoZonedDateTime.java | 1 + .../time/chrono/ChronoZonedDateTimeImpl.java | 19 ++--- .../java/time/temporal/ChronoUnit.java | 4 +- .../classes/java/time/temporal/IsoFields.java | 11 ++- .../classes/java/time/temporal/Temporal.java | 22 ++++-- .../java/time/temporal/TemporalUnit.java | 23 ++++-- .../java/time/tck/java/time/TCKDuration.java | 10 ++- .../java/time/tck/java/time/TCKInstant.java | 32 ++++++-- .../java/time/tck/java/time/TCKLocalDate.java | 29 +++++-- .../time/tck/java/time/TCKLocalDateTime.java | 27 ++++++- .../java/time/tck/java/time/TCKLocalTime.java | 29 +++++-- .../time/tck/java/time/TCKOffsetDateTime.java | 75 +++++++++++++++++++ .../time/tck/java/time/TCKOffsetTime.java | 62 ++++++++------- jdk/test/java/time/tck/java/time/TCKYear.java | 47 ++++++++---- .../java/time/tck/java/time/TCKYearMonth.java | 44 +++++++---- .../time/tck/java/time/TCKZonedDateTime.java | 22 +++--- .../time/tck/java/time/chrono/CopticDate.java | 12 +-- .../tck/java/time/temporal/TCKIsoFields.java | 11 ++- 34 files changed, 487 insertions(+), 278 deletions(-) diff --git a/jdk/src/share/classes/java/time/Duration.java b/jdk/src/share/classes/java/time/Duration.java index ce2ba7781b0..896a2990eaa 100644 --- a/jdk/src/share/classes/java/time/Duration.java +++ b/jdk/src/share/classes/java/time/Duration.java @@ -441,9 +441,13 @@ public final class Duration //----------------------------------------------------------------------- /** - * Obtains a {@code Duration} representing the duration between two instants. + * Obtains a {@code Duration} representing the duration between two temporal objects. + *

+ * This calculates the duration between two temporal objects. If the objects + * are of different types, then the duration is calculated based on the type + * of the first object. For example, if the first argument is a {@code LocalTime} + * then the second argument is converted to a {@code LocalTime}. *

- * This calculates the duration between two temporal objects of the same type. * The specified temporal objects must support the {@link ChronoUnit#SECONDS SECONDS} unit. * For full accuracy, either the {@link ChronoUnit#NANOS NANOS} unit or the * {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} field should be supported. diff --git a/jdk/src/share/classes/java/time/Instant.java b/jdk/src/share/classes/java/time/Instant.java index 9d74e29f91a..a7bd6f92004 100644 --- a/jdk/src/share/classes/java/time/Instant.java +++ b/jdk/src/share/classes/java/time/Instant.java @@ -362,6 +362,10 @@ public final class Instant * @throws DateTimeException if unable to convert to an {@code Instant} */ public static Instant from(TemporalAccessor temporal) { + if (temporal instanceof Instant) { + return (Instant) temporal; + } + Objects.requireNonNull(temporal, "temporal"); long instantSecs = temporal.getLong(INSTANT_SECONDS); int nanoOfSecond = temporal.get(NANO_OF_SECOND); return Instant.ofEpochSecond(instantSecs, nanoOfSecond); @@ -1091,7 +1095,8 @@ public final class Instant * The result will be negative if the end is before the start. * The calculation returns a whole number, representing the number of * complete units between the two instants. - * The {@code Temporal} passed to this method must be an {@code Instant}. + * The {@code Temporal} passed to this method is converted to a + * {@code Instant} using {@link #from(TemporalAccessor)}. * For example, the amount in days between two dates can be calculated * using {@code startInstant.until(endInstant, SECONDS)}. *

@@ -1112,25 +1117,22 @@ public final class Instant *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endInstant the end date, which must be an {@code Instant}, not null + * @param endExclusive the end date, exclusive, which is converted to an {@code Instant}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this instant and the end instant - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to an {@code Instant} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endInstant, TemporalUnit unit) { - if (endInstant instanceof Instant == false) { - Objects.requireNonNull(endInstant, "endInstant"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - Instant end = (Instant) endInstant; + public long until(Temporal endExclusive, TemporalUnit unit) { + Instant end = Instant.from(endExclusive); if (unit instanceof ChronoUnit) { ChronoUnit f = (ChronoUnit) unit; switch (f) { @@ -1145,7 +1147,7 @@ public final class Instant } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endInstant); + return unit.between(this, end); } private long nanosUntil(Instant end) { diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java index 110a80fc9c0..f388959aa63 100644 --- a/jdk/src/share/classes/java/time/LocalDate.java +++ b/jdk/src/share/classes/java/time/LocalDate.java @@ -353,6 +353,7 @@ public final class LocalDate * @throws DateTimeException if unable to convert to a {@code LocalDate} */ public static LocalDate from(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); LocalDate date = temporal.query(TemporalQuery.localDate()); if (date == null) { throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + temporal.getClass()); @@ -1125,11 +1126,11 @@ public final class LocalDate */ @Override public LocalDate plus(TemporalAmount amountToAdd) { - Objects.requireNonNull(amountToAdd, "amountToAdd"); if (amountToAdd instanceof Period) { Period periodToAdd = (Period) amountToAdd; return plusMonths(periodToAdd.toTotalMonths()).plusDays(periodToAdd.getDays()); } + Objects.requireNonNull(amountToAdd, "amountToAdd"); return (LocalDate) amountToAdd.addTo(this); } @@ -1358,11 +1359,11 @@ public final class LocalDate */ @Override public LocalDate minus(TemporalAmount amountToSubtract) { - Objects.requireNonNull(amountToSubtract, "amountToSubtract"); if (amountToSubtract instanceof Period) { Period periodToSubtract = (Period) amountToSubtract; return minusMonths(periodToSubtract.toTotalMonths()).minusDays(periodToSubtract.getDays()); } + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); return (LocalDate) amountToSubtract.subtractFrom(this); } @@ -1541,7 +1542,8 @@ public final class LocalDate * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified date. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code LocalDate}. + * The {@code Temporal} passed to this method is converted to a + * {@code LocalDate} using {@link #from(TemporalAccessor)}. * For example, the amount in days between two dates can be calculated * using {@code startDate.until(endDate, DAYS)}. *

@@ -1567,26 +1569,22 @@ public final class LocalDate *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endDate the end date, which must be a {@code LocalDate}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code LocalDate}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date and the end date - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code LocalDate} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDate, TemporalUnit unit) { - Objects.requireNonNull(unit, "unit"); - if (endDate instanceof LocalDate == false) { - Objects.requireNonNull(endDate, "endDate"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - LocalDate end = (LocalDate) endDate; + public long until(Temporal endExclusive, TemporalUnit unit) { + LocalDate end = LocalDate.from(endExclusive); if (unit instanceof ChronoUnit) { switch ((ChronoUnit) unit) { case DAYS: return daysUntil(end); @@ -1600,7 +1598,7 @@ public final class LocalDate } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endDate); + return unit.between(this, end); } long daysUntil(LocalDate end) { diff --git a/jdk/src/share/classes/java/time/LocalDateTime.java b/jdk/src/share/classes/java/time/LocalDateTime.java index d0b72b90f82..aed44dd4bfe 100644 --- a/jdk/src/share/classes/java/time/LocalDateTime.java +++ b/jdk/src/share/classes/java/time/LocalDateTime.java @@ -1129,11 +1129,11 @@ public final class LocalDateTime */ @Override public LocalDateTime plus(TemporalAmount amountToAdd) { - Objects.requireNonNull(amountToAdd, "amountToAdd"); if (amountToAdd instanceof Period) { Period periodToAdd = (Period) amountToAdd; return with(date.plus(periodToAdd), time); } + Objects.requireNonNull(amountToAdd, "amountToAdd"); return (LocalDateTime) amountToAdd.addTo(this); } @@ -1348,11 +1348,11 @@ public final class LocalDateTime */ @Override public LocalDateTime minus(TemporalAmount amountToSubtract) { - Objects.requireNonNull(amountToSubtract, "amountToSubtract"); if (amountToSubtract instanceof Period) { Period periodToSubtract = (Period) amountToSubtract; return with(date.minus(periodToSubtract), time); } + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); return (LocalDateTime) amountToSubtract.subtractFrom(this); } @@ -1621,7 +1621,8 @@ public final class LocalDateTime * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified date-time. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code LocalDateTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code LocalDateTime} using {@link #from(TemporalAccessor)}. * For example, the amount in days between two date-times can be calculated * using {@code startDateTime.until(endDateTime, DAYS)}. *

@@ -1649,25 +1650,22 @@ public final class LocalDateTime *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endDateTime the end date-time, which must be a {@code LocalDateTime}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code LocalDateTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date-time and the end date-time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code LocalDateTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof LocalDateTime == false) { - Objects.requireNonNull(endDateTime, "endDateTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - LocalDateTime end = (LocalDateTime) endDateTime; + public long until(Temporal endExclusive, TemporalUnit unit) { + LocalDateTime end = LocalDateTime.from(endExclusive); if (unit instanceof ChronoUnit) { if (unit.isTimeBased()) { long amount = date.daysUntil(end.date); @@ -1721,7 +1719,7 @@ public final class LocalDateTime } return date.until(endDate, unit); } - return unit.between(this, endDateTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/LocalTime.java b/jdk/src/share/classes/java/time/LocalTime.java index a6270db19cf..77ab2c7f286 100644 --- a/jdk/src/share/classes/java/time/LocalTime.java +++ b/jdk/src/share/classes/java/time/LocalTime.java @@ -394,6 +394,7 @@ public final class LocalTime * @throws DateTimeException if unable to convert to a {@code LocalTime} */ public static LocalTime from(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); LocalTime time = temporal.query(TemporalQuery.localTime()); if (time == null) { throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass()); @@ -1330,7 +1331,8 @@ public final class LocalTime * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified time. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code LocalTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code LocalTime} using {@link #from(TemporalAccessor)}. * For example, the amount in hours between two times can be calculated * using {@code startTime.until(endTime, HOURS)}. *

@@ -1356,25 +1358,22 @@ public final class LocalTime *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endTime the end time, which must be a {@code LocalTime}, not null + * @param endExclusive the end time, exclusive, which is converted to a {@code LocalTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this time and the end time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code LocalTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endTime, TemporalUnit unit) { - if (endTime instanceof LocalTime == false) { - Objects.requireNonNull(endTime, "endTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - LocalTime end = (LocalTime) endTime; + public long until(Temporal endExclusive, TemporalUnit unit) { + LocalTime end = LocalTime.from(endExclusive); if (unit instanceof ChronoUnit) { long nanosUntil = end.toNanoOfDay() - toNanoOfDay(); // no overflow switch ((ChronoUnit) unit) { @@ -1388,7 +1387,7 @@ public final class LocalTime } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/MonthDay.java b/jdk/src/share/classes/java/time/MonthDay.java index 22807822f2b..67f5d4fa87f 100644 --- a/jdk/src/share/classes/java/time/MonthDay.java +++ b/jdk/src/share/classes/java/time/MonthDay.java @@ -246,7 +246,8 @@ public final class MonthDay *

* The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} and * {@link ChronoField#DAY_OF_MONTH DAY_OF_MONTH} fields. - * The extraction is only permitted if the date-time has an ISO chronology. + * The extraction is only permitted if the temporal object has an ISO + * chronology, or can be converted to a {@code LocalDate}. *

* This method matches the signature of the functional interface {@link TemporalQuery} * allowing it to be used in queries via method reference, {@code MonthDay::from}. diff --git a/jdk/src/share/classes/java/time/OffsetDateTime.java b/jdk/src/share/classes/java/time/OffsetDateTime.java index f894e53e46f..410c7f3a747 100644 --- a/jdk/src/share/classes/java/time/OffsetDateTime.java +++ b/jdk/src/share/classes/java/time/OffsetDateTime.java @@ -1592,7 +1592,8 @@ public final class OffsetDateTime * For example, the period in days between two date-times can be calculated * using {@code startDateTime.until(endDateTime, DAYS)}. *

- * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code OffsetDateTime} using {@link #from(TemporalAccessor)}. * If the offset differs between the two date-times, the specified * end date-time is normalized to have the same offset as this date-time. *

@@ -1620,30 +1621,27 @@ public final class OffsetDateTime *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endDateTime the end date-time, which must be an {@code OffsetDateTime}, not null + * @param endExclusive the end date, exclusive, which is converted to an {@code OffsetDateTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date-time and the end date-time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to an {@code OffsetDateTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof OffsetDateTime == false) { - Objects.requireNonNull(endDateTime, "endDateTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + OffsetDateTime end = OffsetDateTime.from(endExclusive); if (unit instanceof ChronoUnit) { - OffsetDateTime end = (OffsetDateTime) endDateTime; end = end.withOffsetSameInstant(offset); return dateTime.until(end.dateTime, unit); } - return unit.between(this, endDateTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/OffsetTime.java b/jdk/src/share/classes/java/time/OffsetTime.java index 6c67ef82bb1..a8dbf8a7a56 100644 --- a/jdk/src/share/classes/java/time/OffsetTime.java +++ b/jdk/src/share/classes/java/time/OffsetTime.java @@ -1124,7 +1124,8 @@ public final class OffsetTime * For example, the period in hours between two times can be calculated * using {@code startTime.until(endTime, HOURS)}. *

- * The {@code Temporal} passed to this method must be an {@code OffsetTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code OffsetTime} using {@link #from(TemporalAccessor)}. * If the offset differs between the two times, then the specified * end time is normalized to have the same offset as this time. *

@@ -1150,26 +1151,23 @@ public final class OffsetTime *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endTime the end time, which must be an {@code OffsetTime}, not null + * @param endExclusive the end date, exclusive, which is converted to an {@code OffsetTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this time and the end time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to an {@code OffsetTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endTime, TemporalUnit unit) { - if (endTime instanceof OffsetTime == false) { - Objects.requireNonNull(endTime, "endTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + OffsetTime end = OffsetTime.from(endExclusive); if (unit instanceof ChronoUnit) { - OffsetTime end = (OffsetTime) endTime; long nanosUntil = end.toEpochNano() - toEpochNano(); // no overflow switch ((ChronoUnit) unit) { case NANOS: return nanosUntil; @@ -1182,7 +1180,7 @@ public final class OffsetTime } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/Year.java b/jdk/src/share/classes/java/time/Year.java index f51bda69664..377dfd5185a 100644 --- a/jdk/src/share/classes/java/time/Year.java +++ b/jdk/src/share/classes/java/time/Year.java @@ -242,6 +242,7 @@ public final class Year if (temporal instanceof Year) { return (Year) temporal; } + Objects.requireNonNull(temporal, "temporal"); try { if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { temporal = LocalDate.from(temporal); @@ -859,7 +860,8 @@ public final class Year * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified year. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code Year}. + * The {@code Temporal} passed to this method is converted to a + * {@code Year} using {@link #from(TemporalAccessor)}. * For example, the period in decades between two year can be calculated * using {@code startYear.until(endYear, DECADES)}. *

@@ -885,25 +887,22 @@ public final class Year *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endYear the end year, which must be a {@code Year}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code Year}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this year and the end year - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code Year} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endYear, TemporalUnit unit) { - if (endYear instanceof Year == false) { - Objects.requireNonNull(endYear, "endYear"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - Year end = (Year) endYear; + public long until(Temporal endExclusive, TemporalUnit unit) { + Year end = Year.from(endExclusive); if (unit instanceof ChronoUnit) { long yearsUntil = ((long) end.year) - year; // no overflow switch ((ChronoUnit) unit) { @@ -915,7 +914,7 @@ public final class Year } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endYear); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/YearMonth.java b/jdk/src/share/classes/java/time/YearMonth.java index 541676117eb..223c90ab0f0 100644 --- a/jdk/src/share/classes/java/time/YearMonth.java +++ b/jdk/src/share/classes/java/time/YearMonth.java @@ -245,6 +245,7 @@ public final class YearMonth if (temporal instanceof YearMonth) { return (YearMonth) temporal; } + Objects.requireNonNull(temporal, "temporal"); try { if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) { temporal = LocalDate.from(temporal); @@ -992,7 +993,8 @@ public final class YearMonth * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified year-month. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a {@code YearMonth}. + * The {@code Temporal} passed to this method is converted to a + * {@code YearMonth} using {@link #from(TemporalAccessor)}. * For example, the period in years between two year-months can be calculated * using {@code startYearMonth.until(endYearMonth, YEARS)}. *

@@ -1018,25 +1020,22 @@ public final class YearMonth *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endYearMonth the end year-month, which must be a {@code YearMonth}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code YearMonth}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this year-month and the end year-month - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code YearMonth} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endYearMonth, TemporalUnit unit) { - if (endYearMonth instanceof YearMonth == false) { - Objects.requireNonNull(endYearMonth, "endYearMonth"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - YearMonth end = (YearMonth) endYearMonth; + public long until(Temporal endExclusive, TemporalUnit unit) { + YearMonth end = YearMonth.from(endExclusive); if (unit instanceof ChronoUnit) { long monthsUntil = end.getProlepticMonth() - getProlepticMonth(); // no overflow switch ((ChronoUnit) unit) { @@ -1049,7 +1048,7 @@ public final class YearMonth } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endYearMonth); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/ZoneOffset.java b/jdk/src/share/classes/java/time/ZoneOffset.java index 2d63a978d8c..3475e5f4db3 100644 --- a/jdk/src/share/classes/java/time/ZoneOffset.java +++ b/jdk/src/share/classes/java/time/ZoneOffset.java @@ -333,6 +333,7 @@ public final class ZoneOffset * @throws DateTimeException if unable to convert to an {@code ZoneOffset} */ public static ZoneOffset from(TemporalAccessor temporal) { + Objects.requireNonNull(temporal, "temporal"); ZoneOffset offset = temporal.query(TemporalQuery.offset()); if (offset == null) { throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + temporal.getClass()); diff --git a/jdk/src/share/classes/java/time/ZonedDateTime.java b/jdk/src/share/classes/java/time/ZonedDateTime.java index 971ba6daf5b..1114ab4edd3 100644 --- a/jdk/src/share/classes/java/time/ZonedDateTime.java +++ b/jdk/src/share/classes/java/time/ZonedDateTime.java @@ -1540,11 +1540,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime plus(TemporalAmount amountToAdd) { - Objects.requireNonNull(amountToAdd, "amountToAdd"); if (amountToAdd instanceof Period) { Period periodToAdd = (Period) amountToAdd; return resolveLocal(dateTime.plus(periodToAdd)); } + Objects.requireNonNull(amountToAdd, "amountToAdd"); return (ZonedDateTime) amountToAdd.addTo(this); } @@ -1792,11 +1792,11 @@ public final class ZonedDateTime */ @Override public ZonedDateTime minus(TemporalAmount amountToSubtract) { - Objects.requireNonNull(amountToSubtract, "amountToSubtract"); if (amountToSubtract instanceof Period) { Period periodToSubtract = (Period) amountToSubtract; return resolveLocal(dateTime.minus(periodToSubtract)); } + Objects.requireNonNull(amountToSubtract, "amountToSubtract"); return (ZonedDateTime) amountToSubtract.subtractFrom(this); } @@ -2044,7 +2044,8 @@ public final class ZonedDateTime * For example, the period in days between two date-times can be calculated * using {@code startDateTime.until(endDateTime, DAYS)}. *

- * The {@code Temporal} passed to this method must be a {@code ZonedDateTime}. + * The {@code Temporal} passed to this method is converted to a + * {@code ZonedDateTime} using {@link #from(TemporalAccessor)}. * If the time-zone differs between the two zoned date-times, the specified * end date-time is normalized to have the same zone as this date-time. *

@@ -2086,26 +2087,23 @@ public final class ZonedDateTime *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as - * the second argument. + * passing {@code this} as the first argument and the converted input temporal + * as the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endDateTime the end date-time, which must be a {@code ZonedDateTime}, not null + * @param endExclusive the end date, exclusive, which is converted to a {@code ZonedDateTime}, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date-time and the end date-time - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code ZonedDateTime} * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ZonedDateTime == false) { - Objects.requireNonNull(endDateTime, "endDateTime"); - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + ZonedDateTime end = ZonedDateTime.from(endExclusive); if (unit instanceof ChronoUnit) { - ZonedDateTime end = (ZonedDateTime) endDateTime; end = end.withZoneSameInstant(zone); if (unit.isDateBased()) { return dateTime.until(end.dateTime, unit); @@ -2113,7 +2111,7 @@ public final class ZonedDateTime return toOffsetDateTime().until(end.toOffsetDateTime(), unit); } } - return unit.between(this, endDateTime); + return unit.between(this, end); } /** diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index 58ae3b8c1c5..58e4f5d5250 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -291,6 +291,7 @@ public interface ChronoLocalDate if (temporal instanceof ChronoLocalDate) { return (ChronoLocalDate) temporal; } + Objects.requireNonNull(temporal, "temporal"); Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass()); @@ -560,8 +561,8 @@ public interface ChronoLocalDate * objects in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified date. * The result will be negative if the end is before the start. - * The {@code Temporal} passed to this method must be a - * {@code ChronoLocalDate} in the same chronology. + * The {@code Temporal} passed to this method is converted to a + * {@code ChronoLocalDate} using {@link Chronology#date(TemporalAccessor)}. * The calculation returns a whole number, representing the number of * complete units between the two dates. * For example, the amount in days between two dates can be calculated @@ -585,20 +586,22 @@ public interface ChronoLocalDate *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as + * passing {@code this} as the first argument and the converted input temporal as * the second argument. *

* This instance is immutable and unaffected by this method call. * - * @param endDate the end date, which must be a {@code ChronoLocalDate} - * in the same chronology, not null + * @param endExclusive the end date, exclusive, which is converted to a + * {@code ChronoLocalDate} in the same chronology, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this date and the end date - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to a {@code ChronoLocalDate} + * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ @Override // override for Javadoc - long until(Temporal endDate, TemporalUnit unit); + long until(Temporal endExclusive, TemporalUnit unit); /** * Calculates the period between this date and another date as a {@code ChronoPeriod}. diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java index fd8c8f88662..6cb115d393e 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java @@ -372,22 +372,10 @@ abstract class ChronoLocalDateImpl } //----------------------------------------------------------------------- - /** - * {@inheritDoc} - * @throws DateTimeException {@inheritDoc} - * @throws ArithmeticException {@inheritDoc} - */ @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - Objects.requireNonNull(endDateTime, "endDateTime"); - Objects.requireNonNull(unit, "unit"); - if (endDateTime instanceof ChronoLocalDate == false) { - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } - ChronoLocalDate end = (ChronoLocalDate) endDateTime; - if (getChronology().equals(end.getChronology()) == false) { - throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + Objects.requireNonNull(endExclusive, "endExclusive"); + ChronoLocalDate end = getChronology().date(endExclusive); if (unit instanceof ChronoUnit) { switch ((ChronoUnit) unit) { case DAYS: return daysUntil(end); @@ -401,7 +389,8 @@ abstract class ChronoLocalDateImpl } throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return unit.between(this, endDateTime); + Objects.requireNonNull(unit, "unit"); + return unit.between(this, end); } private long daysUntil(ChronoLocalDate end) { diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java index be93f0e036a..cde8a982fbc 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java @@ -165,6 +165,7 @@ public interface ChronoLocalDateTime if (temporal instanceof ChronoLocalDateTime) { return (ChronoLocalDateTime) temporal; } + Objects.requireNonNull(temporal, "temporal"); Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass()); diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index 13b3a0e8817..817ae85411a 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -69,7 +69,6 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; -import java.time.DateTimeException; import java.time.LocalTime; import java.time.ZoneId; import java.time.temporal.ChronoField; @@ -369,15 +368,10 @@ final class ChronoLocalDateTimeImpl //----------------------------------------------------------------------- @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ChronoLocalDateTime == false) { - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoLocalDateTime end = (ChronoLocalDateTime) endDateTime; - if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) { - throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); - } + ChronoLocalDateTime end = (ChronoLocalDateTime) toLocalDate().getChronology().localDateTime(endExclusive); if (unit instanceof ChronoUnit) { if (unit.isTimeBased()) { long amount = end.getLong(EPOCH_DAY) - date.getLong(EPOCH_DAY); @@ -398,7 +392,8 @@ final class ChronoLocalDateTimeImpl } return date.until(endDate, unit); } - return unit.between(this, endDateTime); + Objects.requireNonNull(unit, "unit"); + return unit.between(this, end); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java index dd911fcd789..abe84799716 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java @@ -166,6 +166,7 @@ public interface ChronoZonedDateTime if (temporal instanceof ChronoZonedDateTime) { return (ChronoZonedDateTime) temporal; } + Objects.requireNonNull(temporal, "temporal"); Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass()); diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java index 1cc7b5b5786..1fe8ccf0192 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java @@ -69,7 +69,6 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; import java.io.Serializable; -import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -234,7 +233,7 @@ final class ChronoZonedDateTimeImpl if (trans != null && trans.isOverlap()) { ZoneOffset earlierOffset = trans.getOffsetBefore(); if (earlierOffset.equals(offset) == false) { - return new ChronoZonedDateTimeImpl(dateTime, earlierOffset, zone); + return new ChronoZonedDateTimeImpl<>(dateTime, earlierOffset, zone); } } return this; @@ -246,7 +245,7 @@ final class ChronoZonedDateTimeImpl if (trans != null) { ZoneOffset offset = trans.getOffsetAfter(); if (offset.equals(getOffset()) == false) { - return new ChronoZonedDateTimeImpl(dateTime, offset, zone); + return new ChronoZonedDateTimeImpl<>(dateTime, offset, zone); } } return this; @@ -308,20 +307,16 @@ final class ChronoZonedDateTimeImpl //----------------------------------------------------------------------- @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ChronoZonedDateTime == false) { - throw new DateTimeException("Unable to calculate amount as objects are of two different types"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoZonedDateTime end = (ChronoZonedDateTime) endDateTime; - if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) { - throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); - } + ChronoZonedDateTime end = (ChronoZonedDateTime) toLocalDate().getChronology().zonedDateTime(endExclusive); if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); return dateTime.until(end.toLocalDateTime(), unit); } - return unit.between(this, endDateTime); + Objects.requireNonNull(unit, "unit"); + return unit.between(this, end); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java index 19a37e46f4c..c7043272398 100644 --- a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java +++ b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java @@ -268,8 +268,8 @@ public enum ChronoUnit implements TemporalUnit { //----------------------------------------------------------------------- @Override - public long between(Temporal temporal1, Temporal temporal2) { - return temporal1.until(temporal2, this); + public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) { + return temporal1Inclusive.until(temporal2Exclusive, this); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/temporal/IsoFields.java b/jdk/src/share/classes/java/time/temporal/IsoFields.java index eae057afb2a..bb19c299875 100644 --- a/jdk/src/share/classes/java/time/temporal/IsoFields.java +++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java @@ -684,13 +684,16 @@ public final class IsoFields { } @Override - public long between(Temporal temporal1, Temporal temporal2) { + public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) { + if (temporal1Inclusive.getClass() != temporal2Exclusive.getClass()) { + return temporal1Inclusive.until(temporal2Exclusive, this); + } switch(this) { case WEEK_BASED_YEARS: - return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR), - temporal1.getLong(WEEK_BASED_YEAR)); + return Math.subtractExact(temporal2Exclusive.getLong(WEEK_BASED_YEAR), + temporal1Inclusive.getLong(WEEK_BASED_YEAR)); case QUARTER_YEARS: - return temporal1.until(temporal2, MONTHS) / 3; + return temporal1Inclusive.until(temporal2Exclusive, MONTHS) / 3; default: throw new IllegalStateException("Unreachable"); } diff --git a/jdk/src/share/classes/java/time/temporal/Temporal.java b/jdk/src/share/classes/java/time/temporal/Temporal.java index 54110bed771..9931c46f4f1 100644 --- a/jdk/src/share/classes/java/time/temporal/Temporal.java +++ b/jdk/src/share/classes/java/time/temporal/Temporal.java @@ -374,8 +374,9 @@ public interface Temporal extends TemporalAccessor { * Calculates the amount of time until another temporal in terms of the specified unit. *

* This calculates the amount of time between two temporal objects - * of the same type in terms of a single {@code TemporalUnit}. + * in terms of a single {@code TemporalUnit}. * The start and end points are {@code this} and the specified temporal. + * The end point is converted to be of the same type as the start point if different. * The result will be negative if the end is before the start. * For example, the period in hours between two temporal objects can be * calculated using {@code startTime.until(endTime, HOURS)}. @@ -412,31 +413,36 @@ public interface Temporal extends TemporalAccessor { *

* If the unit is not a {@code ChronoUnit}, then the result of this method * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} - * passing {@code this} as the first argument and the input temporal as + * passing {@code this} as the first argument and the converted input temporal as * the second argument. *

- * In summary, implementations must behave in a manner equivalent to this code: + * In summary, implementations must behave in a manner equivalent to this pseudo-code: *

-     *  // check input temporal is the same type as this class
+     *  // convert the end temporal to the same type as this class
      *  if (unit instanceof ChronoUnit) {
      *    // if unit is supported, then calculate and return result
      *    // else throw UnsupportedTemporalTypeException for unsupported units
      *  }
-     *  return unit.between(this, endTemporal);
+     *  return unit.between(this, convertedEndTemporal);
      * 
*

+ * Note that the unit's {@code between} method must only be invoked if the + * two temporal objects have exactly the same type evaluated by {@code getClass()}. + *

* Implementations must ensure that no observable state is altered when this * read-only method is invoked. * - * @param endTemporal the end temporal, of the same type as this object, not null + * @param endExclusive the end temporal, exclusive, converted to be of the + * same type as this object, not null * @param unit the unit to measure the amount in, not null * @return the amount of time between this temporal object and the specified one * in terms of the unit; positive if the specified object is later than this one, * negative if it is earlier than this one - * @throws DateTimeException if the amount cannot be calculated + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to the same type as this temporal * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ - long until(Temporal endTemporal, TemporalUnit unit); + long until(Temporal endExclusive, TemporalUnit unit); } diff --git a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java index 05577d713f8..1c41afa0593 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java @@ -231,7 +231,9 @@ public interface TemporalUnit { * Calculates the amount of time between two temporal objects. *

* This calculates the amount in terms of this unit. The start and end - * points are supplied as temporal objects and must be of the same type. + * points are supplied as temporal objects and must be of compatible types. + * The implementation will convert the second type to be an instance of the + * first type before the calculating the amount. * The result will be negative if the end is before the start. * For example, the amount in hours between two temporal objects can be * calculated using {@code HOURS.between(startTime, endTime)}. @@ -264,15 +266,22 @@ public interface TemporalUnit { * If the unit is not supported an {@code UnsupportedTemporalTypeException} must be thrown. * Implementations must not alter the specified temporal objects. * - * @param temporal1 the base temporal object, not null - * @param temporal2 the other temporal object, not null - * @return the amount of time between temporal1 and temporal2 in terms of this unit; - * positive if temporal2 is later than temporal1, negative if earlier - * @throws DateTimeException if the amount cannot be calculated + * @implSpec + * Implementations must begin by checking to if the two temporals have the + * same type using {@code getClass()}. If they do not, then the result must be + * obtained by calling {@code temporal1Inclusive.until(temporal2Exclusive, this)}. + * + * @param temporal1Inclusive the base temporal object, not null + * @param temporal2Exclusive the other temporal object, exclusive, not null + * @return the amount of time between temporal1Inclusive and temporal2Exclusive + * in terms of this unit; positive if temporal2Exclusive is later than + * temporal1Inclusive, negative if earlier + * @throws DateTimeException if the amount cannot be calculated, or the end + * temporal cannot be converted to the same type as the start temporal * @throws UnsupportedTemporalTypeException if the unit is not supported by the temporal * @throws ArithmeticException if numeric overflow occurs */ - long between(Temporal temporal1, Temporal temporal2); + long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive); //----------------------------------------------------------------------- /** diff --git a/jdk/test/java/time/tck/java/time/TCKDuration.java b/jdk/test/java/time/tck/java/time/TCKDuration.java index c3bb0c9c906..c12e914b91f 100644 --- a/jdk/test/java/time/tck/java/time/TCKDuration.java +++ b/jdk/test/java/time/tck/java/time/TCKDuration.java @@ -77,6 +77,7 @@ import java.io.DataOutputStream; import java.time.DateTimeException; import java.time.Duration; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Period; @@ -843,10 +844,17 @@ public class TCKDuration extends AbstractTCKTest { assertEquals(Duration.between(end, start), Duration.between(start, end).negated()); } - @Test(expectedExceptions=DateTimeException.class) + @Test public void factory_between_TemporalTemporal_mixedTypes() { Instant start = Instant.ofEpochSecond(1); ZonedDateTime end = Instant.ofEpochSecond(4).atZone(ZoneOffset.UTC); + assertEquals(Duration.between(start, end), Duration.ofSeconds(3)); + } + + @Test(expectedExceptions=DateTimeException.class) + public void factory_between_TemporalTemporal_invalidMixedTypes() { + Instant start = Instant.ofEpochSecond(1); + LocalDate end = LocalDate.of(2010, 6, 20); Duration.between(start, end); } diff --git a/jdk/test/java/time/tck/java/time/TCKInstant.java b/jdk/test/java/time/tck/java/time/TCKInstant.java index bb3a765de42..bf6ac9e7026 100644 --- a/jdk/test/java/time/tck/java/time/TCKInstant.java +++ b/jdk/test/java/time/tck/java/time/TCKInstant.java @@ -84,6 +84,7 @@ import java.time.DateTimeException; import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZoneOffset; @@ -1800,7 +1801,7 @@ public class TCKInstant extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); long amount = i1.until(i2, unit); @@ -1808,25 +1809,46 @@ public class TCKInstant extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); long amount = i2.until(i1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { + Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); + Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); + long amount = unit.between(i1, i2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + Instant start = Instant.ofEpochSecond(12, 3000); + OffsetDateTime end = start.plusSeconds(2).atOffset(ZoneOffset.ofHours(2)); + assertEquals(start.until(end, SECONDS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + Instant start = Instant.ofEpochSecond(12, 3000); + start.until(LocalTime.of(11, 30), SECONDS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_12345_123456789.until(TEST_12345_123456789, MONTHS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_12345_123456789.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_12345_123456789.until(TEST_12345_123456789, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/TCKLocalDate.java index 3d4cbbbc884..cb41a707945 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java @@ -1723,29 +1723,48 @@ public class TCKLocalDate extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { long amount = date1.until(date2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { long amount = date2.until(date1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { + long amount = unit.between(date1, date2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + LocalDate start = LocalDate.of(2010, 6, 30); + OffsetDateTime end = start.plusDays(2).atStartOfDay().atOffset(OFFSET_PONE); + assertEquals(start.until(end, DAYS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + LocalDate start = LocalDate.of(2010, 6, 30); + start.until(LocalTime.of(11, 30), DAYS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_2007_07_15.until(TEST_2007_07_15, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2007_07_15.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2007_07_15.until(TEST_2007_07_15, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java index 040704cd9bc..62b53b3b8a3 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java @@ -2895,24 +2895,43 @@ public class TCKLocalDateTime extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { long amount = dt1.until(dt2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { long amount = dt2.until(dt1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { + long amount = unit.between(dt1, dt2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30); + OffsetDateTime end = start.plusDays(2).atOffset(OFFSET_PONE); + assertEquals(start.until(end, DAYS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30); + start.until(LocalTime.of(11, 30), DAYS); + } + @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2007_07_15_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2007_07_15_12_30_40_987654321.until(TEST_2007_07_15_12_30_40_987654321, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java index 2291b5ca16b..bac3f8587d1 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java @@ -1971,29 +1971,48 @@ public class TCKLocalTime extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { long amount = time1.until(time2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { long amount = time2.until(time1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { + long amount = unit.between(time1, time2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + LocalTime start = LocalTime.of(11, 30); + LocalDateTime end = start.plusSeconds(2).atDate(LocalDate.of(2010, 6, 30)); + assertEquals(start.until(end, SECONDS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + LocalTime start = LocalTime.of(11, 30); + start.until(LocalDate.of(2010, 6, 30), SECONDS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java index 0cf024fdde1..0ced814d06b 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java @@ -91,6 +91,13 @@ import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HALF_DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; import static java.time.temporal.ChronoUnit.NANOS; import static java.time.temporal.ChronoUnit.SECONDS; import static org.testng.Assert.assertEquals; @@ -1128,6 +1135,74 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(test, OffsetDateTime.of(2008, 6, 30, 11, 30, 58, 999999999, OFFSET_PONE)); } + //----------------------------------------------------------------------- + // until(Temporal, TemporalUnit) + //----------------------------------------------------------------------- + @DataProvider(name="periodUntilUnit") + Object[][] data_untilUnit() { + return new Object[][] { + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 13, 1, 1, 0, OFFSET_PONE), HALF_DAYS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), HOURS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MINUTES, 60}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), SECONDS, 3600}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MILLIS, 3600*1000}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MICROS, 3600*1000*1000L}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), NANOS, 3600*1000*1000L*1000}, + + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 14, 1, 1, 0, OFFSET_PTWO), HALF_DAYS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), HOURS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MINUTES, 60}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), SECONDS, 3600}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MILLIS, 3600*1000}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MICROS, 3600*1000*1000L}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), NANOS, 3600*1000*1000L*1000}, + + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 7, 1, 1, 1, 0, 999999999, OFFSET_PONE), DAYS, 0}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 7, 1, 1, 1, 1, 0, OFFSET_PONE), DAYS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 29, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 1}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 30, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 2}, + {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 31, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 2}, + }; + } + + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) { + long amount = odt1.until(odt2, unit); + assertEquals(amount, expected); + } + + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_negated(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) { + long amount = odt2.until(odt1, unit); + assertEquals(amount, -expected); + } + + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) { + long amount = unit.between(odt1, odt2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + OffsetDateTime odt = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE); + ZonedDateTime zdt = odt.plusSeconds(3).toZonedDateTime(); + assertEquals(odt.until(zdt, SECONDS), 3); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + OffsetDateTime odt = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE); + odt.until(Instant.ofEpochSecond(12), SECONDS); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidTemporalUnit() { + OffsetDateTime odt1 = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE); + OffsetDateTime odt2 = OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE); + odt1.until(odt2, FOREVER); + } + //----------------------------------------------------------------------- // format(DateTimeFormatter) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java index ee5b2d3f69f..5bc2312ea0f 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java @@ -1069,49 +1069,61 @@ public class TCKOffsetTime extends AbstractDateTimeTest { // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") - Object[][] data_periodUntilUnit() { + Object[][] data_untilUnit() { return new Object[][] { - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(13, 1, 1), ZoneOffset.ofHours(1)), HALF_DAYS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), HOURS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MINUTES, 60}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), SECONDS, 3600}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MILLIS, 3600*1000}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MICROS, 3600*1000*1000L}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), NANOS, 3600*1000*1000L*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(13, 1, 1, 0, OFFSET_PONE), HALF_DAYS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), HOURS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MINUTES, 60}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), SECONDS, 3600}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MILLIS, 3600*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MICROS, 3600*1000*1000L}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), NANOS, 3600*1000*1000L*1000}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(14, 1, 1), ZoneOffset.ofHours(2)), HALF_DAYS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), HOURS, 1}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MINUTES, 60}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), SECONDS, 3600}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MILLIS, 3600*1000}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MICROS, 3600*1000*1000L}, - {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), NANOS, 3600*1000*1000L*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(14, 1, 1, 0, OFFSET_PTWO), HALF_DAYS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), HOURS, 1}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MINUTES, 60}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), SECONDS, 3600}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MILLIS, 3600*1000}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MICROS, 3600*1000*1000L}, + {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), NANOS, 3600*1000*1000L*1000}, }; } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { long amount = offsetTime1.until(offsetTime2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { long amount = offsetTime2.until(offsetTime1, unit); assertEquals(amount, -expected); } - @Test(expectedExceptions=DateTimeException.class) - public void test_periodUntil_InvalidType() { - OffsetTime offsetTime = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); - OffsetDateTime offsetDateTime = offsetTime.atDate(LocalDate.of(1980, 2, 10)); - offsetTime.until(offsetDateTime, SECONDS); + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { + long amount = unit.between(offsetTime1, offsetTime2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + OffsetTime offsetTime = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE); + OffsetDateTime offsetDateTime = offsetTime.plusSeconds(3).atDate(LocalDate.of(1980, 2, 10)); + assertEquals(offsetTime.until(offsetDateTime, SECONDS), 3); } @Test(expectedExceptions=DateTimeException.class) - public void test_periodUntil_InvalidTemporalUnit() { - OffsetTime offsetTime1 = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); - OffsetTime offsetTime2 = OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)); + public void test_until_invalidType() { + OffsetTime offsetTime = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE); + offsetTime.until(LocalDate.of(1980, 2, 10), SECONDS); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidTemporalUnit() { + OffsetTime offsetTime1 = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE); + OffsetTime offsetTime2 = OffsetTime.of(2, 1, 1, 0, OFFSET_PONE); offsetTime1.until(offsetTime2, MONTHS); } diff --git a/jdk/test/java/time/tck/java/time/TCKYear.java b/jdk/test/java/time/tck/java/time/TCKYear.java index c0a35967a7b..59d464a5373 100644 --- a/jdk/test/java/time/tck/java/time/TCKYear.java +++ b/jdk/test/java/time/tck/java/time/TCKYear.java @@ -65,10 +65,8 @@ import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static java.time.temporal.ChronoUnit.CENTURIES; import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.DECADES; -import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.MONTHS; -import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.ChronoUnit.YEARS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -90,8 +88,8 @@ import java.time.Year; import java.time.YearMonth; import java.time.ZoneId; import java.time.ZoneOffset; -import java.time.chrono.IsoEra; import java.time.chrono.IsoChronology; +import java.time.chrono.IsoEra; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoField; @@ -229,17 +227,17 @@ public class TCKYear extends AbstractDateTimeTest { //----------------------------------------------------------------------- @Test - public void test_factory_CalendricalObject() { + public void test_from_TemporalAccessor() { assertEquals(Year.from(LocalDate.of(2007, 7, 15)), Year.of(2007)); } @Test(expectedExceptions=DateTimeException.class) - public void test_factory_CalendricalObject_invalid_noDerive() { + public void test_from_TemporalAccessor_invalid_noDerive() { Year.from(LocalTime.of(12, 30)); } @Test(expectedExceptions=NullPointerException.class) - public void test_factory_CalendricalObject_null() { + public void test_from_TemporalAccessor_null() { Year.from((TemporalAccessor) null); } @@ -597,13 +595,13 @@ public class TCKYear extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit") + @Test(dataProvider="plus_long_TemporalUnit") public void test_plus_long_TemporalUnit(Year base, long amount, TemporalUnit unit, Year expectedYear, Class expectedEx) { if (expectedEx == null) { assertEquals(base.plus(amount, unit), expectedYear); } else { try { - Year result = base.plus(amount, unit); + base.plus(amount, unit); fail(); } catch (Exception ex) { assertTrue(expectedEx.isInstance(ex)); @@ -729,7 +727,7 @@ public class TCKYear extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit") + @Test(dataProvider="minus_long_TemporalUnit") public void test_minus_long_TemporalUnit(Year base, long amount, TemporalUnit unit, Year expectedYear, Class expectedEx) { if (expectedEx == null) { assertEquals(base.minus(amount, unit), expectedYear); @@ -788,7 +786,7 @@ public class TCKYear extends AbstractDateTimeTest { //----------------------------------------------------------------------- // with(TemporalField, long) //----------------------------------------------------------------------- - @Test(groups={"tck"}) + @Test public void test_with() { Year base = Year.of(5); Year result = base.with(ChronoField.ERA, 0); @@ -923,29 +921,48 @@ public class TCKYear extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) { long amount = year1.until(year2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) { long amount = year2.until(year1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(Year year1, Year year2, TemporalUnit unit, long expected) { + long amount = unit.between(year1, year2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + Year start = Year.of(2010); + YearMonth end = start.plusYears(2).atMonth(Month.APRIL); + assertEquals(start.until(end, YEARS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + Year start = Year.of(2010); + start.until(LocalTime.of(11, 30), YEARS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_2008.until(TEST_2008, MONTHS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2008.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2008.until(TEST_2008, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/TCKYearMonth.java index e1f1a466574..bb16839bda1 100644 --- a/jdk/test/java/time/tck/java/time/TCKYearMonth.java +++ b/jdk/test/java/time/tck/java/time/TCKYearMonth.java @@ -70,7 +70,6 @@ import static java.time.temporal.ChronoUnit.DECADES; import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.MONTHS; -import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.ChronoUnit.YEARS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -270,17 +269,17 @@ public class TCKYearMonth extends AbstractDateTimeTest { //----------------------------------------------------------------------- @Test - public void test_factory_CalendricalObject() { + public void test_from_TemporalAccessor() { assertEquals(YearMonth.from(LocalDate.of(2007, 7, 15)), YearMonth.of(2007, 7)); } @Test(expectedExceptions=DateTimeException.class) - public void test_factory_CalendricalObject_invalid_noDerive() { + public void test_from_TemporalAccessor_invalid_noDerive() { YearMonth.from(LocalTime.of(12, 30)); } @Test(expectedExceptions=NullPointerException.class) - public void test_factory_CalendricalObject_null() { + public void test_from_TemporalAccessor_null() { YearMonth.from((TemporalAccessor) null); } @@ -768,7 +767,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit") + @Test(dataProvider="plus_long_TemporalUnit") public void test_plus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.plus(amount, unit), expectedYearMonth); @@ -820,7 +819,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="plus_TemporalAmount") + @Test(dataProvider="plus_TemporalAmount") public void test_plus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.plus(temporalAmount), expectedYearMonth); @@ -983,7 +982,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit") + @Test(dataProvider="minus_long_TemporalUnit") public void test_minus_long_TemporalUnit(YearMonth base, long amount, TemporalUnit unit, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.minus(amount, unit), expectedYearMonth); @@ -1035,7 +1034,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { }; } - @Test(groups={"tck"}, dataProvider="minus_TemporalAmount") + @Test(dataProvider="minus_TemporalAmount") public void test_minus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) { if (expectedEx == null) { assertEquals(base.minus(temporalAmount), expectedYearMonth); @@ -1243,29 +1242,48 @@ public class TCKYearMonth extends AbstractDateTimeTest { } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { long amount = ym1.until(ym2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") - public void test_periodUntil_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { + public void test_until_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { long amount = ym2.until(ym1, unit); assertEquals(amount, -expected); } + @Test(dataProvider="periodUntilUnit") + public void test_until_TemporalUnit_between(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { + long amount = unit.between(ym1, ym2); + assertEquals(amount, expected); + } + + @Test + public void test_until_convertedType() { + YearMonth start = YearMonth.of(2010, 6); + LocalDate end = start.plusMonths(2).atDay(12); + assertEquals(start.until(end, MONTHS), 2); + } + + @Test(expectedExceptions=DateTimeException.class) + public void test_until_invalidType() { + YearMonth start = YearMonth.of(2010, 6); + start.until(LocalTime.of(11, 30), MONTHS); + } + @Test(expectedExceptions = UnsupportedTemporalTypeException.class) - public void test_periodUntil_TemporalUnit_unsupportedUnit() { + public void test_until_TemporalUnit_unsupportedUnit() { TEST_2008_06.until(TEST_2008_06, HOURS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullEnd() { + public void test_until_TemporalUnit_nullEnd() { TEST_2008_06.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) - public void test_periodUntil_TemporalUnit_nullUnit() { + public void test_until_TemporalUnit_nullUnit() { TEST_2008_06.until(TEST_2008_06, null); } diff --git a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java index 1f5bee32283..4c5319d483a 100644 --- a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java @@ -2001,7 +2001,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { // compare results to OffsetDateTime.until, especially wrt dates @Test(dataProvider="plusDays") - public void test_periodUntil_days(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_days(ZonedDateTime base, long expected, ZonedDateTime end) { if (base.toLocalTime().equals(end.toLocalTime()) == false) { return; // avoid DST gap input values } @@ -2009,27 +2009,27 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test(dataProvider="plusTime") - public void test_periodUntil_hours(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_hours(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, HOURS), expected); } @Test(dataProvider="plusTime") - public void test_periodUntil_minutes(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_minutes(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, MINUTES), expected * 60); } @Test(dataProvider="plusTime") - public void test_periodUntil_seconds(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_seconds(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, SECONDS), expected * 3600); } @Test(dataProvider="plusTime") - public void test_periodUntil_nanos(ZonedDateTime base, long expected, ZonedDateTime end) { + public void test_until_nanos(ZonedDateTime base, long expected, ZonedDateTime end) { assertEquals(base.until(end, NANOS), expected * 3600_000_000_000L); } @Test - public void test_periodUntil_parisLondon() { + public void test_until_parisLondon() { ZonedDateTime midnightLondon = LocalDate.of(2012, 6, 28).atStartOfDay(ZONE_LONDON); ZonedDateTime midnightParis1 = LocalDate.of(2012, 6, 29).atStartOfDay(ZONE_PARIS); ZonedDateTime oneAm1 = LocalDateTime.of(2012, 6, 29, 1, 0).atZone(ZONE_PARIS); @@ -2045,7 +2045,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test - public void test_periodUntil_gap() { + public void test_until_gap() { ZonedDateTime before = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); @@ -2054,7 +2054,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test - public void test_periodUntil_overlap() { + public void test_until_overlap() { ZonedDateTime before = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); @@ -2063,17 +2063,17 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } @Test(expectedExceptions=DateTimeException.class) - public void test_periodUntil_differentType() { + public void test_until_differentType() { TEST_DATE_TIME_PARIS.until(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS); } @Test(expectedExceptions=NullPointerException.class) - public void test_periodUntil_nullTemporal() { + public void test_until_nullTemporal() { TEST_DATE_TIME_PARIS.until(null, DAYS); } @Test(expectedExceptions=NullPointerException.class) - public void test_periodUntil_nullUnit() { + public void test_until_nullUnit() { TEST_DATE_TIME_PARIS.until(TEST_DATE_TIME_PARIS, null); } diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java index 6377c1fc421..c0da6975623 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java @@ -297,18 +297,12 @@ public final class CopticDate } @Override - public long until(Temporal endDateTime, TemporalUnit unit) { - if (endDateTime instanceof ChronoLocalDate == false) { - throw new DateTimeException("Unable to calculate period between objects of two different types"); - } - ChronoLocalDate end = (ChronoLocalDate) endDateTime; - if (getChronology().equals(end.getChronology()) == false) { - throw new DateTimeException("Unable to calculate period between two different chronologies"); - } + public long until(Temporal endExclusive, TemporalUnit unit) { + CopticDate end = getChronology().date(endExclusive); if (unit instanceof ChronoUnit) { return LocalDate.from(this).until(end, unit); // TODO: this is wrong } - return unit.between(this, endDateTime); + return unit.between(this, end); } @Override diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java index 7159b312866..d607571aba1 100644 --- a/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/TCKIsoFields.java @@ -70,11 +70,13 @@ import static org.testng.Assert.fail; import java.time.DayOfWeek; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; import java.time.temporal.IsoFields; +import java.time.temporal.Temporal; import java.time.temporal.ValueRange; import org.testng.annotations.DataProvider; @@ -276,14 +278,21 @@ public class TCKIsoFields { {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 12, 31), -4}, {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 2), -4}, {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 1), -5}, + + {LocalDate.of(2000, 1, 1), LocalDateTime.of(2001, 4, 5, 0, 0), 5}, }; } @Test(dataProvider="quartersBetween") - public void test_quarters_between(LocalDate start, LocalDate end, long expected) { + public void test_quarters_between(LocalDate start, Temporal end, long expected) { assertEquals(IsoFields.QUARTER_YEARS.between(start, end), expected); } + @Test(dataProvider="quartersBetween") + public void test_quarters_between_until(LocalDate start, Temporal end, long expected) { + assertEquals(start.until(end, IsoFields.QUARTER_YEARS), expected); + } + //----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- From d18aae693d00009b2e91a3a852210c7fd4ff09b8 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 4 Oct 2013 12:01:29 -0400 Subject: [PATCH 100/293] 8024999: Instant.Parse typo in example Javadoc only fix to correct example to use "." and "Z" Reviewed-by: sherman --- jdk/src/share/classes/java/time/Instant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/time/Instant.java b/jdk/src/share/classes/java/time/Instant.java index a7bd6f92004..0e22c7bf972 100644 --- a/jdk/src/share/classes/java/time/Instant.java +++ b/jdk/src/share/classes/java/time/Instant.java @@ -374,7 +374,7 @@ public final class Instant //----------------------------------------------------------------------- /** * Obtains an instance of {@code Instant} from a text string such as - * {@code 2007-12-03T10:15:30:00}. + * {@code 2007-12-03T10:15:30.00Z}. *

* The string must represent a valid instant in UTC and is parsed using * {@link DateTimeFormatter#ISO_INSTANT}. From 2040c66b16231be86df4e288dcd1b79ae8790df2 Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Sat, 14 Sep 2013 22:50:40 +0100 Subject: [PATCH 101/293] 8024807: Add getChronlogy() to CLDT/CZDT Alternative to method is clunky and hard to find Reviewed-by: sherman --- .../java/time/chrono/ChronoLocalDateTime.java | 24 ++++++++++++++----- .../time/chrono/ChronoLocalDateTimeImpl.java | 6 ++--- .../java/time/chrono/ChronoZonedDateTime.java | 24 ++++++++++++++----- .../time/chrono/ChronoZonedDateTimeImpl.java | 12 +++++----- .../time/chrono/TCKChronoLocalDateTime.java | 7 ++++++ .../time/chrono/TCKChronoZonedDateTime.java | 7 ++++++ 6 files changed, 59 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java index cde8a982fbc..4c2ddfd31a7 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java @@ -174,6 +174,18 @@ public interface ChronoLocalDateTime } //----------------------------------------------------------------------- + /** + * Gets the chronology of this date-time. + *

+ * The {@code Chronology} represents the calendar system in use. + * The era and other fields in {@link ChronoField} are defined by the chronology. + * + * @return the chronology, not null + */ + default Chronology getChronology() { + return toLocalDate().getChronology(); + } + /** * Gets the local date part of this date-time. *

@@ -251,7 +263,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime with(TemporalAdjuster adjuster) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -269,7 +281,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime plus(TemporalAmount amount) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -287,7 +299,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime minus(TemporalAmount amount) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -297,7 +309,7 @@ public interface ChronoLocalDateTime */ @Override default ChronoLocalDateTime minus(long amountToSubtract, TemporalUnit unit) { - return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); + return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- @@ -327,7 +339,7 @@ public interface ChronoLocalDateTime } else if (query == TemporalQuery.localTime()) { return (R) toLocalTime(); } else if (query == TemporalQuery.chronology()) { - return (R) toLocalDate().getChronology(); + return (R) getChronology(); } else if (query == TemporalQuery.precision()) { return (R) NANOS; } @@ -489,7 +501,7 @@ public interface ChronoLocalDateTime if (cmp == 0) { cmp = toLocalTime().compareTo(other.toLocalTime()); if (cmp == 0) { - cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology()); + cmp = getChronology().compareTo(other.getChronology()); } } return cmp; diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index 817ae85411a..e33e82ebab2 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -186,9 +186,9 @@ final class ChronoLocalDateTimeImpl static ChronoLocalDateTimeImpl ensureValid(Chronology chrono, Temporal temporal) { @SuppressWarnings("unchecked") ChronoLocalDateTimeImpl other = (ChronoLocalDateTimeImpl) temporal; - if (chrono.equals(other.toLocalDate().getChronology()) == false) { + if (chrono.equals(other.getChronology()) == false) { throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() - + ", actual: " + other.toLocalDate().getChronology().getId()); + + ", actual: " + other.getChronology().getId()); } return other; } @@ -371,7 +371,7 @@ final class ChronoLocalDateTimeImpl public long until(Temporal endExclusive, TemporalUnit unit) { Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoLocalDateTime end = (ChronoLocalDateTime) toLocalDate().getChronology().localDateTime(endExclusive); + ChronoLocalDateTime end = (ChronoLocalDateTime) getChronology().localDateTime(endExclusive); if (unit instanceof ChronoUnit) { if (unit.isTimeBased()) { long amount = end.getLong(EPOCH_DAY) - date.getLong(EPOCH_DAY); diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java index abe84799716..033ab997fdd 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java @@ -246,6 +246,18 @@ public interface ChronoZonedDateTime */ ChronoLocalDateTime toLocalDateTime(); + /** + * Gets the chronology of this date-time. + *

+ * The {@code Chronology} represents the calendar system in use. + * The era and other fields in {@link ChronoField} are defined by the chronology. + * + * @return the chronology, not null + */ + default Chronology getChronology() { + return toLocalDate().getChronology(); + } + /** * Gets the zone offset, such as '+01:00'. *

@@ -398,7 +410,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime with(TemporalAdjuster adjuster) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -416,7 +428,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime plus(TemporalAmount amount) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -434,7 +446,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime minus(TemporalAmount amount) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -444,7 +456,7 @@ public interface ChronoZonedDateTime */ @Override default ChronoZonedDateTime minus(long amountToSubtract, TemporalUnit unit) { - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- @@ -476,7 +488,7 @@ public interface ChronoZonedDateTime } else if (query == TemporalQuery.localTime()) { return (R) toLocalTime(); } else if (query == TemporalQuery.chronology()) { - return (R) toLocalDate().getChronology(); + return (R) getChronology(); } else if (query == TemporalQuery.precision()) { return (R) NANOS; } @@ -563,7 +575,7 @@ public interface ChronoZonedDateTime if (cmp == 0) { cmp = getZone().getId().compareTo(other.getZone().getId()); if (cmp == 0) { - cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology()); + cmp = getChronology().compareTo(other.getChronology()); } } } diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java index 1fe8ccf0192..5222db367f2 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java @@ -185,7 +185,7 @@ final class ChronoZonedDateTimeImpl */ @SuppressWarnings("unchecked") private ChronoZonedDateTimeImpl create(Instant instant, ZoneId zone) { - return (ChronoZonedDateTimeImpl)ofInstant(toLocalDate().getChronology(), instant, zone); + return (ChronoZonedDateTimeImpl)ofInstant(getChronology(), instant, zone); } /** @@ -200,9 +200,9 @@ final class ChronoZonedDateTimeImpl static ChronoZonedDateTimeImpl ensureValid(Chronology chrono, Temporal temporal) { @SuppressWarnings("unchecked") ChronoZonedDateTimeImpl other = (ChronoZonedDateTimeImpl) temporal; - if (chrono.equals(other.toLocalDate().getChronology()) == false) { + if (chrono.equals(other.getChronology()) == false) { throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() - + ", actual: " + other.toLocalDate().getChronology().getId()); + + ", actual: " + other.getChronology().getId()); } return other; } @@ -293,7 +293,7 @@ final class ChronoZonedDateTimeImpl } return ofBest(dateTime.with(field, newValue), zone, offset); } - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), field.adjustInto(this, newValue)); + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); } //----------------------------------------------------------------------- @@ -302,7 +302,7 @@ final class ChronoZonedDateTimeImpl if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit)); } - return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), unit.addTo(this, amountToAdd)); /// TODO: Generics replacement Risk! + return ChronoZonedDateTimeImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); /// TODO: Generics replacement Risk! } //----------------------------------------------------------------------- @@ -310,7 +310,7 @@ final class ChronoZonedDateTimeImpl public long until(Temporal endExclusive, TemporalUnit unit) { Objects.requireNonNull(endExclusive, "endExclusive"); @SuppressWarnings("unchecked") - ChronoZonedDateTime end = (ChronoZonedDateTime) toLocalDate().getChronology().zonedDateTime(endExclusive); + ChronoZonedDateTime end = (ChronoZonedDateTime) getChronology().zonedDateTime(endExclusive); if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); return dateTime.until(end.toLocalDateTime(), unit); diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java index 7ca03e2e3fb..51b68bb7c1f 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java @@ -343,6 +343,13 @@ public class TCKChronoLocalDateTime { ChronoLocalDateTime.from(null); } + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_getChronology(Chronology chrono) { + ChronoLocalDateTime test = chrono.localDateTime(LocalDateTime.of(2010, 6, 30, 11, 30)); + assertEquals(test.getChronology(), chrono); + } + //----------------------------------------------------------------------- /** * FixedAdjusted returns a fixed Temporal in all adjustments. diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java index b2b7fc2cc6c..0cabccab036 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java @@ -344,6 +344,13 @@ public class TCKChronoZonedDateTime { ChronoZonedDateTime.from(null); } + //----------------------------------------------------------------------- + @Test(dataProvider="calendars") + public void test_getChronology(Chronology chrono) { + ChronoZonedDateTime test = chrono.zonedDateTime(ZonedDateTime.of(2010, 6, 30, 11, 30, 0, 0, ZoneOffset.UTC)); + assertEquals(test.getChronology(), chrono); + } + //----------------------------------------------------------------------- /** * FixedAdjusted returns a fixed Temporal in all adjustments. From ea9e3930af2c8ff70178064b53b9455424ffe55b Mon Sep 17 00:00:00 2001 From: Stephen Colebourne Date: Sat, 14 Sep 2013 22:54:38 +0100 Subject: [PATCH 102/293] 8024834: Better return type for TemporalField resolve Allow resolve method to return more than just ChronoLocalDate Reviewed-by: sherman --- .../classes/java/time/format/Parsed.java | 40 +++- .../java/time/temporal/TemporalField.java | 11 +- .../time/format/TCKDateTimeParseResolver.java | 219 ++++++++++++++++++ 3 files changed, 260 insertions(+), 10 deletions(-) diff --git a/jdk/src/share/classes/java/time/format/Parsed.java b/jdk/src/share/classes/java/time/format/Parsed.java index 42223d6c1d9..7413467826d 100644 --- a/jdk/src/share/classes/java/time/format/Parsed.java +++ b/jdk/src/share/classes/java/time/format/Parsed.java @@ -83,6 +83,8 @@ import java.time.LocalTime; import java.time.Period; import java.time.ZoneId; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; @@ -260,11 +262,34 @@ final class Parsed implements TemporalAccessor { while (changedCount < 50) { for (Map.Entry entry : fieldValues.entrySet()) { TemporalField targetField = entry.getKey(); - ChronoLocalDate resolvedDate = targetField.resolve(fieldValues, chrono, zone, resolverStyle); - if (resolvedDate != null) { - updateCheckConflict(resolvedDate); - changedCount++; - continue outer; // have to restart to avoid concurrent modification + TemporalAccessor resolvedObject = targetField.resolve(fieldValues, chrono, zone, resolverStyle); + if (resolvedObject != null) { + if (resolvedObject instanceof ChronoZonedDateTime) { + ChronoZonedDateTime czdt = (ChronoZonedDateTime) resolvedObject; + if (zone.equals(czdt.getZone()) == false) { + throw new DateTimeException("ChronoZonedDateTime must use the effective parsed zone: " + zone); + } + resolvedObject = czdt.toLocalDateTime(); + } + if (resolvedObject instanceof ChronoLocalDateTime) { + ChronoLocalDateTime cldt = (ChronoLocalDateTime) resolvedObject; + updateCheckConflict(cldt.toLocalTime(), Period.ZERO); + updateCheckConflict(cldt.toLocalDate()); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } + if (resolvedObject instanceof ChronoLocalDate) { + updateCheckConflict((ChronoLocalDate) resolvedObject); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } + if (resolvedObject instanceof LocalTime) { + updateCheckConflict((LocalTime) resolvedObject, Period.ZERO); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } + throw new DateTimeException("Method resolveFields() can only return ChronoZonedDateTime," + + "ChronoLocalDateTime, ChronoLocalDate or LocalTime"); } else if (fieldValues.containsKey(targetField) == false) { changedCount++; continue outer; // have to restart to avoid concurrent modification @@ -302,7 +327,10 @@ final class Parsed implements TemporalAccessor { if (cld != null && date.equals(cld) == false) { throw new DateTimeException("Conflict found: Fields resolved to two different dates: " + date + " " + cld); } - } else { + } else if (cld != null) { + if (chrono.equals(cld.getChronology()) == false) { + throw new DateTimeException("ChronoLocalDate must use the effective parsed chronology: " + chrono); + } date = cld; } } diff --git a/jdk/src/share/classes/java/time/temporal/TemporalField.java b/jdk/src/share/classes/java/time/temporal/TemporalField.java index e4d6b407783..e757734510c 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalField.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalField.java @@ -63,7 +63,6 @@ package java.time.temporal; import java.time.DateTimeException; import java.time.ZoneId; -import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.format.ResolverStyle; import java.util.Locale; @@ -350,6 +349,10 @@ public interface TemporalField { * be acceptable for the date fields to be resolved into other {@code ChronoField} * instances that can produce a date, such as {@code EPOCH_DAY}. *

+ * Not all {@code TemporalAccessor} implementations are accepted as return values. + * Implementations must accept {@code ChronoLocalDate}, {@code ChronoLocalDateTime}, + * {@code ChronoZonedDateTime} and {@code LocalTime}. + *

* The zone is not normally required for resolution, but is provided for completeness. *

* The default implementation must return null. @@ -358,13 +361,13 @@ public interface TemporalField { * @param chronology the effective chronology, not null * @param zone the effective zone, not null * @param resolverStyle the requested type of resolve, not null - * @return the resolved date; null if resolving only changed the map, - * or no resolve occurred + * @return the resolved temporal object; null if resolving only + * changed the map, or no resolve occurred * @throws ArithmeticException if numeric overflow occurs * @throws DateTimeException if resolving results in an error. This must not be thrown * by querying a field on the temporal without first checking if it is supported */ - default ChronoLocalDate resolve( + default TemporalAccessor resolve( Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { return null; diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java index 9b249f19224..4ef01317b2e 100644 --- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java +++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java @@ -90,20 +90,33 @@ import static java.time.temporal.ChronoField.SECOND_OF_DAY; import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.NANOS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Period; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.chrono.Chronology; +import java.time.chrono.ThaiBuddhistChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; import java.time.format.ResolverStyle; +import java.time.temporal.ChronoUnit; import java.time.temporal.IsoFields; +import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; +import java.time.temporal.ValueRange; +import java.util.Map; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -872,4 +885,210 @@ public class TCKDateTimeParseResolver { } } + //----------------------------------------------------------------------- + @Test + public void test_fieldResolvesToLocalTime() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + return LocalTime.MIDNIGHT.plusNanos(fieldValues.remove(this)); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter(); + TemporalAccessor accessor = f.parse("1234567890"); + assertEquals(accessor.query(TemporalQuery.localDate()), null); + assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.of(0, 0, 1, 234_567_890)); + } + + @Test + public void test_fieldResolvesToChronoLocalDateTime() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + fieldValues.remove(this); + return LocalDateTime.of(2010, 6, 30, 12, 30); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter(); + TemporalAccessor accessor = f.parse("1234567890"); + assertEquals(accessor.query(TemporalQuery.localDate()), LocalDate.of(2010, 6, 30)); + assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.of(12, 30)); + } + + @Test(expectedExceptions = DateTimeParseException.class) + public void test_fieldResolvesWrongChrono() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + return ThaiBuddhistChronology.INSTANCE.dateNow(); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter(); + f.parse("1234567890"); + } + + @Test(expectedExceptions = DateTimeParseException.class) + public void test_fieldResolvesWrongZone() { + TemporalField field = new TemporalField() { + @Override + public TemporalUnit getBaseUnit() { + throw new UnsupportedOperationException(); + } + @Override + public TemporalUnit getRangeUnit() { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange range() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isDateBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isTimeBased() { + throw new UnsupportedOperationException(); + } + @Override + public boolean isSupportedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public long getFrom(TemporalAccessor temporal) { + throw new UnsupportedOperationException(); + } + @Override + public R adjustInto(R temporal, long newValue) { + throw new UnsupportedOperationException(); + } + @Override + public TemporalAccessor resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { + return ZonedDateTime.of(2010, 6, 30, 12, 30, 0, 0, ZoneId.of("Europe/Paris")); + } + }; + DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter().withZone(ZoneId.of("Europe/London")); + f.parse("1234567890"); + } + } From 3184042cd14fb6a080bb75cb31f683200855393c Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 16 Sep 2013 10:20:45 +0200 Subject: [PATCH 103/293] 8024396: VM crashing with assert(!UseLargePages || UseParallelOldGC || use_large_pages) failed: Wrong alignment to use large pages Loosen wrong assert for UseParallelOldGC to UseParallelGC Reviewed-by: stefank, brutisso --- hotspot/src/share/vm/memory/universe.cpp | 2 +- .../TestAlignmentToUseLargePages.java | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index 54d6851d16d..a9be3486396 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -881,7 +881,7 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size()); assert(!UseLargePages - || UseParallelOldGC + || UseParallelGC || use_large_pages, "Wrong alignment to use large pages"); char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop); diff --git a/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java new file mode 100644 index 00000000000..125c1aabd51 --- /dev/null +++ b/hotspot/test/gc/arguments/TestAlignmentToUseLargePages.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test TestAlignmentToUseLargePages + * @summary All parallel GC variants may use large pages without the requirement that the + * heap alignment is large page aligned. Other collectors also need to start up with odd sized heaps. + * @bug 8024396 + * @key gc + * @key regression + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:-UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseSerialGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseConcMarkSweepGC -XX:-UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:+UseLargePages TestAlignmentToUseLargePages + * @run main/othervm -Xms7M -Xmx9M -XX:+UseG1GC -XX:-UseLargePages TestAlignmentToUseLargePages + */ + +public class TestAlignmentToUseLargePages { + public static void main(String args[]) throws Exception { + // nothing to do + } +} From 139c3e6621b2105f1d69c5032e5a10b48967dc8a Mon Sep 17 00:00:00 2001 From: David Holmes Date: Mon, 16 Sep 2013 07:38:13 -0400 Subject: [PATCH 104/293] 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock Associate CLOCK_MONOTONIC with the pthread_cond_t objects used for relative timed waits Reviewed-by: dcubed, shade --- hotspot/src/os/linux/vm/os_linux.cpp | 148 +++++++++++++++++++-------- hotspot/src/os/linux/vm/os_linux.hpp | 25 ++++- 2 files changed, 128 insertions(+), 45 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 70837a850d8..de5a7686989 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -131,6 +131,7 @@ bool os::Linux::_is_NPTL = false; bool os::Linux::_supports_fast_thread_cpu_time = false; const char * os::Linux::_glibc_version = NULL; const char * os::Linux::_libpthread_version = NULL; +pthread_condattr_t os::Linux::_condattr[1]; static jlong initial_time_count=0; @@ -1399,12 +1400,15 @@ void os::Linux::clock_init() { clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) { // yes, monotonic clock is supported _clock_gettime = clock_gettime_func; + return; } else { // close librt if there is no monotonic clock dlclose(handle); } } } + warning("No monotonic clock was available - timed services may " \ + "be adversely affected if the time-of-day clock changes"); } #ifndef SYS_clock_getres @@ -4709,6 +4713,26 @@ void os::init(void) { Linux::clock_init(); initial_time_count = os::elapsed_counter(); + + // pthread_condattr initialization for monotonic clock + int status; + pthread_condattr_t* _condattr = os::Linux::condAttr(); + if ((status = pthread_condattr_init(_condattr)) != 0) { + fatal(err_msg("pthread_condattr_init: %s", strerror(status))); + } + // Only set the clock if CLOCK_MONOTONIC is available + if (Linux::supports_monotonic_clock()) { + if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) { + if (status == EINVAL) { + warning("Unable to use monotonic clock with relative timed-waits" \ + " - changes to the time-of-day clock may have adverse affects"); + } else { + fatal(err_msg("pthread_condattr_setclock: %s", strerror(status))); + } + } + } + // else it defaults to CLOCK_REALTIME + pthread_mutex_init(&dl_mutex, NULL); // If the pagesize of the VM is greater than 8K determine the appropriate @@ -5519,21 +5543,36 @@ void os::pause() { static struct timespec* compute_abstime(timespec* abstime, jlong millis) { if (millis < 0) millis = 0; - struct timeval now; - int status = gettimeofday(&now, NULL); - assert(status == 0, "gettimeofday"); + jlong seconds = millis / 1000; millis %= 1000; if (seconds > 50000000) { // see man cond_timedwait(3T) seconds = 50000000; } - abstime->tv_sec = now.tv_sec + seconds; - long usec = now.tv_usec + millis * 1000; - if (usec >= 1000000) { - abstime->tv_sec += 1; - usec -= 1000000; + + if (os::Linux::supports_monotonic_clock()) { + struct timespec now; + int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); + assert_status(status == 0, status, "clock_gettime"); + abstime->tv_sec = now.tv_sec + seconds; + long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC; + if (nanos >= NANOSECS_PER_SEC) { + abstime->tv_sec += 1; + nanos -= NANOSECS_PER_SEC; + } + abstime->tv_nsec = nanos; + } else { + struct timeval now; + int status = gettimeofday(&now, NULL); + assert(status == 0, "gettimeofday"); + abstime->tv_sec = now.tv_sec + seconds; + long usec = now.tv_usec + millis * 1000; + if (usec >= 1000000) { + abstime->tv_sec += 1; + usec -= 1000000; + } + abstime->tv_nsec = usec * 1000; } - abstime->tv_nsec = usec * 1000; return abstime; } @@ -5625,7 +5664,7 @@ int os::PlatformEvent::park(jlong millis) { status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst); if (status != 0 && WorkAroundNPTLTimedWaitHang) { pthread_cond_destroy (_cond); - pthread_cond_init (_cond, NULL) ; + pthread_cond_init (_cond, os::Linux::condAttr()) ; } assert_status(status == 0 || status == EINTR || status == ETIME || status == ETIMEDOUT, @@ -5726,32 +5765,50 @@ void os::PlatformEvent::unpark() { static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { assert (time > 0, "convertTime"); + time_t max_secs = 0; - struct timeval now; - int status = gettimeofday(&now, NULL); - assert(status == 0, "gettimeofday"); + if (!os::Linux::supports_monotonic_clock() || isAbsolute) { + struct timeval now; + int status = gettimeofday(&now, NULL); + assert(status == 0, "gettimeofday"); - time_t max_secs = now.tv_sec + MAX_SECS; + max_secs = now.tv_sec + MAX_SECS; - if (isAbsolute) { - jlong secs = time / 1000; - if (secs > max_secs) { - absTime->tv_sec = max_secs; + if (isAbsolute) { + jlong secs = time / 1000; + if (secs > max_secs) { + absTime->tv_sec = max_secs; + } else { + absTime->tv_sec = secs; + } + absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; + } else { + jlong secs = time / NANOSECS_PER_SEC; + if (secs >= MAX_SECS) { + absTime->tv_sec = max_secs; + absTime->tv_nsec = 0; + } else { + absTime->tv_sec = now.tv_sec + secs; + absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; + if (absTime->tv_nsec >= NANOSECS_PER_SEC) { + absTime->tv_nsec -= NANOSECS_PER_SEC; + ++absTime->tv_sec; // note: this must be <= max_secs + } + } } - else { - absTime->tv_sec = secs; - } - absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; - } - else { + } else { + // must be relative using monotonic clock + struct timespec now; + int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); + assert_status(status == 0, status, "clock_gettime"); + max_secs = now.tv_sec + MAX_SECS; jlong secs = time / NANOSECS_PER_SEC; if (secs >= MAX_SECS) { absTime->tv_sec = max_secs; absTime->tv_nsec = 0; - } - else { + } else { absTime->tv_sec = now.tv_sec + secs; - absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; + absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec; if (absTime->tv_nsec >= NANOSECS_PER_SEC) { absTime->tv_nsec -= NANOSECS_PER_SEC; ++absTime->tv_sec; // note: this must be <= max_secs @@ -5831,15 +5888,19 @@ void Parker::park(bool isAbsolute, jlong time) { jt->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() + assert(_cur_index == -1, "invariant"); if (time == 0) { - status = pthread_cond_wait (_cond, _mutex) ; + _cur_index = REL_INDEX; // arbitrary choice when not timed + status = pthread_cond_wait (&_cond[_cur_index], _mutex) ; } else { - status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ; + _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX; + status = os::Linux::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ; if (status != 0 && WorkAroundNPTLTimedWaitHang) { - pthread_cond_destroy (_cond) ; - pthread_cond_init (_cond, NULL); + pthread_cond_destroy (&_cond[_cur_index]) ; + pthread_cond_init (&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr()); } } + _cur_index = -1; assert_status(status == 0 || status == EINTR || status == ETIME || status == ETIMEDOUT, status, "cond_timedwait"); @@ -5868,17 +5929,24 @@ void Parker::unpark() { s = _counter; _counter = 1; if (s < 1) { - if (WorkAroundNPTLTimedWaitHang) { - status = pthread_cond_signal (_cond) ; - assert (status == 0, "invariant") ; + // thread might be parked + if (_cur_index != -1) { + // thread is definitely parked + if (WorkAroundNPTLTimedWaitHang) { + status = pthread_cond_signal (&_cond[_cur_index]); + assert (status == 0, "invariant"); status = pthread_mutex_unlock(_mutex); - assert (status == 0, "invariant") ; - } else { + assert (status == 0, "invariant"); + } else { status = pthread_mutex_unlock(_mutex); - assert (status == 0, "invariant") ; - status = pthread_cond_signal (_cond) ; - assert (status == 0, "invariant") ; - } + assert (status == 0, "invariant"); + status = pthread_cond_signal (&_cond[_cur_index]); + assert (status == 0, "invariant"); + } + } else { + pthread_mutex_unlock(_mutex); + assert (status == 0, "invariant") ; + } } else { pthread_mutex_unlock(_mutex); assert (status == 0, "invariant") ; diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp index c824e8ad3fe..5eed54f8c1e 100644 --- a/hotspot/src/os/linux/vm/os_linux.hpp +++ b/hotspot/src/os/linux/vm/os_linux.hpp @@ -221,6 +221,13 @@ class Linux { static jlong fast_thread_cpu_time(clockid_t clockid); + // pthread_cond clock suppport + private: + static pthread_condattr_t _condattr[1]; + + public: + static pthread_condattr_t* condAttr() { return _condattr; } + // Stack repair handling // none present @@ -295,7 +302,7 @@ class PlatformEvent : public CHeapObj { public: PlatformEvent() { int status; - status = pthread_cond_init (_cond, NULL); + status = pthread_cond_init (_cond, os::Linux::condAttr()); assert_status(status == 0, status, "cond_init"); status = pthread_mutex_init (_mutex, NULL); assert_status(status == 0, status, "mutex_init"); @@ -310,14 +317,19 @@ class PlatformEvent : public CHeapObj { void park () ; void unpark () ; int TryPark () ; - int park (jlong millis) ; + int park (jlong millis) ; // relative timed-wait only void SetAssociation (Thread * a) { _Assoc = a ; } } ; class PlatformParker : public CHeapObj { protected: + enum { + REL_INDEX = 0, + ABS_INDEX = 1 + }; + int _cur_index; // which cond is in use: -1, 0, 1 pthread_mutex_t _mutex [1] ; - pthread_cond_t _cond [1] ; + pthread_cond_t _cond [2] ; // one for relative times and one for abs. public: // TODO-FIXME: make dtor private ~PlatformParker() { guarantee (0, "invariant") ; } @@ -325,10 +337,13 @@ class PlatformParker : public CHeapObj { public: PlatformParker() { int status; - status = pthread_cond_init (_cond, NULL); - assert_status(status == 0, status, "cond_init"); + status = pthread_cond_init (&_cond[REL_INDEX], os::Linux::condAttr()); + assert_status(status == 0, status, "cond_init rel"); + status = pthread_cond_init (&_cond[ABS_INDEX], NULL); + assert_status(status == 0, status, "cond_init abs"); status = pthread_mutex_init (_mutex, NULL); assert_status(status == 0, status, "mutex_init"); + _cur_index = -1; // mark as unused } }; From dffefd9ecfd231283a25f48e3a45c92fdeac11ba Mon Sep 17 00:00:00 2001 From: Gerald Thornbrugh Date: Mon, 16 Sep 2013 12:43:34 -0700 Subject: [PATCH 105/293] 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian" Cleanup and document how various Linux release info files are used by print_distro_info(). Reviewed-by: dcubed, dsamersoff, coleenp, iklam, omajid --- hotspot/src/os/linux/vm/os_linux.cpp | 58 ++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index de5a7686989..ec6adc5d3ea 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -2169,23 +2169,49 @@ void os::print_os_info(outputStream* st) { } // Try to identify popular distros. -// Most Linux distributions have /etc/XXX-release file, which contains -// the OS version string. Some have more than one /etc/XXX-release file -// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.), -// so the order is important. +// Most Linux distributions have a /etc/XXX-release file, which contains +// the OS version string. Newer Linux distributions have a /etc/lsb-release +// file that also contains the OS version string. Some have more than one +// /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and +// /etc/redhat-release.), so the order is important. +// Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have +// their own specific XXX-release file as well as a redhat-release file. +// Because of this the XXX-release file needs to be searched for before the +// redhat-release file. +// Since Red Hat has a lsb-release file that is not very descriptive the +// search for redhat-release needs to be before lsb-release. +// Since the lsb-release file is the new standard it needs to be searched +// before the older style release files. +// Searching system-release (Red Hat) and os-release (other Linuxes) are a +// next to last resort. The os-release file is a new standard that contains +// distribution information and the system-release file seems to be an old +// standard that has been replaced by the lsb-release and os-release files. +// Searching for the debian_version file is the last resort. It contains +// an informative string like "6.0.6" or "wheezy/sid". Because of this +// "Debian " is printed before the contents of the debian_version file. void os::Linux::print_distro_info(outputStream* st) { - if (!_print_ascii_file("/etc/mandrake-release", st) && - !_print_ascii_file("/etc/sun-release", st) && - !_print_ascii_file("/etc/redhat-release", st) && - !_print_ascii_file("/etc/SuSE-release", st) && - !_print_ascii_file("/etc/turbolinux-release", st) && - !_print_ascii_file("/etc/gentoo-release", st) && - !_print_ascii_file("/etc/debian_version", st) && - !_print_ascii_file("/etc/ltib-release", st) && - !_print_ascii_file("/etc/angstrom-version", st)) { - st->print("Linux"); - } - st->cr(); + if (!_print_ascii_file("/etc/oracle-release", st) && + !_print_ascii_file("/etc/mandriva-release", st) && + !_print_ascii_file("/etc/mandrake-release", st) && + !_print_ascii_file("/etc/sun-release", st) && + !_print_ascii_file("/etc/redhat-release", st) && + !_print_ascii_file("/etc/lsb-release", st) && + !_print_ascii_file("/etc/SuSE-release", st) && + !_print_ascii_file("/etc/turbolinux-release", st) && + !_print_ascii_file("/etc/gentoo-release", st) && + !_print_ascii_file("/etc/ltib-release", st) && + !_print_ascii_file("/etc/angstrom-version", st) && + !_print_ascii_file("/etc/system-release", st) && + !_print_ascii_file("/etc/os-release", st)) { + + if (file_exists("/etc/debian_version")) { + st->print("Debian "); + _print_ascii_file("/etc/debian_version", st); + } else { + st->print("Linux"); + } + } + st->cr(); } void os::Linux::print_libversion_info(outputStream* st) { From 9505ddf1e2ac35d74071f4425bdeba180c11a46a Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Mon, 16 Sep 2013 17:57:56 -0400 Subject: [PATCH 106/293] 8024647: Default method resolution with private superclass method Reviewed-by: kamg, minqi --- .../src/share/vm/classfile/defaultMethods.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index b59fe66e062..99a45b55b6d 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -450,6 +450,10 @@ class MethodFamily : public ResourceObj { streamIndentor si(str, indent * 2); str->indent().print("Selected method: "); print_method(str, _selected_target); + Klass* method_holder = _selected_target->method_holder(); + if (!method_holder->is_interface()) { + tty->print(" : in superclass"); + } str->print_cr(""); } @@ -1141,19 +1145,23 @@ static void create_overpasses( #endif // ndef PRODUCT if (method->has_target()) { Method* selected = method->get_selected_target(); - max_stack = assemble_redirect( + if (selected->method_holder()->is_interface()) { + max_stack = assemble_redirect( &bpool, &buffer, slot->signature(), selected, CHECK); + } } else if (method->throws_exception()) { max_stack = assemble_abstract_method_error( &bpool, &buffer, method->get_exception_message(), CHECK); } - AccessFlags flags = accessFlags_from( + if (max_stack != 0) { + AccessFlags flags = accessFlags_from( JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); - Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), + Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), flags, max_stack, slot->size_of_parameters(), ConstMethod::OVERPASS, CHECK); - if (m != NULL) { - overpasses.push(m); + if (m != NULL) { + overpasses.push(m); + } } } } From 0cd7bc2cde5d0042634e25b269501235707fea7c Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Mon, 16 Sep 2013 15:35:04 -0700 Subject: [PATCH 107/293] 7164841: Improvements to the GC log file rotation Made changes to easily identify current log file in rotation. Parameterize the input with %t for time replacement in file name. Reviewed-by: ccheung, tschatzl, tamao, zgu --- hotspot/src/share/vm/prims/jni.cpp | 2 + hotspot/src/share/vm/runtime/arguments.cpp | 54 ++- hotspot/src/share/vm/utilities/ostream.cpp | 385 ++++++++++++++++----- hotspot/src/share/vm/utilities/ostream.hpp | 18 +- 4 files changed, 357 insertions(+), 102 deletions(-) diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index ea44e2c6679..4fba6577d82 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5037,6 +5037,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) { #include "gc_implementation/g1/heapRegionRemSet.hpp" #endif #include "utilities/quickSort.hpp" +#include "utilities/ostream.hpp" #if INCLUDE_VM_STRUCTS #include "runtime/vmStructs.hpp" #endif @@ -5060,6 +5061,7 @@ void execute_internal_vm_tests() { run_unit_test(CollectedHeap::test_is_in()); run_unit_test(QuickSort::test_quick_sort()); run_unit_test(AltHashing::test_alt_hash()); + run_unit_test(test_loggc_filename()); #if INCLUDE_VM_STRUCTS run_unit_test(VMStructs::test()); #endif diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index d8a6f90eeef..ef4da6da740 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1839,7 +1839,7 @@ void check_gclog_consistency() { (NumberOfGCLogFiles == 0) || (GCLogFileSize == 0)) { jio_fprintf(defaultStream::output_stream(), - "To enable GC log rotation, use -Xloggc: -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=\n" + "To enable GC log rotation, use -Xloggc: -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=[k|K|m|M|g|G]\n" "where num_of_file > 0 and num_of_size > 0\n" "GC log rotation is turned off\n"); UseGCLogFileRotation = false; @@ -1853,6 +1853,51 @@ void check_gclog_consistency() { } } +// This function is called for -Xloggc:, it can be used +// to check if a given file name(or string) conforms to the following +// specification: +// A valid string only contains "[A-Z][a-z][0-9].-_%[p|t]" +// %p and %t only allowed once. We only limit usage of filename not path +bool is_filename_valid(const char *file_name) { + const char* p = file_name; + char file_sep = os::file_separator()[0]; + const char* cp; + // skip prefix path + for (cp = file_name; *cp != '\0'; cp++) { + if (*cp == '/' || *cp == file_sep) { + p = cp + 1; + } + } + + int count_p = 0; + int count_t = 0; + while (*p != '\0') { + if ((*p >= '0' && *p <= '9') || + (*p >= 'A' && *p <= 'Z') || + (*p >= 'a' && *p <= 'z') || + *p == '-' || + *p == '_' || + *p == '.') { + p++; + continue; + } + if (*p == '%') { + if(*(p + 1) == 'p') { + p += 2; + count_p ++; + continue; + } + if (*(p + 1) == 't') { + p += 2; + count_t ++; + continue; + } + } + return false; + } + return count_p < 2 && count_t < 2; +} + // Check consistency of GC selection bool Arguments::check_gc_consistency() { check_gclog_consistency(); @@ -2806,6 +2851,13 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, // ostream_init_log(), when called will use this filename // to initialize a fileStream. _gc_log_filename = strdup(tail); + if (!is_filename_valid(_gc_log_filename)) { + jio_fprintf(defaultStream::output_stream(), + "Invalid file name for use with -Xloggc: Filename can only contain the " + "characters [A-Z][a-z][0-9]-_.%%[p|t] but it has been %s\n" + "Note %%p or %%t can only be used once\n", _gc_log_filename); + return JNI_EINVAL; + } FLAG_SET_CMDLINE(bool, PrintGC, true); FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true); diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index 2f04fa0e437..0ad9b9eb0dd 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -342,7 +342,7 @@ void stringStream::write(const char* s, size_t len) { } char* stringStream::as_string() { - char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1); + char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1); strncpy(copy, buffer, buffer_pos); copy[buffer_pos] = 0; // terminating null return copy; @@ -355,14 +355,190 @@ outputStream* tty; outputStream* gclog_or_tty; extern Mutex* tty_lock; +#define EXTRACHARLEN 32 +#define CURRENTAPPX ".current" +#define FILENAMEBUFLEN 1024 +// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS +char* get_datetime_string(char *buf, size_t len) { + os::local_time_string(buf, len); + int i = (int)strlen(buf); + while (i-- >= 0) { + if (buf[i] == ' ') buf[i] = '_'; + else if (buf[i] == ':') buf[i] = '-'; + } + return buf; +} + +static const char* make_log_name_internal(const char* log_name, const char* force_directory, + int pid, const char* tms) { + const char* basename = log_name; + char file_sep = os::file_separator()[0]; + const char* cp; + char pid_text[32]; + + for (cp = log_name; *cp != '\0'; cp++) { + if (*cp == '/' || *cp == file_sep) { + basename = cp + 1; + } + } + const char* nametail = log_name; + // Compute buffer length + size_t buffer_length; + if (force_directory != NULL) { + buffer_length = strlen(force_directory) + strlen(os::file_separator()) + + strlen(basename) + 1; + } else { + buffer_length = strlen(log_name) + 1; + } + + // const char* star = strchr(basename, '*'); + const char* pts = strstr(basename, "%p"); + int pid_pos = (pts == NULL) ? -1 : (pts - nametail); + + if (pid_pos >= 0) { + jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid); + buffer_length += strlen(pid_text); + } + + pts = strstr(basename, "%t"); + int tms_pos = (pts == NULL) ? -1 : (pts - nametail); + if (tms_pos >= 0) { + buffer_length += strlen(tms); + } + + // Create big enough buffer. + char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); + + strcpy(buf, ""); + if (force_directory != NULL) { + strcat(buf, force_directory); + strcat(buf, os::file_separator()); + nametail = basename; // completely skip directory prefix + } + + // who is first, %p or %t? + int first = -1, second = -1; + const char *p1st = NULL; + const char *p2nd = NULL; + + if (pid_pos >= 0 && tms_pos >= 0) { + // contains both %p and %t + if (pid_pos < tms_pos) { + // case foo%pbar%tmonkey.log + first = pid_pos; + p1st = pid_text; + second = tms_pos; + p2nd = tms; + } else { + // case foo%tbar%pmonkey.log + first = tms_pos; + p1st = tms; + second = pid_pos; + p2nd = pid_text; + } + } else if (pid_pos >= 0) { + // contains %p only + first = pid_pos; + p1st = pid_text; + } else if (tms_pos >= 0) { + // contains %t only + first = tms_pos; + p1st = tms; + } + + int buf_pos = (int)strlen(buf); + const char* tail = nametail; + + if (first >= 0) { + tail = nametail + first + 2; + strncpy(&buf[buf_pos], nametail, first); + strcpy(&buf[buf_pos + first], p1st); + buf_pos = (int)strlen(buf); + if (second >= 0) { + strncpy(&buf[buf_pos], tail, second - first - 2); + strcpy(&buf[buf_pos + second - first - 2], p2nd); + tail = nametail + second + 2; + } + } + strcat(buf, tail); // append rest of name, or all of name + return buf; +} + +// log_name comes from -XX:LogFile=log_name or -Xloggc:log_name +// in log_name, %p => pipd1234 and +// %t => YYYY-MM-DD_HH-MM-SS +static const char* make_log_name(const char* log_name, const char* force_directory) { + char timestr[32]; + get_datetime_string(timestr, sizeof(timestr)); + return make_log_name_internal(log_name, force_directory, os::current_process_id(), + timestr); +} + +#ifndef PRODUCT +void test_loggc_filename() { + int pid; + char tms[32]; + char i_result[FILENAMEBUFLEN]; + const char* o_result; + get_datetime_string(tms, sizeof(tms)); + pid = os::current_process_id(); + + // test.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms); + o_result = make_log_name_internal("test.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // test-%t-%p.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid); + o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // test-%t%p.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid); + o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // %p%t.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms); + o_result = make_log_name_internal("%p%t.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // %p-test.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid); + o_result = make_log_name_internal("%p-test.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); + + // %t.log + jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms); + o_result = make_log_name_internal("%t.log", NULL, pid, tms); + assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)"); + FREE_C_HEAP_ARRAY(char, o_result, mtInternal); +} +#endif // PRODUCT + fileStream::fileStream(const char* file_name) { _file = fopen(file_name, "w"); - _need_close = true; + if (_file != NULL) { + _need_close = true; + } else { + warning("Cannot open file %s due to %s\n", file_name, strerror(errno)); + _need_close = false; + } } fileStream::fileStream(const char* file_name, const char* opentype) { _file = fopen(file_name, opentype); - _need_close = true; + if (_file != NULL) { + _need_close = true; + } else { + warning("Cannot open file %s due to %s\n", file_name, strerror(errno)); + _need_close = false; + } } void fileStream::write(const char* s, size_t len) { @@ -423,34 +599,51 @@ void fdStream::write(const char* s, size_t len) { update_position(s, len); } -rotatingFileStream::~rotatingFileStream() { +// dump vm version, os version, platform info, build id, +// memory usage and command line flags into header +void gcLogFileStream::dump_loggc_header() { + if (is_open()) { + print_cr(Abstract_VM_Version::internal_vm_info_string()); + os::print_memory_info(this); + print("CommandLine flags: "); + CommandLineFlags::printSetFlags(this); + } +} + +gcLogFileStream::~gcLogFileStream() { if (_file != NULL) { if (_need_close) fclose(_file); - _file = NULL; + _file = NULL; + } + if (_file_name != NULL) { FREE_C_HEAP_ARRAY(char, _file_name, mtInternal); _file_name = NULL; } } -rotatingFileStream::rotatingFileStream(const char* file_name) { +gcLogFileStream::gcLogFileStream(const char* file_name) { _cur_file_num = 0; _bytes_written = 0L; - _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); - jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); - _file = fopen(_file_name, "w"); - _need_close = true; + _file_name = make_log_name(file_name, NULL); + + // gc log file rotation + if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) { + char tempbuf[FILENAMEBUFLEN]; + jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num); + _file = fopen(tempbuf, "w"); + } else { + _file = fopen(_file_name, "w"); + } + if (_file != NULL) { + _need_close = true; + dump_loggc_header(); + } else { + warning("Cannot open file %s due to %s\n", _file_name, strerror(errno)); + _need_close = false; + } } -rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) { - _cur_file_num = 0; - _bytes_written = 0L; - _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); - jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); - _file = fopen(_file_name, opentype); - _need_close = true; -} - -void rotatingFileStream::write(const char* s, size_t len) { +void gcLogFileStream::write(const char* s, size_t len) { if (_file != NULL) { size_t count = fwrite(s, 1, len, _file); _bytes_written += count; @@ -466,7 +659,12 @@ void rotatingFileStream::write(const char* s, size_t len) { // write to gc log file at safepoint. If in future, changes made for mutator threads or // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log // must be synchronized. -void rotatingFileStream::rotate_log() { +void gcLogFileStream::rotate_log() { + char time_msg[FILENAMEBUFLEN]; + char time_str[EXTRACHARLEN]; + char current_file_name[FILENAMEBUFLEN]; + char renamed_file_name[FILENAMEBUFLEN]; + if (_bytes_written < (jlong)GCLogFileSize) { return; } @@ -481,27 +679,89 @@ void rotatingFileStream::rotate_log() { // rotate in same file rewind(); _bytes_written = 0L; + jio_snprintf(time_msg, sizeof(time_msg), "File %s rotated at %s\n", + _file_name, os::local_time_string((char *)time_str, sizeof(time_str))); + write(time_msg, strlen(time_msg)); + dump_loggc_header(); return; } - // rotate file in names file.0, file.1, file.2, ..., file. - // close current file, rotate to next file +#if defined(_WINDOWS) +#ifndef F_OK +#define F_OK 0 +#endif +#endif // _WINDOWS + + // rotate file in names extended_filename.0, extended_filename.1, ..., + // extended_filename.. Current rotation file name will + // have a form of extended_filename..current where i is the current rotation + // file number. After it reaches max file size, the file will be saved and renamed + // with .current removed from its tail. + size_t filename_len = strlen(_file_name); if (_file != NULL) { - _cur_file_num ++; - if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0; - jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d", - Arguments::gc_log_filename(), _cur_file_num); + jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d", + _file_name, _cur_file_num); + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, + _file_name, _cur_file_num); + jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the" + " maximum size. Saved as %s\n", + os::local_time_string((char *)time_str, sizeof(time_str)), + renamed_file_name); + write(time_msg, strlen(time_msg)); + fclose(_file); _file = NULL; + + bool can_rename = true; + if (access(current_file_name, F_OK) != 0) { + // current file does not exist? + warning("No source file exists, cannot rename\n"); + can_rename = false; + } + if (can_rename) { + if (access(renamed_file_name, F_OK) == 0) { + if (remove(renamed_file_name) != 0) { + warning("Could not delete existing file %s\n", renamed_file_name); + can_rename = false; + } + } else { + // file does not exist, ok to rename + } + } + if (can_rename && rename(current_file_name, renamed_file_name) != 0) { + warning("Could not rename %s to %s\n", _file_name, renamed_file_name); + } } - _file = fopen(_file_name, "w"); + + _cur_file_num++; + if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0; + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, + _file_name, _cur_file_num); + _file = fopen(current_file_name, "w"); + if (_file != NULL) { _bytes_written = 0L; _need_close = true; + // reuse current_file_name for time_msg + jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, + "%s.%d", _file_name, _cur_file_num); + jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n", + os::local_time_string((char *)time_str, sizeof(time_str)), + current_file_name); + write(time_msg, strlen(time_msg)); + dump_loggc_header(); + // remove the existing file + if (access(current_file_name, F_OK) == 0) { + if (remove(current_file_name) != 0) { + warning("Could not delete existing file %s\n", current_file_name); + } + } } else { - tty->print_cr("failed to open rotation log file %s due to %s\n", + warning("failed to open rotation log file %s due to %s\n" + "Turned off GC log file rotation\n", _file_name, strerror(errno)); _need_close = false; + FLAG_SET_DEFAULT(UseGCLogFileRotation, false); } } @@ -530,66 +790,6 @@ bool defaultStream::has_log_file() { return _log_file != NULL; } -static const char* make_log_name(const char* log_name, const char* force_directory) { - const char* basename = log_name; - char file_sep = os::file_separator()[0]; - const char* cp; - for (cp = log_name; *cp != '\0'; cp++) { - if (*cp == '/' || *cp == file_sep) { - basename = cp+1; - } - } - const char* nametail = log_name; - - // Compute buffer length - size_t buffer_length; - if (force_directory != NULL) { - buffer_length = strlen(force_directory) + strlen(os::file_separator()) + - strlen(basename) + 1; - } else { - buffer_length = strlen(log_name) + 1; - } - - const char* star = strchr(basename, '*'); - int star_pos = (star == NULL) ? -1 : (star - nametail); - int skip = 1; - if (star == NULL) { - // Try %p - star = strstr(basename, "%p"); - if (star != NULL) { - skip = 2; - } - } - star_pos = (star == NULL) ? -1 : (star - nametail); - - char pid[32]; - if (star_pos >= 0) { - jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id()); - buffer_length += strlen(pid); - } - - // Create big enough buffer. - char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); - - strcpy(buf, ""); - if (force_directory != NULL) { - strcat(buf, force_directory); - strcat(buf, os::file_separator()); - nametail = basename; // completely skip directory prefix - } - - if (star_pos >= 0) { - // convert foo*bar.log or foo%pbar.log to foo123bar.log - int buf_pos = (int) strlen(buf); - strncpy(&buf[buf_pos], nametail, star_pos); - strcpy(&buf[buf_pos + star_pos], pid); - nametail += star_pos + skip; // skip prefix and pid format - } - - strcat(buf, nametail); // append rest of name, or all of name - return buf; -} - void defaultStream::init_log() { // %%% Need a MutexLocker? const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; @@ -877,11 +1077,8 @@ void ostream_init_log() { gclog_or_tty = tty; // default to tty if (Arguments::gc_log_filename() != NULL) { - fileStream * gclog = UseGCLogFileRotation ? - new(ResourceObj::C_HEAP, mtInternal) - rotatingFileStream(Arguments::gc_log_filename()) : - new(ResourceObj::C_HEAP, mtInternal) - fileStream(Arguments::gc_log_filename()); + fileStream * gclog = new(ResourceObj::C_HEAP, mtInternal) + gcLogFileStream(Arguments::gc_log_filename()); if (gclog->is_open()) { // now we update the time stamp of the GC log to be synced up // with tty. diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp index 4d13847663e..9b1b1217b49 100644 --- a/hotspot/src/share/vm/utilities/ostream.hpp +++ b/hotspot/src/share/vm/utilities/ostream.hpp @@ -231,20 +231,24 @@ class fdStream : public outputStream { void flush() {}; }; -class rotatingFileStream : public fileStream { +class gcLogFileStream : public fileStream { protected: - char* _file_name; + const char* _file_name; jlong _bytes_written; - uintx _cur_file_num; // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1 + uintx _cur_file_num; // current logfile rotation number, from 0 to NumberOfGCLogFiles-1 public: - rotatingFileStream(const char* file_name); - rotatingFileStream(const char* file_name, const char* opentype); - rotatingFileStream(FILE* file) : fileStream(file) {} - ~rotatingFileStream(); + gcLogFileStream(const char* file_name); + ~gcLogFileStream(); virtual void write(const char* c, size_t len); virtual void rotate_log(); + void dump_loggc_header(); }; +#ifndef PRODUCT +// unit test for checking -Xloggc: parsing result +void test_loggc_filename(); +#endif + void ostream_init(); void ostream_init_log(); void ostream_exit(); From d11f6f252b8abc75927b658f44a32fab9a21f8fb Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Tue, 17 Sep 2013 08:39:20 +0200 Subject: [PATCH 108/293] 8024128: guarantee(codelet_size > 0 && (size_t)codelet_size > 2*K) failed: not enough space for interpreter generation Increase interpreter size for x86 template interpreter Reviewed-by: kvn, iveresov --- hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp index c828c90fba1..a632fbab313 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86.hpp @@ -34,9 +34,9 @@ // Run with +PrintInterpreter to get the VM to print out the size. // Max size with JVMTI #ifdef AMD64 - const static int InterpreterCodeSize = 200 * 1024; + const static int InterpreterCodeSize = 208 * 1024; #else - const static int InterpreterCodeSize = 168 * 1024; + const static int InterpreterCodeSize = 176 * 1024; #endif // AMD64 #endif // CPU_X86_VM_TEMPLATEINTERPRETER_X86_HPP From 7e77954221a2ef8c24f9686c047be45af1b511d8 Mon Sep 17 00:00:00 2001 From: Dan Horak Date: Tue, 17 Sep 2013 12:04:11 +0200 Subject: [PATCH 109/293] 8024914: Swapped usage of idx_t and bm_word_t types in bitMap.inline.hpp Incorrect usage of idx_t where bm_word_t is appropriate. Reviewed-by: tschatzl, brutisso --- .../src/share/vm/utilities/bitMap.inline.hpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/utilities/bitMap.inline.hpp b/hotspot/src/share/vm/utilities/bitMap.inline.hpp index 7bb244795fc..2171e849f8f 100644 --- a/hotspot/src/share/vm/utilities/bitMap.inline.hpp +++ b/hotspot/src/share/vm/utilities/bitMap.inline.hpp @@ -52,16 +52,16 @@ inline void BitMap::clear_bit(idx_t bit) { inline bool BitMap::par_set_bit(idx_t bit) { verify_index(bit); - volatile idx_t* const addr = word_addr(bit); - const idx_t mask = bit_mask(bit); - idx_t old_val = *addr; + volatile bm_word_t* const addr = word_addr(bit); + const bm_word_t mask = bit_mask(bit); + bm_word_t old_val = *addr; do { - const idx_t new_val = old_val | mask; + const bm_word_t new_val = old_val | mask; if (new_val == old_val) { return false; // Someone else beat us to it. } - const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val, + const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val, (volatile void*) addr, (void*) old_val); if (cur_val == old_val) { @@ -73,16 +73,16 @@ inline bool BitMap::par_set_bit(idx_t bit) { inline bool BitMap::par_clear_bit(idx_t bit) { verify_index(bit); - volatile idx_t* const addr = word_addr(bit); - const idx_t mask = ~bit_mask(bit); - idx_t old_val = *addr; + volatile bm_word_t* const addr = word_addr(bit); + const bm_word_t mask = ~bit_mask(bit); + bm_word_t old_val = *addr; do { - const idx_t new_val = old_val & mask; + const bm_word_t new_val = old_val & mask; if (new_val == old_val) { return false; // Someone else beat us to it. } - const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val, + const bm_word_t cur_val = (bm_word_t) Atomic::cmpxchg_ptr((void*) new_val, (volatile void*) addr, (void*) old_val); if (cur_val == old_val) { From e6c8a775ed5dc5105af44858bc22317665a8dc3b Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Tue, 17 Sep 2013 14:02:53 +0200 Subject: [PATCH 110/293] 8024884: Test name changed, test list not updated Updated the test list with the new test name. Reviewed-by: brutisso, ehelin --- hotspot/test/TEST.groups | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index bf5e3f088fb..a75ac20ce62 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -62,7 +62,7 @@ jdk = \ # needs_jdk = \ gc/TestG1ZeroPGCTJcmdThreadPrint.java \ - gc/metaspace/ClassMetaspaceSizeInJmapHeap.java \ + gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java \ gc/metaspace/TestMetaspacePerfCounters.java \ runtime/6819213/TestBootNativeLibraryPath.java \ runtime/6878713/Test6878713.sh \ From 0051ace82a86bb3cfa9cf825d4c7d025f5ac901e Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Tue, 17 Sep 2013 16:55:53 +0200 Subject: [PATCH 111/293] 8014905: [TESTBUG] Some hotspot tests should be updated to divide test jdk and compile jdk Change JDKToolFinder to look in compile.jdk if the executable cannot be found in test.jdk Reviewed-by: dholmes, hseigel --- hotspot/test/TEST.groups | 11 --- hotspot/test/gc/TestVerifyDuringStartup.java | 2 +- .../java/testlibrary/JDKToolFinder.java | 81 ++++++++++++++----- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index bf5e3f088fb..e6d88dc4b06 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -72,18 +72,7 @@ needs_jdk = \ runtime/7194254/Test7194254.java \ runtime/jsig/Test8017498.sh \ runtime/Metaspace/FragmentMetaspace.java \ - runtime/NMT/BaselineWithParameter.java \ - runtime/NMT/JcmdScale.java \ - runtime/NMT/JcmdWithNMTDisabled.java \ - runtime/NMT/MallocTestType.java \ runtime/NMT/ReleaseCommittedMemory.java \ - runtime/NMT/ShutdownTwice.java \ - runtime/NMT/SummaryAfterShutdown.java \ - runtime/NMT/SummarySanityCheck.java \ - runtime/NMT/ThreadedMallocTestType.java \ - runtime/NMT/ThreadedVirtualAllocTestType.java \ - runtime/NMT/VirtualAllocTestType.java \ - runtime/RedefineObject/TestRedefineObject.java \ serviceability/attach/AttachWithStalePidFile.java # JRE adds further tests to compact3 diff --git a/hotspot/test/gc/TestVerifyDuringStartup.java b/hotspot/test/gc/TestVerifyDuringStartup.java index 4ac32bf118e..f4ac347f80e 100644 --- a/hotspot/test/gc/TestVerifyDuringStartup.java +++ b/hotspot/test/gc/TestVerifyDuringStartup.java @@ -48,7 +48,7 @@ public class TestVerifyDuringStartup { "-XX:+VerifyDuringStartup", "-version"}); - System.out.print("Testing:\n" + JDKToolFinder.getCurrentJDKTool("java")); + System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java")); for (int i = 0; i < vmOpts.size(); i += 1) { System.out.print(" " + vmOpts.get(i)); } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java index a39abbd3626..6434135c108 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java @@ -23,7 +23,9 @@ package com.oracle.java.testlibrary; -import java.io.File; +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.nio.file.Paths; public final class JDKToolFinder { @@ -32,38 +34,73 @@ public final class JDKToolFinder { /** * Returns the full path to an executable in jdk/bin based on System - * property {@code compile.jdk} (set by jtreg test suite) + * property {@code test.jdk} or {@code compile.jdk} (both are set by the jtreg test suite) * * @return Full path to an executable in jdk/bin */ public static String getJDKTool(String tool) { - String binPath = System.getProperty("compile.jdk"); - if (binPath == null) { - throw new RuntimeException("System property 'compile.jdk' not set. " - + "This property is normally set by jtreg. " - + "When running test separately, set this property using " - + "'-Dcompile.jdk=/path/to/jdk'."); - } - binPath += File.separatorChar + "bin" + File.separatorChar + tool; - return binPath; + // First try to find the executable in test.jdk + try { + return getTool(tool, "test.jdk"); + } catch (FileNotFoundException e) { + + } + + // Now see if it's available in compile.jdk + try { + return getTool(tool, "compile.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException("Failed to find " + tool + + ", looked in test.jdk (" + System.getProperty("test.jdk") + + ") and compile.jdk (" + System.getProperty("compile.jdk") + ")"); + } } + /** - * Returns the full path to an executable in <current jdk>/bin based - * on System property {@code test.jdk} (set by jtreg test suite) + * Returns the full path to an executable in jdk/bin based on System + * property {@code compile.jdk} * * @return Full path to an executable in jdk/bin */ - public static String getCurrentJDKTool(String tool) { - String binPath = System.getProperty("test.jdk"); - if (binPath == null) { - throw new RuntimeException("System property 'test.jdk' not set. " - + "This property is normally set by jtreg. " - + "When running test separately, set this property using " - + "'-Dtest.jdk=/path/to/jdk'."); + public static String getCompileJDKTool(String tool) { + try { + return getTool(tool, "compile.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); } - binPath += File.separatorChar + "bin" + File.separatorChar + tool; + } - return binPath; + /** + * Returns the full path to an executable in jdk/bin based on System + * property {@code test.jdk} + * + * @return Full path to an executable in jdk/bin + */ + public static String getTestJDKTool(String tool) { + try { + return getTool(tool, "test.jdk"); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + private static String getTool(String tool, String property) throws FileNotFoundException { + String jdkPath = System.getProperty(property); + + if (jdkPath == null) { + throw new RuntimeException( + "System property '" + property + "' not set. This property is normally set by jtreg. " + + "When running test separately, set this property using '-D" + property + "=/path/to/jdk'."); + } + + Path toolName = Paths.get("bin", tool + (Platform.isWindows() ? ".exe" : "")); + + Path jdkTool = Paths.get(jdkPath, toolName.toString()); + if (!jdkTool.toFile().exists()) { + throw new FileNotFoundException("Could not find file " + jdkTool.toAbsolutePath()); + } + + return jdkTool.toAbsolutePath().toString(); } } From 86d8a77b06c526275a547f0d2a20f675746a9294 Mon Sep 17 00:00:00 2001 From: Peter Allwin Date: Tue, 17 Sep 2013 17:16:28 +0200 Subject: [PATCH 112/293] 7196151: ParserTest SEGv on solaris Reviewed-by: sla, coleenp, ctornqvi, dsamersoff --- hotspot/src/share/vm/services/diagnosticArgument.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/diagnosticArgument.cpp b/hotspot/src/share/vm/services/diagnosticArgument.cpp index 0a1c20d8a2c..51126f063b4 100644 --- a/hotspot/src/share/vm/services/diagnosticArgument.cpp +++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp @@ -61,7 +61,7 @@ void GenDCmdArgument::to_string(MemorySizeArgument m, char* buf, size_t len) { } void GenDCmdArgument::to_string(char* c, char* buf, size_t len) { - jio_snprintf(buf, len, "%s", c); + jio_snprintf(buf, len, "%s", (c != NULL) ? c : ""); } void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) { From a19b450d568a4b09b78fbaf5b23ffe9b2eaed03a Mon Sep 17 00:00:00 2001 From: Mikhailo Seledtsov Date: Tue, 17 Sep 2013 20:09:32 +0200 Subject: [PATCH 113/293] 8016029: test runtime/6878713/Test6878713.sh failed Rewrote test in Java; updated the test condition to reflect latest changes in the source Reviewed-by: dholmes, ctornqvi --- hotspot/test/runtime/6878713/Test6878713.sh | 137 ------------------ .../ClassFile/OomWhileParsingRepeatedJsr.java | 74 ++++++++++ .../{6878713 => ClassFile}/testcase.jar | Bin 3 files changed, 74 insertions(+), 137 deletions(-) delete mode 100644 hotspot/test/runtime/6878713/Test6878713.sh create mode 100644 hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java rename hotspot/test/runtime/{6878713 => ClassFile}/testcase.jar (100%) diff --git a/hotspot/test/runtime/6878713/Test6878713.sh b/hotspot/test/runtime/6878713/Test6878713.sh deleted file mode 100644 index a2b5b2d2eb7..00000000000 --- a/hotspot/test/runtime/6878713/Test6878713.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - - - -## -## @test -## @bug 6878713 -## @bug 7030610 -## @bug 7037122 -## @bug 7123945 -## @summary Verifier heap corruption, relating to backward jsrs -## @run shell Test6878713.sh -## -## some tests require path to find test source dir -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -TARGET_CLASS=OOMCrashClass1960_2 - -echo "INFO: extracting the target class." -${COMPILEJAVA}${FS}bin${FS}jar xvf \ - ${TESTSRC}${FS}testcase.jar ${TARGET_CLASS}.class - -# remove any hs_err_pid that might exist here -rm -f hs_err_pid*.log - -echo "INFO: checking for 32-bit versus 64-bit VM." -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version 2>&1 \ - | grep "64-Bit [^ ][^ ]* VM" > /dev/null 2>&1 -status="$?" -if [ "$status" = 0 ]; then - echo "INFO: testing a 64-bit VM." - is_64_bit=true -else - echo "INFO: testing a 32-bit VM." -fi - -if [ "$is_64_bit" = true ]; then - # limit is 768MB in 8-byte words (1024 * 1024 * 768 / 8) == 100663296 - MALLOC_MAX=100663296 -else - # limit is 768MB in 4-byte words (1024 * 1024 * 768 / 4) == 201326592 - MALLOC_MAX=201326592 -fi -echo "INFO: MALLOC_MAX=$MALLOC_MAX" - -echo "INFO: executing the target class." -# -XX:+PrintCommandLineFlags for debugging purposes -# -XX:+IgnoreUnrecognizedVMOptions so test will run on a VM without -# the new -XX:MallocMaxTestWords option -# -XX:+UnlockDiagnosticVMOptions so we can use -XX:MallocMaxTestWords -# -XX:MallocMaxTestWords limits malloc to $MALLOC_MAX -${TESTJAVA}${FS}bin${FS}java \ - -XX:+PrintCommandLineFlags \ - -XX:+IgnoreUnrecognizedVMOptions \ - -XX:+UnlockDiagnosticVMOptions \ - -XX:MallocMaxTestWords=$MALLOC_MAX \ - ${TESTVMOPTS} ${TARGET_CLASS} > test.out 2>&1 - -echo "INFO: begin contents of test.out:" -cat test.out -echo "INFO: end contents of test.out." - -echo "INFO: checking for memory allocation error message." -# We are looking for this specific memory allocation failure mesg so -# we know we exercised the right allocation path with the test class: -MESG1="Native memory allocation (malloc) failed to allocate 25696531[0-9][0-9] bytes" -grep "$MESG1" test.out -status="$?" -if [ "$status" = 0 ]; then - echo "INFO: found expected memory allocation error message." -else - echo "INFO: did not find expected memory allocation error message." - - # If we didn't find MESG1 above, then there are several scenarios: - # 1) -XX:MallocMaxTestWords is not supported by the current VM and we - # didn't fail TARGET_CLASS's memory allocation attempt; instead - # we failed to find TARGET_CLASS's main() method. The TARGET_CLASS - # is designed to provoke a memory allocation failure during class - # loading; we actually don't care about running the class which is - # why it doesn't have a main() method. - # 2) we failed a memory allocation, but not the one we were looking - # so it might be that TARGET_CLASS no longer tickles the same - # memory allocation code path - # 3) TARGET_CLASS reproduces the failure mode (SIGSEGV) fixed by - # 6878713 because the test is running on a pre-fix VM. - echo "INFO: checking for no main() method message." - MESG2="Error: Main method not found in class" - grep "$MESG2" test.out - status="$?" - if [ "$status" = 0 ]; then - echo "INFO: found no main() method message." - else - echo "FAIL: did not find no main() method message." - # status is non-zero for exit below - - if [ -s hs_err_pid*.log ]; then - echo "INFO: begin contents of hs_err_pid file:" - cat hs_err_pid*.log - echo "INFO: end contents of hs_err_pid file." - fi - fi -fi - -if [ "$status" = 0 ]; then - echo "PASS: test found one of the expected messages." -fi -exit "$status" diff --git a/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java new file mode 100644 index 00000000000..ad08b183e59 --- /dev/null +++ b/hotspot/test/runtime/ClassFile/OomWhileParsingRepeatedJsr.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + + +/* + * @test OomWhileParsingRepeatedJsr + * @summary Testing class file parser; specifically parsing + * a file with repeated JSR (jump local subroutine) + * bytecode command. + * @bug 6878713 + * @bug 7030610 + * @bug 7037122 + * @bug 7123945 + * @bug 8016029 + * @library /testlibrary + * @run main OomWhileParsingRepeatedJsr + */ + +import com.oracle.java.testlibrary.*; + + +public class OomWhileParsingRepeatedJsr { + + public static void main(String[] args) throws Exception { + + // ======= Configure the test + String jarFile = System.getProperty("test.src") + "/testcase.jar"; + String className = "OOMCrashClass1960_2"; + + // limit is 768MB in native words + int mallocMaxTestWords = (1024 * 1024 * 768 / 4); + if (Platform.is64bit()) + mallocMaxTestWords = (mallocMaxTestWords / 2); + + // ======= extract the test class + ProcessBuilder pb = new ProcessBuilder(new String[] { + JDKToolFinder.getJDKTool("jar"), + "xvf", jarFile } ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + // ======= execute the test + pb = ProcessTools.createJavaProcessBuilder( + "-cp", ".", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:MallocMaxTestWords=" + mallocMaxTestWords, + className ); + + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Cannot reserve enough memory"); + } +} + diff --git a/hotspot/test/runtime/6878713/testcase.jar b/hotspot/test/runtime/ClassFile/testcase.jar similarity index 100% rename from hotspot/test/runtime/6878713/testcase.jar rename to hotspot/test/runtime/ClassFile/testcase.jar From 876967ae1f16b587efc44c93334b2155b8931a9d Mon Sep 17 00:00:00 2001 From: Mikhailo Seledtsov Date: Tue, 17 Sep 2013 20:20:03 +0200 Subject: [PATCH 114/293] 7149464: [TESTBUG] Test runtime/7020373/Test7020373.sh failed to clean up files after test Re-wrote in Java, this also eliminated temporary result file; set upper limit on malloc'd memory Reviewed-by: dcubed, dholmes, ccheung --- hotspot/test/runtime/7020373/Test7020373.sh | 43 -------- .../test/runtime/ClassFile/JsrRewriting.java | 102 ++++++++++++++++++ .../JsrRewritingTestCase.jar} | Bin 3 files changed, 102 insertions(+), 43 deletions(-) delete mode 100644 hotspot/test/runtime/7020373/Test7020373.sh create mode 100644 hotspot/test/runtime/ClassFile/JsrRewriting.java rename hotspot/test/runtime/{7020373/testcase.jar => ClassFile/JsrRewritingTestCase.jar} (100%) diff --git a/hotspot/test/runtime/7020373/Test7020373.sh b/hotspot/test/runtime/7020373/Test7020373.sh deleted file mode 100644 index 83b7028c82f..00000000000 --- a/hotspot/test/runtime/7020373/Test7020373.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -## -## @test -## @bug 7020373 7055247 7053586 7185550 -## @key cte_test -## @summary JSR rewriting can overflow memory address size variables -## @ignore Ignore it as 7053586 test uses lots of memory. See bug report for detail. -## @run shell Test7020373.sh -## - -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar - -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1 - -cat test.out - -egrep "SIGSEGV|An unexpected error has been detected" test.out - -if [ $? = 0 ] -then - echo "Test Failed" - exit 1 -else - egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out - if [ $? = 0 ] - then - echo "Test Passed" - exit 0 - else - echo "Test Failed" - exit 1 - fi -fi diff --git a/hotspot/test/runtime/ClassFile/JsrRewriting.java b/hotspot/test/runtime/ClassFile/JsrRewriting.java new file mode 100644 index 00000000000..856658f9bf3 --- /dev/null +++ b/hotspot/test/runtime/ClassFile/JsrRewriting.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + + +/* + * @test JsrRewriting + * @summary JSR (jump local subroutine) + * rewriting can overflow memory address size variables + * @bug 7020373 + * @bug 7055247 + * @bug 7053586 + * @bug 7185550 + * @bug 7149464 + * @key cte_test + * @library /testlibrary + * @run main JsrRewriting + */ + +import com.oracle.java.testlibrary.*; +import java.io.File; + +public class JsrRewriting { + + public static void main(String[] args) throws Exception { + + // ======= Configure the test + String jarFile = System.getProperty("test.src") + + File.separator + "JsrRewritingTestCase.jar"; + String className = "OOMCrashClass4000_1"; + + // limit is 768MB in native words + int mallocMaxTestWords = (1024 * 1024 * 768 / 4); + if (Platform.is64bit()) + mallocMaxTestWords = (mallocMaxTestWords / 2); + + // ======= extract the test class + ProcessBuilder pb = new ProcessBuilder(new String[] { + JDKToolFinder.getJDKTool("jar"), + "xvf", jarFile } ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + // ======= execute the test + pb = ProcessTools.createJavaProcessBuilder( + "-cp", ".", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:MallocMaxTestWords=" + mallocMaxTestWords, + className); + + output = new OutputAnalyzer(pb.start()); + String[] expectedMsgs = { + "java.lang.LinkageError", + "java.lang.NoSuchMethodError", + "Main method not found in class " + className, + "insufficient memory" + }; + + MultipleOrMatch(output, expectedMsgs); + } + + private static void + MultipleOrMatch(OutputAnalyzer analyzer, String[] whatToMatch) { + String output = analyzer.getOutput(); + + for (String expected : whatToMatch) + if (output.contains(expected)) + return; + + String err = + " stdout: [" + analyzer.getOutput() + "];\n" + + " exitValue = " + analyzer.getExitValue() + "\n"; + System.err.println(err); + + StringBuilder msg = new StringBuilder("Output did not contain " + + "any of the following expected messages: \n"); + for (String expected : whatToMatch) + msg.append(expected).append(System.lineSeparator()); + throw new RuntimeException(msg.toString()); + } +} + diff --git a/hotspot/test/runtime/7020373/testcase.jar b/hotspot/test/runtime/ClassFile/JsrRewritingTestCase.jar similarity index 100% rename from hotspot/test/runtime/7020373/testcase.jar rename to hotspot/test/runtime/ClassFile/JsrRewritingTestCase.jar From 2cab7ea037453442645008267f6e63b94fbbcd81 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Tue, 17 Sep 2013 20:59:07 +0200 Subject: [PATCH 115/293] 8024718: Metaspace performance counters and memory pools should report the same data Reviewed-by: stefank, dholmes, coleenp --- .../src/share/vm/memory/metaspaceCounters.cpp | 62 ++++++------- .../src/share/vm/memory/metaspaceCounters.hpp | 11 ++- hotspot/src/share/vm/services/memoryPool.cpp | 19 ++-- hotspot/src/share/vm/services/memoryPool.hpp | 2 - hotspot/src/share/vm/services/memoryUsage.hpp | 4 +- .../gc/metaspace/TestMetaspaceMemoryPool.java | 71 ++++----------- .../metaspace/TestMetaspacePerfCounters.java | 35 ++++++-- .../TestPerfCountersAndMemoryPools.java | 86 +++++++++++++++++++ .../java/testlibrary/InputArguments.java | 25 ++++++ 9 files changed, 201 insertions(+), 114 deletions(-) create mode 100644 hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp index 6f443466ffb..60e26b8c714 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp @@ -65,26 +65,25 @@ class MetaspacePerfCounters: public CHeapObj { MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL; -size_t MetaspaceCounters::calculate_capacity() { - // The total capacity is the sum of - // 1) capacity of Metachunks in use by all Metaspaces - // 2) unused space at the end of each Metachunk - // 3) space in the freelist - size_t total_capacity = MetaspaceAux::allocated_capacity_bytes() - + MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_bytes(); - return total_capacity; +size_t MetaspaceCounters::used() { + return MetaspaceAux::allocated_used_bytes(); +} + +size_t MetaspaceCounters::capacity() { + return MetaspaceAux::committed_bytes(); +} + +size_t MetaspaceCounters::max_capacity() { + return MetaspaceAux::reserved_bytes(); } void MetaspaceCounters::initialize_performance_counters() { if (UsePerfData) { assert(_perf_counters == NULL, "Should only be initialized once"); - size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(); - size_t used = MetaspaceAux::allocated_used_bytes(); - - _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used); + size_t min_capacity = 0; + _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, + capacity(), max_capacity(), used()); } } @@ -92,31 +91,29 @@ void MetaspaceCounters::update_performance_counters() { if (UsePerfData) { assert(_perf_counters != NULL, "Should be initialized"); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(); - size_t used = MetaspaceAux::allocated_used_bytes(); - - _perf_counters->update(capacity, max_capacity, used); + _perf_counters->update(capacity(), max_capacity(), used()); } } MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL; -size_t CompressedClassSpaceCounters::calculate_capacity() { - return MetaspaceAux::allocated_capacity_bytes(_class_type) + - MetaspaceAux::free_bytes(_class_type) + - MetaspaceAux::free_chunks_total_bytes(_class_type); +size_t CompressedClassSpaceCounters::used() { + return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); +} + +size_t CompressedClassSpaceCounters::capacity() { + return MetaspaceAux::committed_bytes(Metaspace::ClassType); +} + +size_t CompressedClassSpaceCounters::max_capacity() { + return MetaspaceAux::reserved_bytes(Metaspace::ClassType); } void CompressedClassSpaceCounters::update_performance_counters() { if (UsePerfData && UseCompressedClassPointers) { assert(_perf_counters != NULL, "Should be initialized"); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); - size_t used = MetaspaceAux::allocated_used_bytes(_class_type); - - _perf_counters->update(capacity, max_capacity, used); + _perf_counters->update(capacity(), max_capacity(), used()); } } @@ -126,12 +123,9 @@ void CompressedClassSpaceCounters::initialize_performance_counters() { const char* ns = "compressedclassspace"; if (UseCompressedClassPointers) { - size_t min_capacity = MetaspaceAux::min_chunk_size_bytes(); - size_t capacity = calculate_capacity(); - size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type); - size_t used = MetaspaceAux::allocated_used_bytes(_class_type); - - _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used); + size_t min_capacity = 0; + _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity(), + max_capacity(), used()); } else { _perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0); } diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.hpp b/hotspot/src/share/vm/memory/metaspaceCounters.hpp index 5b481d59b4d..0fa991291a1 100644 --- a/hotspot/src/share/vm/memory/metaspaceCounters.hpp +++ b/hotspot/src/share/vm/memory/metaspaceCounters.hpp @@ -25,13 +25,15 @@ #ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP #define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP -#include "memory/metaspace.hpp" +#include "memory/allocation.hpp" class MetaspacePerfCounters; class MetaspaceCounters: public AllStatic { static MetaspacePerfCounters* _perf_counters; - static size_t calculate_capacity(); + static size_t used(); + static size_t capacity(); + static size_t max_capacity(); public: static void initialize_performance_counters(); @@ -40,8 +42,9 @@ class MetaspaceCounters: public AllStatic { class CompressedClassSpaceCounters: public AllStatic { static MetaspacePerfCounters* _perf_counters; - static size_t calculate_capacity(); - static const Metaspace::MetadataType _class_type = Metaspace::ClassType; + static size_t used(); + static size_t capacity(); + static size_t max_capacity(); public: static void initialize_performance_counters(); diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index 7a17f0bd138..cfae726cf7b 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -260,10 +260,10 @@ MemoryUsage CodeHeapPool::get_memory_usage() { } MetaspacePool::MetaspacePool() : - MemoryPool("Metaspace", NonHeap, capacity_in_bytes(), calculate_max_size(), true, false) { } + MemoryPool("Metaspace", NonHeap, 0, calculate_max_size(), true, false) { } MemoryUsage MetaspacePool::get_memory_usage() { - size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size()); + size_t committed = MetaspaceAux::committed_bytes(); return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size()); } @@ -271,26 +271,19 @@ size_t MetaspacePool::used_in_bytes() { return MetaspaceAux::allocated_used_bytes(); } -size_t MetaspacePool::capacity_in_bytes() const { - return MetaspaceAux::allocated_capacity_bytes(); -} - size_t MetaspacePool::calculate_max_size() const { - return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : max_uintx; + return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : + MemoryUsage::undefined_size(); } CompressedKlassSpacePool::CompressedKlassSpacePool() : - MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), CompressedClassSpaceSize, true, false) { } + MemoryPool("Compressed Class Space", NonHeap, 0, CompressedClassSpaceSize, true, false) { } size_t CompressedKlassSpacePool::used_in_bytes() { return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType); } -size_t CompressedKlassSpacePool::capacity_in_bytes() const { - return MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); -} - MemoryUsage CompressedKlassSpacePool::get_memory_usage() { - size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size()); + size_t committed = MetaspaceAux::committed_bytes(Metaspace::ClassType); return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size()); } diff --git a/hotspot/src/share/vm/services/memoryPool.hpp b/hotspot/src/share/vm/services/memoryPool.hpp index 08efe08e838..4ec810a985f 100644 --- a/hotspot/src/share/vm/services/memoryPool.hpp +++ b/hotspot/src/share/vm/services/memoryPool.hpp @@ -224,7 +224,6 @@ public: class MetaspacePool : public MemoryPool { size_t calculate_max_size() const; - size_t capacity_in_bytes() const; public: MetaspacePool(); MemoryUsage get_memory_usage(); @@ -232,7 +231,6 @@ class MetaspacePool : public MemoryPool { }; class CompressedKlassSpacePool : public MemoryPool { - size_t capacity_in_bytes() const; public: CompressedKlassSpacePool(); MemoryUsage get_memory_usage(); diff --git a/hotspot/src/share/vm/services/memoryUsage.hpp b/hotspot/src/share/vm/services/memoryUsage.hpp index efc6f2966d1..9027f8e76b7 100644 --- a/hotspot/src/share/vm/services/memoryUsage.hpp +++ b/hotspot/src/share/vm/services/memoryUsage.hpp @@ -63,10 +63,12 @@ public: size_t committed() const { return _committed; } size_t max_size() const { return _maxSize; } + static size_t undefined_size() { return (size_t) -1; } + inline static jlong convert_to_jlong(size_t val) { // In the 64-bit vm, a size_t can overflow a jlong (which is signed). jlong ret; - if (val == (size_t)-1) { + if (val == undefined_size()) { ret = -1L; } else { NOT_LP64(ret = val;) diff --git a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java index 105ba240ddf..bf9e74c8ab0 100644 --- a/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java +++ b/hotspot/test/gc/metaspace/TestMetaspaceMemoryPool.java @@ -22,18 +22,15 @@ */ import java.util.List; -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryManagerMXBean; -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.MemoryUsage; - -import java.lang.management.RuntimeMXBean; -import java.lang.management.ManagementFactory; +import java.lang.management.*; +import com.oracle.java.testlibrary.*; +import static com.oracle.java.testlibrary.Asserts.*; /* @test TestMetaspaceMemoryPool * @bug 8000754 * @summary Tests that a MemoryPoolMXBeans is created for metaspace and that a * MemoryManagerMXBean is created. + * @library /testlibrary * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops TestMetaspaceMemoryPool * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPool * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers TestMetaspaceMemoryPool @@ -42,35 +39,18 @@ import java.lang.management.ManagementFactory; public class TestMetaspaceMemoryPool { public static void main(String[] args) { verifyThatMetaspaceMemoryManagerExists(); - verifyMemoryPool(getMemoryPool("Metaspace"), isFlagDefined("MaxMetaspaceSize")); - if (runsOn64bit()) { - if (usesCompressedOops()) { + boolean isMetaspaceMaxDefined = InputArguments.containsPrefix("-XX:MaxMetaspaceSize"); + verifyMemoryPool(getMemoryPool("Metaspace"), isMetaspaceMaxDefined); + + if (Platform.is64bit()) { + if (InputArguments.contains("-XX:+UseCompressedOops")) { MemoryPoolMXBean cksPool = getMemoryPool("Compressed Class Space"); verifyMemoryPool(cksPool, true); } } } - private static boolean runsOn64bit() { - return !System.getProperty("sun.arch.data.model").equals("32"); - } - - private static boolean usesCompressedOops() { - return isFlagDefined("+UseCompressedOops"); - } - - private static boolean isFlagDefined(String name) { - RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); - List args = runtimeMxBean.getInputArguments(); - for (String arg : args) { - if (arg.startsWith("-XX:" + name)) { - return true; - } - } - return false; - } - private static void verifyThatMetaspaceMemoryManagerExists() { List managers = ManagementFactory.getMemoryManagerMXBeans(); for (MemoryManagerMXBean manager : managers) { @@ -95,32 +75,19 @@ public class TestMetaspaceMemoryPool { private static void verifyMemoryPool(MemoryPoolMXBean pool, boolean isMaxDefined) { MemoryUsage mu = pool.getUsage(); - assertDefined(mu.getInit(), "init"); - assertDefined(mu.getUsed(), "used"); - assertDefined(mu.getCommitted(), "committed"); + long init = mu.getInit(); + long used = mu.getUsed(); + long committed = mu.getCommitted(); + long max = mu.getMax(); + + assertGTE(init, 0L); + assertGTE(used, init); + assertGTE(committed, used); if (isMaxDefined) { - assertDefined(mu.getMax(), "max"); + assertGTE(max, committed); } else { - assertUndefined(mu.getMax(), "max"); - } - } - - private static void assertDefined(long value, String name) { - assertTrue(value != -1, "Expected " + name + " to be defined"); - } - - private static void assertUndefined(long value, String name) { - assertEquals(value, -1, "Expected " + name + " to be undefined"); - } - - private static void assertEquals(long actual, long expected, String msg) { - assertTrue(actual == expected, msg); - } - - private static void assertTrue(boolean condition, String msg) { - if (!condition) { - throw new RuntimeException(msg); + assertEQ(max, -1L); } } } diff --git a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java index 9672d90a5d0..974066cba56 100644 --- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java +++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java @@ -61,10 +61,15 @@ public class TestMetaspacePerfCounters { } private static void checkPerfCounters(String ns) throws Exception { - for (PerfCounter counter : countersInNamespace(ns)) { - String msg = "Expected " + counter.getName() + " to be larger than 0"; - assertGT(counter.longValue(), 0L, msg); - } + long minCapacity = getMinCapacity(ns); + long maxCapacity = getMaxCapacity(ns); + long capacity = getCapacity(ns); + long used = getUsed(ns); + + assertGTE(minCapacity, 0L); + assertGTE(used, minCapacity); + assertGTE(capacity, used); + assertGTE(maxCapacity, capacity); } private static void checkEmptyPerfCounters(String ns) throws Exception { @@ -75,12 +80,10 @@ public class TestMetaspacePerfCounters { } private static void checkUsedIncreasesWhenLoadingClass(String ns) throws Exception { - PerfCounter used = PerfCounters.findByName(ns + ".used"); - - long before = used.longValue(); + long before = getUsed(ns); fooClass = compileAndLoad("Foo", "public class Foo { }"); System.gc(); - long after = used.longValue(); + long after = getUsed(ns); assertGT(after, before); } @@ -101,4 +104,20 @@ public class TestMetaspacePerfCounters { private static boolean isUsingCompressedClassPointers() { return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers"); } + + private static long getMinCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".minCapacity").longValue(); + } + + private static long getCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".capacity").longValue(); + } + + private static long getMaxCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".maxCapacity").longValue(); + } + + private static long getUsed(String ns) throws Exception { + return PerfCounters.findByName(ns + ".used").longValue(); + } } diff --git a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java new file mode 100644 index 00000000000..e26aa6eee57 --- /dev/null +++ b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; +import java.lang.management.*; + +import com.oracle.java.testlibrary.*; +import static com.oracle.java.testlibrary.Asserts.*; + +/* @test TestPerfCountersAndMemoryPools + * @bug 8023476 + * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace + * report the same data. + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools + */ +public class TestPerfCountersAndMemoryPools { + public static void main(String[] args) throws Exception { + checkMemoryUsage("Metaspace", "sun.gc.metaspace"); + + if (InputArguments.contains("-XX:+UseCompressedKlassPointers") && Platform.is64bit()) { + checkMemoryUsage("Compressed Class Space", "sun.gc.compressedclassspace"); + } + } + + private static MemoryUsage getMemoryUsage(String memoryPoolName) { + List pools = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean pool : pools) { + if (pool.getName().equals(memoryPoolName)) { + return pool.getUsage(); + } + } + + throw new RuntimeException("Excpted to find a memory pool with name " + + memoryPoolName); + } + + private static void checkMemoryUsage(String memoryPoolName, String perfNS) + throws Exception { + // Need to do a gc before each comparison to update the perf counters + + System.gc(); + MemoryUsage mu = getMemoryUsage(memoryPoolName); + assertEQ(getMinCapacity(perfNS), mu.getInit()); + + System.gc(); + mu = getMemoryUsage(memoryPoolName); + assertEQ(getUsed(perfNS), mu.getUsed()); + + System.gc(); + mu = getMemoryUsage(memoryPoolName); + assertEQ(getCapacity(perfNS), mu.getCommitted()); + } + + private static long getMinCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".minCapacity").longValue(); + } + + private static long getCapacity(String ns) throws Exception { + return PerfCounters.findByName(ns + ".capacity").longValue(); + } + + private static long getUsed(String ns) throws Exception { + return PerfCounters.findByName(ns + ".used").longValue(); + } +} diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java index 650d6c23390..6f40b4050be 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InputArguments.java @@ -41,6 +41,9 @@ public class InputArguments { /** * Returns true if {@code arg} is an input argument to the VM. * + * This is useful for checking boolean flags such as -XX:+UseSerialGC or + * -XX:-UsePerfData. + * * @param arg The name of the argument. * @return {@code true} if the given argument is an input argument, * otherwise {@code false}. @@ -48,4 +51,26 @@ public class InputArguments { public static boolean contains(String arg) { return args.contains(arg); } + + /** + * Returns true if {@code prefix} is the start of an input argument to the + * VM. + * + * This is useful for checking if flags describing a quantity, such as + * -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity. + * To check if the flag -XX:MaxMetaspaceSize is set, use + * {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}. + * + * @param prefix The start of the argument. + * @return {@code true} if the given argument is the start of an input + * argument, otherwise {@code false}. + */ + public static boolean containsPrefix(String prefix) { + for (String arg : args) { + if (arg.startsWith(prefix)) { + return true; + } + } + return false; + } } From 7cc012b008641662edc9fbaa84b4b1be7527540a Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 17 Sep 2013 14:17:13 -0700 Subject: [PATCH 116/293] 8024538: -Xdoclint + -Xprefer:source + incremental compilation == FAIL Reviewed-by: darcy --- .../com/sun/tools/doclint/DocLint.java | 19 ++++++++-- .../com/sun/tools/javac/comp/Enter.java | 4 ++- .../implicitSource/ImplicitSourceTest.java | 35 +++++++++++++++++++ .../javac/doclint/implicitSource/Other.java | 25 +++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java create mode 100644 langtools/test/tools/javac/doclint/implicitSource/Other.java diff --git a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java index 20151d1f360..a7b6fb6a15c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java @@ -29,9 +29,14 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Queue; +import java.util.Set; import javax.lang.model.element.Name; +import javax.tools.JavaFileObject; import javax.tools.StandardLocation; import com.sun.source.doctree.DocCommentTree; @@ -278,15 +283,25 @@ public class DocLint implements Plugin { TaskListener tl = new TaskListener() { @Override public void started(TaskEvent e) { + switch (e.getKind()) { + case ANALYZE: + CompilationUnitTree tree; + while ((tree = todo.poll()) != null) + ds.scan(tree, null); + break; + } } @Override public void finished(TaskEvent e) { switch (e.getKind()) { - case ENTER: - ds.scan(e.getCompilationUnit(), null); + case PARSE: + todo.add(e.getCompilationUnit()); + break; } } + + Queue todo = new LinkedList(); }; task.addTaskListener(tl); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java index 41c0792acf2..697a6921d01 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java @@ -288,7 +288,9 @@ public class Enter extends JCTree.Visitor { JavaFileObject.Kind.SOURCE); if (tree.pid != null) { tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid)); - if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) { + if (tree.packageAnnotations.nonEmpty() + || pkginfoOpt == PkgInfo.ALWAYS + || tree.docComments != null) { if (isPkgInfo) { addEnv = true; } else if (tree.packageAnnotations.nonEmpty()){ diff --git a/langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java b/langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java new file mode 100644 index 00000000000..6ae67ce2819 --- /dev/null +++ b/langtools/test/tools/javac/doclint/implicitSource/ImplicitSourceTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024538 + * @summary -Xdoclint + -Xprefer:source + incremental compilation == FAIL + * @compile -Xdoclint -Xprefer:source ImplicitSourceTest.java + */ + +/** ImplicitSourceTest. */ +class ImplicitSourceTest { + /**

{@link Other}

*/ + int i; +} diff --git a/langtools/test/tools/javac/doclint/implicitSource/Other.java b/langtools/test/tools/javac/doclint/implicitSource/Other.java new file mode 100644 index 00000000000..65a5dd5b45a --- /dev/null +++ b/langtools/test/tools/javac/doclint/implicitSource/Other.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** Other. */ +class Other { } From 73fa61708235e102fde7475399427e295ed3873c Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Wed, 18 Sep 2013 07:22:20 +0200 Subject: [PATCH 117/293] 8022883: Assertion failed: sweptCount >= flushedCount + markedCount + zombifiedCount Provide correct number of visited nmethods to Tracing Reviewed-by: kvn, iveresov --- hotspot/src/share/vm/runtime/sweeper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index ebecda50be0..37315aec328 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -269,6 +269,7 @@ void NMethodSweeper::sweep_code_cache() { // the number of nmethods changes during the sweep so the final // stage must iterate until it there are no more nmethods. int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; + int swept_count = 0; assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); assert(!CodeCache_lock->owned_by_self(), "just checking"); @@ -278,6 +279,7 @@ void NMethodSweeper::sweep_code_cache() { // The last invocation iterates until there are no more nmethods for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) { + swept_count++; if (SafepointSynchronize::is_synchronizing()) { // Safepoint request if (PrintMethodFlushing && Verbose) { tty->print_cr("### Sweep at %d out of %d, invocation: %d, yielding to safepoint", _seen, CodeCache::nof_nmethods(), _invocations); @@ -331,7 +333,7 @@ void NMethodSweeper::sweep_code_cache() { event.set_endtime(sweep_end_counter); event.set_sweepIndex(_traversals); event.set_sweepFractionIndex(NmethodSweepFraction - _invocations + 1); - event.set_sweptCount(todo); + event.set_sweptCount(swept_count); event.set_flushedCount(_flushed_count); event.set_markedCount(_marked_count); event.set_zombifiedCount(_zombified_count); From e287ff4ec907bfb39052cb1516ba2d81381415db Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 18 Sep 2013 13:06:17 +0530 Subject: [PATCH 118/293] 8024972: for (LeftHandSideExpression in Expression) crashes the compiler Reviewed-by: lagergren, hannesw --- .../internal/codegen/CodeGenerator.java | 1 - nashorn/test/script/basic/JDK-8024972.js | 43 +++++++++++++++++++ .../test/script/basic/JDK-8024972.js.EXPECTED | 6 +++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8024972.js create mode 100644 nashorn/test/script/basic/JDK-8024972.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 809b2ec21e2..6307e2f9dbe 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -852,7 +852,6 @@ final class CodeGenerator extends NodeOperatorVisitor"+ arr[obj.x]); +} + +var abc = { foo: 'bar', hello: 'world' }; +for (obj.x in abc) { + print(obj.x + "->" + abc[obj.x]); +} + +for (obj.x in 0) {} diff --git a/nashorn/test/script/basic/JDK-8024972.js.EXPECTED b/nashorn/test/script/basic/JDK-8024972.js.EXPECTED new file mode 100644 index 00000000000..aa4692fb2cc --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024972.js.EXPECTED @@ -0,0 +1,6 @@ +0->2 +1->45 +2->-1 +3->445 +foo->bar +hello->world From 3e4a59f7973775bea3d1bebce1e095178854df42 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 18 Sep 2013 10:02:19 +0200 Subject: [PATCH 119/293] 8024662: gc/arguments/TestUseCompressedOopsErgo.java does not compile Fix compilation error and use of an outdated VM option in the test Reviewed-by: stefank, jwilhelm --- .../TestUseCompressedOopsErgoTools.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java index 49d0a8a1d21..54c70672d04 100644 --- a/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgoTools.java @@ -42,10 +42,10 @@ class DetermineMaxHeapForCompressedOops { class TestUseCompressedOopsErgoTools { - private static long getClassMetaspaceSize() { + private static long getCompressedClassSpaceSize() { HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); - VMOption option = diagnostic.getVMOption("ClassMetaspaceSize"); + VMOption option = diagnostic.getVMOption("CompressedClassSpaceSize"); return Long.parseLong(option.getValue()); } @@ -132,13 +132,13 @@ class TestUseCompressedOopsErgoTools { checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops - 1, true); checkUseCompressedOops(join(gcflags, "-XX:ObjectAlignmentInBytes=16"), maxHeapForCompressedOops + 1, false); - // use a different ClassMetaspaceSize - String classMetaspaceSizeArg = "-XX:ClassMetaspaceSize=" + 2 * getClassMetaspaceSize(); - maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, classMetaspaceSizeArg)); + // use a different CompressedClassSpaceSize + String compressedClassSpaceSizeArg = "-XX:CompressedClassSpaceSize=" + 2 * getCompressedClassSpaceSize(); + maxHeapForCompressedOops = getMaxHeapForCompressedOops(join(gcflags, compressedClassSpaceSizeArg)); - checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops, true); - checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops - 1, true); - checkUseCompressedOops(join(gcflags, classMetaspaceSizeArg), maxHeapForCompressedOops + 1, false); + checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops, true); + checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops - 1, true); + checkUseCompressedOops(join(gcflags, compressedClassSpaceSizeArg), maxHeapForCompressedOops + 1, false); } private static void checkUseCompressedOops(String[] args, long heapsize, boolean expectUseCompressedOops) throws Exception { @@ -152,9 +152,7 @@ class TestUseCompressedOopsErgoTools { boolean actualUseCompressedOops = getFlagBoolValue(" UseCompressedOops", output); - if (expectUseCompressedOops != actualUseCompressedOops) { - throw new RuntimeException("Expected use of compressed oops: " + expectUseCompressedOops + " but was: " + actualUseCompressedOops); - } + Asserts.assertEQ(expectUseCompressedOops, actualUseCompressedOops); } private static boolean getFlagBoolValue(String flag, String where) { @@ -162,7 +160,7 @@ class TestUseCompressedOopsErgoTools { if (!m.find()) { throw new RuntimeException("Could not find value for flag " + flag + " in output string"); } - String match = m.group(1).equals("true"); + return m.group(1).equals("true"); } private static String expect(String[] flags, boolean hasWarning, boolean hasError, int errorcode) throws Exception { From 8f9057132237247776d8e2ce6b5308356b5154dd Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 18 Sep 2013 16:36:25 +0530 Subject: [PATCH 120/293] 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException Reviewed-by: jlaskey, hannesw --- .../api/scripting/NashornScriptEngine.java | 69 +++++++++++-------- .../jdk/nashorn/internal/runtime/Source.java | 2 +- nashorn/test/script/trusted/JDK-8008305.js | 2 +- .../api/scripting/ScriptEngineTest.java | 13 ++++ 4 files changed, 56 insertions(+), 30 deletions(-) diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 45eddd117aa..4629665f98b 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -185,21 +185,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C @Override public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException { - try { - if (reader instanceof URLReader) { - final URL url = ((URLReader)reader).getURL(); - final Charset cs = ((URLReader)reader).getCharset(); - return evalImpl(compileImpl(new Source(url.toString(), url, cs), ctxt), ctxt); - } - return evalImpl(Source.readFully(reader), ctxt); - } catch (final IOException e) { - throw new ScriptException(e); - } + return evalImpl(makeSource(reader, ctxt), ctxt); } @Override public Object eval(final String script, final ScriptContext ctxt) throws ScriptException { - return evalImpl(script.toCharArray(), ctxt); + return evalImpl(makeSource(script, ctxt), ctxt); } @Override @@ -221,16 +212,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C @Override public CompiledScript compile(final Reader reader) throws ScriptException { - try { - return asCompiledScript(compileImpl(Source.readFully(reader), context)); - } catch (final IOException e) { - throw new ScriptException(e); - } + return asCompiledScript(makeSource(reader, context)); } @Override public CompiledScript compile(final String str) throws ScriptException { - return asCompiledScript(compileImpl(str.toCharArray(), context)); + return asCompiledScript(makeSource(str, context)); } // Invocable methods @@ -292,6 +279,29 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Implementation only below this point + private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException { + try { + if (reader instanceof URLReader) { + final URL url = ((URLReader)reader).getURL(); + final Charset cs = ((URLReader)reader).getCharset(); + return new Source(url.toString(), url, cs); + } else { + return new Source(getScriptName(ctxt), Source.readFully(reader)); + } + } catch (final IOException ioExp) { + throw new ScriptException(ioExp); + } + } + + private static Source makeSource(final String src, final ScriptContext ctxt) { + return new Source(getScriptName(ctxt), src); + } + + private static String getScriptName(final ScriptContext ctxt) { + final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); + return (val != null) ? val.toString() : ""; + } + private T getInterfaceInner(final Object thiz, final Class clazz) { if (clazz == null || !clazz.isInterface()) { throw new IllegalArgumentException(getMessage("interface.class.expected")); @@ -429,7 +439,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // current ScriptContext exposed as "context" // "context" is non-writable from script - but script engine still // needs to set it and so save the context Property object - contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, null); + contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, ctxt); // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property // in the Global of a Context we just created - both the Context and the Global were just created and can not be @@ -509,8 +519,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("interface.on.non.script.object")); } - private Object evalImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { - return evalImpl(compileImpl(buf, ctxt), ctxt); + private Object evalImpl(final Source src, final ScriptContext ctxt) throws ScriptException { + return evalImpl(compileImpl(src, ctxt), ctxt); } private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException { @@ -561,11 +571,20 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } } - private CompiledScript asCompiledScript(final ScriptFunction script) { + private CompiledScript asCompiledScript(final Source source) throws ScriptException { + final ScriptFunction func = compileImpl(source, context); return new CompiledScript() { @Override public Object eval(final ScriptContext ctxt) throws ScriptException { - return evalImpl(script, ctxt); + final ScriptObject global = getNashornGlobalFrom(ctxt); + // Are we running the script in the correct global? + if (func.getScope() == global) { + return evalImpl(func, ctxt, global); + } else { + // ScriptContext with a different global. Compile again! + // Note that we may still hit per-global compilation cache. + return evalImpl(compileImpl(source, ctxt), ctxt, global); + } } @Override public ScriptEngine getEngine() { @@ -574,12 +593,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C }; } - private ScriptFunction compileImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { - final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); - final String fileName = (val != null) ? val.toString() : ""; - return compileImpl(new Source(fileName, buf), ctxt); - } - private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException { return compileImpl(source, getNashornGlobalFrom(ctxt)); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Source.java b/nashorn/src/jdk/nashorn/internal/runtime/Source.java index 7e3c8684e91..9273e7a8bac 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Source.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Source.java @@ -169,7 +169,7 @@ public final class Source { final Source src = (Source)obj; // Only compare content as a last resort measure - return length == src.length && Objects.equals(name, src.name) && Arrays.equals(content, src.content); + return length == src.length && Objects.equals(url, src.url) && Objects.equals(name, src.name) && Arrays.equals(content, src.content); } @Override diff --git a/nashorn/test/script/trusted/JDK-8008305.js b/nashorn/test/script/trusted/JDK-8008305.js index e4d052cbce8..d57b5208048 100644 --- a/nashorn/test/script/trusted/JDK-8008305.js +++ b/nashorn/test/script/trusted/JDK-8008305.js @@ -54,6 +54,6 @@ try { fail("Expected SecurityException from script!"); } catch (e) { if (! (e instanceof SecurityException)) { - faile("Expected SecurityException, but got " + e); + fail("Expected SecurityException, but got " + e); } } diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index 416669fbcf3..99207de0d6e 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -37,10 +37,12 @@ import java.lang.reflect.Method; import java.util.concurrent.Callable; import javax.script.Compilable; import javax.script.CompiledScript; +import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import javax.script.SimpleScriptContext; import org.testng.annotations.Test; /** @@ -230,6 +232,17 @@ public class ScriptEngineTest { } } + @Test + public void compileAndEvalInDiffContextTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine = m.getEngineByName("js"); + final Compilable compilable = (Compilable) engine; + final CompiledScript compiledScript = compilable.compile("foo"); + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE); + assertEquals(compiledScript.eval(ctxt), "hello"); + } + @Test public void accessGlobalTest() { final ScriptEngineManager m = new ScriptEngineManager(); From f6e98b818159cabd05ad21cadc906c8ef1b5cba6 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 18 Sep 2013 13:18:52 +0200 Subject: [PATCH 121/293] 8024669: Native OOME when allocating after changes to maximum heap supporting Coops sizing on sparcv9 After changes in 8010722 the ergonomics for calculating the size of the heap that supports zero based compressed oops changed. This lead to the VM actually using zero based compressed oops. Due to low default HeapBaseMinAddress, the OS mapping in the application image at the same address, and limitations of the malloc implementation on Solaris this resulted in very little C heap available for the VM. So the VM immediately gives a native OOME when the machine has lots of physical memory (>=32G). The solution is to increase the HeapBaseMinAddress so that the VM has enough C heap. Reviewed-by: kvn, brutisso --- hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp index 595cd781447..e0ed6961e3a 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp @@ -35,7 +35,9 @@ define_pd_global(intx, CompilerThreadStackSize, 0); // Used on 64 bit platforms for UseCompressedOops base address #ifdef _LP64 -define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G); +// use 6G as default base address because by default the OS maps the application +// to 4G on Solaris-Sparc. This leaves at least 2G for the native heap. +define_pd_global(uintx, HeapBaseMinAddress, CONST64(6)*G); #else define_pd_global(uintx, HeapBaseMinAddress, 2*G); #endif From 775822bed7ad6b5df862bf28fc8b462c203cf247 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Wed, 18 Sep 2013 14:39:27 +0200 Subject: [PATCH 122/293] 8024127: javac, Code_attribute.exception_table_langth should be Code_attribute.exception_table_length Exception_table_langth renamed to exception_table_length Reviewed-by: jfranck, jjg --- .../classes/com/sun/tools/classfile/Code_attribute.java | 8 ++++---- .../src/share/classes/com/sun/tools/javap/CodeWriter.java | 2 +- langtools/test/tools/javac/T7093325.java | 2 +- .../javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java | 2 +- langtools/test/tools/javac/multicatch/Pos05.java | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java index 5d7c81474f2..6d5b7e6bef8 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Code_attribute.java @@ -61,9 +61,9 @@ public class Code_attribute extends Attribute { code_length = cr.readInt(); code = new byte[code_length]; cr.readFully(code); - exception_table_langth = cr.readUnsignedShort(); - exception_table = new Exception_data[exception_table_langth]; - for (int i = 0; i < exception_table_langth; i++) + exception_table_length = cr.readUnsignedShort(); + exception_table = new Exception_data[exception_table_length]; + for (int i = 0; i < exception_table_length; i++) exception_table[i] = new Exception_data(cr); attributes = new Attributes(cr); } @@ -139,7 +139,7 @@ public class Code_attribute extends Attribute { public final int max_locals; public final int code_length; public final byte[] code; - public final int exception_table_langth; + public final int exception_table_length; public final Exception_data[] exception_table; public final Attributes attributes; diff --git a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java index 657194d19c6..6211a2a13cf 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java @@ -208,7 +208,7 @@ public class CodeWriter extends BasicWriter { public void writeExceptionTable(Code_attribute attr) { - if (attr.exception_table_langth > 0) { + if (attr.exception_table_length > 0) { println("Exception table:"); indent(+1); println(" from to target type"); diff --git a/langtools/test/tools/javac/T7093325.java b/langtools/test/tools/javac/T7093325.java index dcdc6e62856..fb11a87e77e 100644 --- a/langtools/test/tools/javac/T7093325.java +++ b/langtools/test/tools/javac/T7093325.java @@ -208,7 +208,7 @@ public class T7093325 } int actualGapsCount = 0; - for (int i = 0; i < code.exception_table_langth ; i++) { + for (int i = 0; i < code.exception_table_length ; i++) { int catchType = code.exception_table[i].catch_type; if (catchType == 0) { //any actualGapsCount++; diff --git a/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java index 0dd25871f3a..9b69b074624 100644 --- a/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java +++ b/langtools/test/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java @@ -100,7 +100,7 @@ public class NoDeadCodeGenerationOnTrySmtTest { if (method.getName(classFile.constant_pool).equals(methodToFind)) { numberOfmethodsFound++; Code_attribute code = (Code_attribute) method.attributes.get("Code"); - Assert.check(code.exception_table_langth == expectedExceptionTable.length, + Assert.check(code.exception_table_length == expectedExceptionTable.length, "The ExceptionTable found has a length different to the expected one"); int i = 0; for (Exception_data entry: code.exception_table) { diff --git a/langtools/test/tools/javac/multicatch/Pos05.java b/langtools/test/tools/javac/multicatch/Pos05.java index e3c3d50d321..32d76b2368b 100644 --- a/langtools/test/tools/javac/multicatch/Pos05.java +++ b/langtools/test/tools/javac/multicatch/Pos05.java @@ -95,7 +95,7 @@ public class Pos05 { throw new Error("Code attribute for test() method not found"); } Exception_data firstExceptionTable = null; - for (int i = 0 ; i < ea.exception_table_langth; i++) { + for (int i = 0 ; i < ea.exception_table_length; i++) { if (firstExceptionTable == null) { firstExceptionTable = ea.exception_table[i]; } From c5c705217bf51ac2a2e329fbffe1db3e0de366f7 Mon Sep 17 00:00:00 2001 From: Sergey Gabdurakhmanov Date: Wed, 18 Sep 2013 16:48:49 +0400 Subject: [PATCH 123/293] 8022836: JVM crashes in JVMTIENVBASE::GET_CURRENT_CONTENDED_MONITOR and GET_OWNED_MONITOR Check that the _java_thread parameter is valid when it is possible that the JavaThread has exited after the initial checks were made in generated/jvmtifiles/jvmtiEnter.cpp: jvmti_GetCurrentContendedMonitor() Reviewed-by: dcubed, dsamersoff --- hotspot/src/share/vm/prims/jvmtiEnvBase.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp index 929dcf22260..265154683ba 100644 --- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp +++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp @@ -406,7 +406,11 @@ public: VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; } jvmtiError result() { return _result; } void doit() { - _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); + _result = JVMTI_ERROR_THREAD_NOT_ALIVE; + if (Threads::includes(_java_thread) && !_java_thread->is_exiting() && + _java_thread->threadObj() != NULL) { + _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); + } } }; From 41bce440a4f08849888aff8042a6663e9942745c Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Wed, 18 Sep 2013 07:02:10 -0700 Subject: [PATCH 124/293] 8019835: Strings interned in different threads equal but does not == Add -XX:+VerifyStringTableAtExit option and code to verify StringTable invariants. Reviewed-by: rdurbin, sspitsyn, coleenp --- .../src/share/vm/classfile/javaClasses.cpp | 23 +++ .../src/share/vm/classfile/javaClasses.hpp | 1 + .../src/share/vm/classfile/symbolTable.cpp | 158 ++++++++++++++++++ .../src/share/vm/classfile/symbolTable.hpp | 20 +++ hotspot/src/share/vm/runtime/globals.hpp | 3 + hotspot/src/share/vm/runtime/java.cpp | 13 ++ 6 files changed, 218 insertions(+) diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 8e94d834ad9..9331cc1246f 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -438,6 +438,29 @@ bool java_lang_String::equals(oop java_string, jchar* chars, int len) { return true; } +bool java_lang_String::equals(oop str1, oop str2) { + assert(str1->klass() == SystemDictionary::String_klass(), + "must be java String"); + assert(str2->klass() == SystemDictionary::String_klass(), + "must be java String"); + typeArrayOop value1 = java_lang_String::value(str1); + int offset1 = java_lang_String::offset(str1); + int length1 = java_lang_String::length(str1); + typeArrayOop value2 = java_lang_String::value(str2); + int offset2 = java_lang_String::offset(str2); + int length2 = java_lang_String::length(str2); + + if (length1 != length2) { + return false; + } + for (int i = 0; i < length1; i++) { + if (value1->char_at(i + offset1) != value2->char_at(i + offset2)) { + return false; + } + } + return true; +} + void java_lang_String::print(Handle java_string, outputStream* st) { oop obj = java_string(); assert(obj->klass() == SystemDictionary::String_klass(), "must be java_string"); diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 8a8e801f387..ffccf2f0e0c 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -182,6 +182,7 @@ class java_lang_String : AllStatic { static unsigned int hash_string(oop java_string); static bool equals(oop java_string, jchar* chars, int len); + static bool equals(oop str1, oop str2); // Conversion between '.' and '/' formats static Handle externalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '/', '.', THREAD); } diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index c00e9581759..747ca870c2b 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -807,6 +807,8 @@ void StringTable::possibly_parallel_oops_do(OopClosure* f) { } } +// This verification is part of Universe::verify() and needs to be quick. +// See StringTable::verify_and_compare() below for exhaustive verification. void StringTable::verify() { for (int i = 0; i < the_table()->table_size(); ++i) { HashtableEntry* p = the_table()->bucket(i); @@ -825,6 +827,162 @@ void StringTable::dump(outputStream* st) { the_table()->dump_table(st, "StringTable"); } +StringTable::VerifyRetTypes StringTable::compare_entries( + int bkt1, int e_cnt1, + HashtableEntry* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry* e_ptr2) { + // These entries are sanity checked by verify_and_compare_entries() + // before this function is called. + oop str1 = e_ptr1->literal(); + oop str2 = e_ptr2->literal(); + + if (str1 == str2) { + tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " + "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", + str1, bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + if (java_lang_String::equals(str1, str2)) { + tty->print_cr("ERROR: identical String values in entry @ " + "bucket[%d][%d] and entry @ bucket[%d][%d]", + bkt1, e_cnt1, bkt2, e_cnt2); + return _verify_fail_continue; + } + + return _verify_pass; +} + +StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt, + HashtableEntry* e_ptr, + StringTable::VerifyMesgModes mesg_mode) { + + VerifyRetTypes ret = _verify_pass; // be optimistic + + oop str = e_ptr->literal(); + if (str == NULL) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt, + e_cnt); + } + // NULL oop means no more verifications are possible + return _verify_fail_done; + } + + if (str->klass() != SystemDictionary::String_klass()) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]", + bkt, e_cnt); + } + // not a String means no more verifications are possible + return _verify_fail_done; + } + + unsigned int h = java_lang_String::hash_string(str); + if (e_ptr->hash() != h) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], " + "bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h); + } + ret = _verify_fail_continue; + } + + if (the_table()->hash_to_index(h) != bkt) { + if (mesg_mode == _verify_with_mesgs) { + tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], " + "str_hash=%d, hash_to_index=%d", bkt, e_cnt, h, + the_table()->hash_to_index(h)); + } + ret = _verify_fail_continue; + } + + return ret; +} + +// See StringTable::verify() above for the quick verification that is +// part of Universe::verify(). This verification is exhaustive and +// reports on every issue that is found. StringTable::verify() only +// reports on the first issue that is found. +// +// StringTable::verify_entry() checks: +// - oop value != NULL (same as verify()) +// - oop value is a String +// - hash(String) == hash in entry (same as verify()) +// - index for hash == index of entry (same as verify()) +// +// StringTable::compare_entries() checks: +// - oops are unique across all entries +// - String values are unique across all entries +// +int StringTable::verify_and_compare_entries() { + assert(StringTable_lock->is_locked(), "sanity check"); + + int fail_cnt = 0; + + // first, verify all the entries individually: + for (int bkt = 0; bkt < the_table()->table_size(); bkt++) { + HashtableEntry* e_ptr = the_table()->bucket(bkt); + for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) { + VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs); + if (ret != _verify_pass) { + fail_cnt++; + } + } + } + + // Optimization: if the above check did not find any failures, then + // the comparison loop below does not need to call verify_entry() + // before calling compare_entries(). If there were failures, then we + // have to call verify_entry() to see if the entry can be passed to + // compare_entries() safely. When we call verify_entry() in the loop + // below, we do so quietly to void duplicate messages and we don't + // increment fail_cnt because the failures have already been counted. + bool need_entry_verify = (fail_cnt != 0); + + // second, verify all entries relative to each other: + for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) { + HashtableEntry* e_ptr1 = the_table()->bucket(bkt1); + for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) { + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot use the current entry to compare against other entries + continue; + } + } + + for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) { + HashtableEntry* e_ptr2 = the_table()->bucket(bkt2); + int e_cnt2; + for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) { + if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) { + // skip the entries up to and including the one that + // we're comparing against + continue; + } + + if (need_entry_verify) { + VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2, + _verify_quietly); + if (ret == _verify_fail_done) { + // cannot compare against this entry + continue; + } + } + + // compare two entries, report and count any failures: + if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2) + != _verify_pass) { + fail_cnt++; + } + } + } + } + } + return fail_cnt; +} // Create a new table and using alternate hash code, populate the new table // with the existing strings. Set flag to use the alternate hash code afterwards. diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp index 7a0031c9ab4..dc7d0337a0e 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.hpp +++ b/hotspot/src/share/vm/classfile/symbolTable.hpp @@ -311,6 +311,26 @@ public: static void verify(); static void dump(outputStream* st); + enum VerifyMesgModes { + _verify_quietly = 0, + _verify_with_mesgs = 1 + }; + + enum VerifyRetTypes { + _verify_pass = 0, + _verify_fail_continue = 1, + _verify_fail_done = 2 + }; + + static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, + HashtableEntry* e_ptr1, + int bkt2, int e_cnt2, + HashtableEntry* e_ptr2); + static VerifyRetTypes verify_entry(int bkt, int e_cnt, + HashtableEntry* e_ptr, + VerifyMesgModes mesg_mode); + static int verify_and_compare_entries(); + // Sharing static void copy_buckets(char** top, char*end) { the_table()->Hashtable::copy_buckets(top, end); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 7fdf668bac5..bdee0be3c32 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2525,6 +2525,9 @@ class CommandLineFlags { product(bool, PrintStringTableStatistics, false, \ "print statistics about the StringTable and SymbolTable") \ \ + diagnostic(bool, VerifyStringTableAtExit, false, \ + "verify StringTable contents at exit") \ + \ notproduct(bool, PrintSymbolTableSizeHistogram, false, \ "print histogram of the symbol table") \ \ diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp index ebc4e087578..874765fa3e5 100644 --- a/hotspot/src/share/vm/runtime/java.cpp +++ b/hotspot/src/share/vm/runtime/java.cpp @@ -544,6 +544,19 @@ void before_exit(JavaThread * thread) { // it will run into trouble when system destroys static variables. MemTracker::shutdown(MemTracker::NMT_normal); + if (VerifyStringTableAtExit) { + int fail_cnt = 0; + { + MutexLocker ml(StringTable_lock); + fail_cnt = StringTable::verify_and_compare_entries(); + } + + if (fail_cnt != 0) { + tty->print_cr("ERROR: fail_cnt=%d", fail_cnt); + guarantee(fail_cnt == 0, "unexpected StringTable verification failures"); + } + } + #undef BEFORE_EXIT_NOT_RUN #undef BEFORE_EXIT_RUNNING #undef BEFORE_EXIT_DONE From f99391ee6f088383a785637b63dbce56fe3f6f5c Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Wed, 18 Sep 2013 14:10:21 -0700 Subject: [PATCH 125/293] 8023542: Test java/io/File/CheckPermission.java fails due to unfinished recursion (java.lang.StackOverflowError) when JIT'ed code (-client,-server) is running Move null check before klass reference materialization in checkcast Reviewed-by: kvn, roland --- hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 334d0cc92db..952e1adbc52 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -1724,14 +1724,6 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } assert_different_registers(obj, k_RInfo, klass_RInfo); - if (!k->is_loaded()) { - klass2reg_with_patching(k_RInfo, op->info_for_patch()); - } else { -#ifdef _LP64 - __ mov_metadata(k_RInfo, k->constant_encoding()); -#endif // _LP64 - } - assert(obj != k_RInfo, "must be different"); __ cmpptr(obj, (int32_t)NULL_WORD); if (op->should_profile()) { @@ -1748,6 +1740,14 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L } else { __ jcc(Assembler::equal, *obj_is_null); } + + if (!k->is_loaded()) { + klass2reg_with_patching(k_RInfo, op->info_for_patch()); + } else { +#ifdef _LP64 + __ mov_metadata(k_RInfo, k->constant_encoding()); +#endif // _LP64 + } __ verify_oop(obj); if (op->fast_check()) { From 82705bda51b399bf0901d948fd5846d30107718d Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Wed, 18 Sep 2013 20:08:00 -0400 Subject: [PATCH 126/293] 8024826: (s) : Remove alt-rt.jar, used by +AggressiveOps Reviewed-by: alanb, chegar, dholmes, ksrini --- hotspot/src/share/vm/runtime/arguments.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index ef4da6da740..78b8338265d 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -2409,21 +2409,6 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) { return result; } - if (AggressiveOpts) { - // Insert alt-rt.jar between user-specified bootclasspath - // prefix and the default bootclasspath. os::set_boot_path() - // uses meta_index_dir as the default bootclasspath directory. - const char* altclasses_jar = "alt-rt.jar"; - size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 + - strlen(altclasses_jar); - char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len, mtInternal); - strcpy(altclasses_path, get_meta_index_dir()); - strcat(altclasses_path, altclasses_jar); - scp.add_suffix_to_prefix(altclasses_path); - scp_assembly_required = true; - FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal); - } - // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) result = parse_java_options_environment_variable(&scp, &scp_assembly_required); if (result != JNI_OK) { From 484e378a9d7a1c3a3c6dd4c8b1e2ddc0b4c1e884 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 18 Sep 2013 17:13:26 -0700 Subject: [PATCH 127/293] 8015249: javadoc fails to document static final fields in annotation types Reviewed-by: jjg --- .../html/AnnotationTypeFieldWriterImpl.java | 301 ++++++++++++++++++ ...nnotationTypeRequiredMemberWriterImpl.java | 14 + .../html/AnnotationTypeWriterImpl.java | 24 +- .../formats/html/HtmlDocletWriter.java | 5 + .../formats/html/WriterFactoryImpl.java | 13 + .../formats/html/markup/HtmlConstants.java | 12 + .../toolkit/AnnotationTypeFieldWriter.java | 132 ++++++++ .../AnnotationTypeRequiredMemberWriter.java | 16 +- .../toolkit/AnnotationTypeWriter.java | 9 +- .../internal/toolkit/WriterFactory.java | 12 + .../builders/AnnotationTypeBuilder.java | 17 +- .../builders/AnnotationTypeFieldBuilder.java | 240 ++++++++++++++ .../AnnotationTypeRequiredMemberBuilder.java | 13 +- .../toolkit/builders/BuilderFactory.java | 20 +- .../builders/MemberSummaryBuilder.java | 14 + .../internal/toolkit/resources/doclet.xml | 9 + .../toolkit/util/VisibleMemberMap.java | 12 +- .../TestAnnotationTypes.java | 35 +- .../pkg/AnnotationTypeField.java | 35 ++ .../TestNewLanguageFeatures.java | 4 +- 20 files changed, 897 insertions(+), 40 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java create mode 100644 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java create mode 100644 langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java new file mode 100644 index 00000000000..f4c7c68f565 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeFieldWriterImpl.java @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclets.formats.html; + +import java.io.*; + +import com.sun.javadoc.*; +import com.sun.tools.doclets.formats.html.markup.*; +import com.sun.tools.doclets.internal.toolkit.*; + +/** + * Writes annotation type field documentation in HTML format. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * @author Bhavesh Patel + */ +public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter + implements AnnotationTypeFieldWriter, MemberSummaryWriter { + + /** + * Construct a new AnnotationTypeFieldWriterImpl. + * + * @param writer the writer that will write the output. + * @param annotationType the AnnotationType that holds this member. + */ + public AnnotationTypeFieldWriterImpl(SubWriterHolderWriter writer, + AnnotationTypeDoc annotationType) { + super(writer, annotationType); + } + + /** + * {@inheritDoc} + */ + public Content getMemberSummaryHeader(ClassDoc classDoc, + Content memberSummaryTree) { + memberSummaryTree.addContent( + HtmlConstants.START_OF_ANNOTATION_TYPE_FIELD_SUMMARY); + Content memberTree = writer.getMemberTreeHeader(); + writer.addSummaryHeader(this, classDoc, memberTree); + return memberTree; + } + + /** + * {@inheritDoc} + */ + public Content getMemberTreeHeader() { + return writer.getMemberTreeHeader(); + } + + /** + * {@inheritDoc} + */ + public void addAnnotationFieldDetailsMarker(Content memberDetails) { + memberDetails.addContent(HtmlConstants.START_OF_ANNOTATION_TYPE_FIELD_DETAILS); + } + + /** + * {@inheritDoc} + */ + public void addAnnotationDetailsTreeHeader(ClassDoc classDoc, + Content memberDetailsTree) { + if (!writer.printedAnnotationFieldHeading) { + memberDetailsTree.addContent(writer.getMarkerAnchor( + "annotation_type_field_detail")); + Content heading = HtmlTree.HEADING(HtmlConstants.DETAILS_HEADING, + writer.fieldDetailsLabel); + memberDetailsTree.addContent(heading); + writer.printedAnnotationFieldHeading = true; + } + } + + /** + * {@inheritDoc} + */ + public Content getAnnotationDocTreeHeader(MemberDoc member, + Content annotationDetailsTree) { + annotationDetailsTree.addContent( + writer.getMarkerAnchor(member.name())); + Content annotationDocTree = writer.getMemberTreeHeader(); + Content heading = new HtmlTree(HtmlConstants.MEMBER_HEADING); + heading.addContent(member.name()); + annotationDocTree.addContent(heading); + return annotationDocTree; + } + + /** + * {@inheritDoc} + */ + public Content getSignature(MemberDoc member) { + Content pre = new HtmlTree(HtmlTag.PRE); + writer.addAnnotationInfo(member, pre); + addModifiers(member, pre); + Content link = + writer.getLink(new LinkInfoImpl(configuration, + LinkInfoImpl.Kind.MEMBER, getType(member))); + pre.addContent(link); + pre.addContent(writer.getSpace()); + if (configuration.linksource) { + Content memberName = new StringContent(member.name()); + writer.addSrcLink(member, memberName, pre); + } else { + addName(member.name(), pre); + } + return pre; + } + + /** + * {@inheritDoc} + */ + public void addDeprecated(MemberDoc member, Content annotationDocTree) { + addDeprecatedInfo(member, annotationDocTree); + } + + /** + * {@inheritDoc} + */ + public void addComments(MemberDoc member, Content annotationDocTree) { + addComment(member, annotationDocTree); + } + + /** + * {@inheritDoc} + */ + public void addTags(MemberDoc member, Content annotationDocTree) { + writer.addTagsInfo(member, annotationDocTree); + } + + /** + * {@inheritDoc} + */ + public Content getAnnotationDetails(Content annotationDetailsTree) { + return getMemberTree(annotationDetailsTree); + } + + /** + * {@inheritDoc} + */ + public Content getAnnotationDoc(Content annotationDocTree, + boolean isLastContent) { + return getMemberTree(annotationDocTree, isLastContent); + } + + /** + * Close the writer. + */ + public void close() throws IOException { + writer.close(); + } + + /** + * {@inheritDoc} + */ + public void addSummaryLabel(Content memberTree) { + Content label = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, + writer.getResource("doclet.Field_Summary")); + memberTree.addContent(label); + } + + /** + * {@inheritDoc} + */ + public String getTableSummary() { + return configuration.getText("doclet.Member_Table_Summary", + configuration.getText("doclet.Field_Summary"), + configuration.getText("doclet.fields")); + } + + /** + * {@inheritDoc} + */ + public Content getCaption() { + return configuration.getResource("doclet.Fields"); + } + + /** + * {@inheritDoc} + */ + public String[] getSummaryTableHeader(ProgramElementDoc member) { + String[] header = new String[] { + writer.getModifierTypeHeader(), + configuration.getText("doclet.0_and_1", + configuration.getText("doclet.Fields"), + configuration.getText("doclet.Description")) + }; + return header; + } + + /** + * {@inheritDoc} + */ + public void addSummaryAnchor(ClassDoc cd, Content memberTree) { + memberTree.addContent(writer.getMarkerAnchor( + "annotation_type_field_summary")); + } + + /** + * {@inheritDoc} + */ + public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) { + } + + /** + * {@inheritDoc} + */ + public void addInheritedSummaryLabel(ClassDoc cd, Content inheritedTree) { + } + + /** + * {@inheritDoc} + */ + protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member, + Content tdSummary) { + Content strong = HtmlTree.SPAN(HtmlStyle.strong, + writer.getDocLink(context, (MemberDoc) member, member.name(), false)); + Content code = HtmlTree.CODE(strong); + tdSummary.addContent(code); + } + + /** + * {@inheritDoc} + */ + protected void addInheritedSummaryLink(ClassDoc cd, + ProgramElementDoc member, Content linksTree) { + //Not applicable. + } + + /** + * {@inheritDoc} + */ + protected void addSummaryType(ProgramElementDoc member, Content tdSummaryType) { + MemberDoc m = (MemberDoc)member; + addModifierAndType(m, getType(m), tdSummaryType); + } + + /** + * {@inheritDoc} + */ + protected Content getDeprecatedLink(ProgramElementDoc member) { + return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, + (MemberDoc) member, ((MemberDoc)member).qualifiedName()); + } + + /** + * {@inheritDoc} + */ + protected Content getNavSummaryLink(ClassDoc cd, boolean link) { + if (link) { + return writer.getHyperLink("annotation_type_field_summary", + writer.getResource("doclet.navField")); + } else { + return writer.getResource("doclet.navField"); + } + } + + /** + * {@inheritDoc} + */ + protected void addNavDetailLink(boolean link, Content liNav) { + if (link) { + liNav.addContent(writer.getHyperLink("annotation_type_field_detail", + writer.getResource("doclet.navField"))); + } else { + liNav.addContent(writer.getResource("doclet.navField")); + } + } + + private Type getType(MemberDoc member) { + if (member instanceof FieldDoc) { + return ((FieldDoc) member).type(); + } else { + return ((MethodDoc) member).returnType(); + } + } +} diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java index a2fa33b68a5..1833d262db3 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java @@ -68,6 +68,20 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter return memberTree; } + /** + * {@inheritDoc} + */ + public Content getMemberTreeHeader() { + return writer.getMemberTreeHeader(); + } + + /** + * {@inheritDoc} + */ + public void addAnnotationDetailsMarker(Content memberDetails) { + memberDetails.addContent(HtmlConstants.START_OF_ANNOTATION_TYPE_DETAILS); + } + /** * {@inheritDoc} */ diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java index c1c4c9d40e6..c90ae08c27e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java @@ -275,13 +275,6 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter } } - /** - * {@inheritDoc} - */ - public void addAnnotationDetailsMarker(Content memberDetails) { - memberDetails.addContent(HtmlConstants.START_OF_ANNOTATION_TYPE_DETAILS); - } - /** * {@inheritDoc} */ @@ -319,6 +312,12 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) configuration.getBuilderFactory().getMemberSummaryBuilder(this); + Content liNavField = new HtmlTree(HtmlTag.LI); + addNavSummaryLink(memberSummaryBuilder, + "doclet.navField", + VisibleMemberMap.ANNOTATION_TYPE_FIELDS, liNavField); + addNavGap(liNavField); + ulNav.addContent(liNavField); Content liNavReq = new HtmlTree(HtmlTag.LI); addNavSummaryLink(memberSummaryBuilder, "doclet.navAnnotationTypeRequiredMember", @@ -364,12 +363,23 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) configuration.getBuilderFactory().getMemberSummaryBuilder(this); + AbstractMemberWriter writerField = + ((AbstractMemberWriter) memberSummaryBuilder. + getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_FIELDS)); AbstractMemberWriter writerOptional = ((AbstractMemberWriter) memberSummaryBuilder. getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL)); AbstractMemberWriter writerRequired = ((AbstractMemberWriter) memberSummaryBuilder. getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED)); + Content liNavField = new HtmlTree(HtmlTag.LI); + if (writerField != null){ + writerField.addNavDetailLink(annotationType.fields().length > 0, liNavField); + } else { + liNavField.addContent(getResource("doclet.navField")); + } + addNavGap(liNavField); + ulNav.addContent(liNavField); if (writerOptional != null){ Content liNavOpt = new HtmlTree(HtmlTag.LI); writerOptional.addNavDetailLink(annotationType.elements().length > 0, liNavOpt); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java index da36fedcff0..b3bfdcb1c3c 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java @@ -84,6 +84,11 @@ public class HtmlDocletWriter extends HtmlDocWriter { */ protected boolean printedAnnotationHeading = false; + /** + * To check whether annotation field heading is printed or not. + */ + protected boolean printedAnnotationFieldHeading = false; + /** * To check whether the repeated annotations is documented or not. */ diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java index b8a1775c7be..70bace904ab 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java @@ -104,6 +104,16 @@ public class WriterFactoryImpl implements WriterFactory { annotationType, prevType, nextType); } + /** + * {@inheritDoc} + */ + public AnnotationTypeFieldWriter + getAnnotationTypeFieldWriter(AnnotationTypeWriter annotationTypeWriter) throws Exception { + return new AnnotationTypeFieldWriterImpl( + (SubWriterHolderWriter) annotationTypeWriter, + annotationTypeWriter.getAnnotationTypeDoc()); + } + /** * {@inheritDoc} */ @@ -202,6 +212,9 @@ public class WriterFactoryImpl implements WriterFactory { AnnotationTypeWriter annotationTypeWriter, int memberType) throws Exception { switch (memberType) { + case VisibleMemberMap.ANNOTATION_TYPE_FIELDS: + return (AnnotationTypeFieldWriterImpl) + getAnnotationTypeFieldWriter(annotationTypeWriter); case VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL: return (AnnotationTypeOptionalMemberWriterImpl) getAnnotationTypeOptionalMemberWriter(annotationTypeWriter); diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java index 7c32503e625..98651468f95 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlConstants.java @@ -93,6 +93,12 @@ public class HtmlConstants { public static final Content START_OF_ANNOTATION_TYPE_REQUIRED_MEMBER_SUMMARY = new Comment("=========== ANNOTATION TYPE REQUIRED MEMBER SUMMARY ==========="); + /** + * Marker to identify start of annotation type required member summary. + */ + public static final Content START_OF_ANNOTATION_TYPE_FIELD_SUMMARY = + new Comment("=========== ANNOTATION TYPE FIELD SUMMARY ==========="); + /** * Marker to identify start of constructor summary. */ @@ -129,6 +135,12 @@ public class HtmlConstants { public static final Content START_OF_ANNOTATION_TYPE_DETAILS = new Comment("============ ANNOTATION TYPE MEMBER DETAIL ==========="); + /** + * Marker to identify start of annotation type field details. + */ + public static final Content START_OF_ANNOTATION_TYPE_FIELD_DETAILS = + new Comment("============ ANNOTATION TYPE FIELD DETAIL ==========="); + /** * Marker to identify start of method details. */ diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java new file mode 100644 index 00000000000..b556ccc7c86 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeFieldWriter.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclets.internal.toolkit; + +import java.io.*; +import com.sun.javadoc.*; + +/** + * The interface for writing annotation type field output. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * + * @author Bhavesh Patel + * @since 1.8 + */ + +public interface AnnotationTypeFieldWriter { + + /** + * Add the annotation type member tree header. + * + * @return content tree for the member tree header + */ + public Content getMemberTreeHeader(); + + /** + * Add the annotation type field details marker. + * + * @param memberDetails the content tree representing field details marker + */ + public void addAnnotationFieldDetailsMarker(Content memberDetails); + + /** + * Add the annotation type details tree header. + * + * @param classDoc the annotation type being documented + * @param memberDetailsTree the content tree representing member details + */ + public void addAnnotationDetailsTreeHeader(ClassDoc classDoc, + Content memberDetailsTree); + + /** + * Get the annotation type documentation tree header. + * + * @param member the annotation type being documented + * @param annotationDetailsTree the content tree representing annotation type details + * @return content tree for the annotation type documentation header + */ + public Content getAnnotationDocTreeHeader(MemberDoc member, + Content annotationDetailsTree); + + /** + * Get the annotation type details tree. + * + * @param annotationDetailsTree the content tree representing annotation type details + * @return content tree for the annotation type details + */ + public Content getAnnotationDetails(Content annotationDetailsTree); + + /** + * Get the annotation type documentation. + * + * @param annotationDocTree the content tree representing annotation type documentation + * @param isLastContent true if the content to be added is the last content + * @return content tree for the annotation type documentation + */ + public Content getAnnotationDoc(Content annotationDocTree, boolean isLastContent); + + /** + * Get the signature for the given member. + * + * @param member the member being documented + * @return content tree for the annotation type signature + */ + public Content getSignature(MemberDoc member); + + /** + * Add the deprecated output for the given member. + * + * @param member the member being documented + * @param annotationDocTree content tree to which the deprecated information will be added + */ + public void addDeprecated(MemberDoc member, Content annotationDocTree); + + /** + * Add the comments for the given member. + * + * @param member the member being documented + * @param annotationDocTree the content tree to which the comments will be added + */ + public void addComments(MemberDoc member, Content annotationDocTree); + + /** + * Add the tags for the given member. + * + * @param member the member being documented + * @param annotationDocTree the content tree to which the tags will be added + */ + public void addTags(MemberDoc member, Content annotationDocTree); + + /** + * Close the writer. + */ + public void close() throws IOException; +} diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java index 28a18f9eaad..294d3217195 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeRequiredMemberWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,20 @@ import com.sun.javadoc.*; public interface AnnotationTypeRequiredMemberWriter { + /** + * Add the annotation type member tree header. + * + * @return content tree for the member tree header + */ + public Content getMemberTreeHeader(); + + /** + * Add the annotation type details marker. + * + * @param memberDetails the content tree representing details marker + */ + public void addAnnotationDetailsMarker(Content memberDetails); + /** * Add the annotation type details tree header. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java index b65740edf87..c11dfd8527e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AnnotationTypeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,13 +103,6 @@ public interface AnnotationTypeWriter { */ public void addAnnotationTypeDeprecationInfo (Content annotationInfoTree); - /** - * Add the annotation type details marker. - * - * @param memberDetails the content tree representing member details marker - */ - public void addAnnotationDetailsMarker(Content memberDetails); - /** * Get the member tree header for the annotation type. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java index 1fa4c2f00e9..985fb646647 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/WriterFactory.java @@ -129,6 +129,18 @@ public interface WriterFactory { public abstract MethodWriter getMethodWriter(ClassWriter classWriter) throws Exception; + /** + * Return the annotation type field writer for a given annotation type. + * + * @param annotationTypeWriter the writer for the annotation type + * being documented. + * @return the member writer for the given annotation type. Return null if + * this writer is not supported by the doclet. + */ + public abstract AnnotationTypeFieldWriter + getAnnotationTypeFieldWriter( + AnnotationTypeWriter annotationTypeWriter) throws Exception; + /** * Return the annotation type optional member writer for a given annotation * type. diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java index 4de54026794..ae1de88d587 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java @@ -223,13 +223,22 @@ public class AnnotationTypeBuilder extends AbstractBuilder { Content memberDetailsTree = writer.getMemberTreeHeader(); buildChildren(node, memberDetailsTree); if (memberDetailsTree.isValid()) { - Content memberDetails = writer.getMemberTreeHeader(); - writer.addAnnotationDetailsMarker(memberDetails); - memberDetails.addContent(writer.getMemberTree(memberDetailsTree)); - annotationContentTree.addContent(writer.getMemberDetailsTree(memberDetails)); + annotationContentTree.addContent(writer.getMemberDetailsTree(memberDetailsTree)); } } + /** + * Build the annotation type field documentation. + * + * @param node the XML element that specifies which components to document + * @param memberDetailsTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeFieldDetails(XMLNode node, Content memberDetailsTree) + throws Exception { + configuration.getBuilderFactory(). + getAnnotationTypeFieldsBuilder(writer).buildChildren(node, memberDetailsTree); + } + /** * Build the annotation type optional member documentation. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java new file mode 100644 index 00000000000..4cbd4a20213 --- /dev/null +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeFieldBuilder.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.doclets.internal.toolkit.builders; + +import java.util.*; + +import com.sun.javadoc.*; +import com.sun.tools.doclets.internal.toolkit.*; +import com.sun.tools.doclets.internal.toolkit.util.*; + +/** + * Builds documentation for annotation type fields. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + * + * @author Bhavesh Patel + * @since 1.8 + */ +public class AnnotationTypeFieldBuilder extends AbstractMemberBuilder { + + /** + * The annotation type whose members are being documented. + */ + protected ClassDoc classDoc; + + /** + * The visible members for the given class. + */ + protected VisibleMemberMap visibleMemberMap; + + /** + * The writer to output the member documentation. + */ + protected AnnotationTypeFieldWriter writer; + + /** + * The list of members being documented. + */ + protected List members; + + /** + * The index of the current member that is being documented at this point + * in time. + */ + protected int currentMemberIndex; + + /** + * Construct a new AnnotationTypeFieldsBuilder. + * + * @param context the build context. + * @param classDoc the class whose members are being documented. + * @param writer the doclet specific writer. + * @param memberType the type of member that is being documented. + */ + protected AnnotationTypeFieldBuilder(Context context, + ClassDoc classDoc, + AnnotationTypeFieldWriter writer, + int memberType) { + super(context); + this.classDoc = classDoc; + this.writer = writer; + this.visibleMemberMap = new VisibleMemberMap(classDoc, memberType, + configuration); + this.members = new ArrayList( + this.visibleMemberMap.getMembersFor(classDoc)); + if (configuration.getMemberComparator() != null) { + Collections.sort(this.members, configuration.getMemberComparator()); + } + } + + + /** + * Construct a new AnnotationTypeFieldBuilder. + * + * @param context the build context. + * @param classDoc the class whose members are being documented. + * @param writer the doclet specific writer. + */ + public static AnnotationTypeFieldBuilder getInstance( + Context context, ClassDoc classDoc, + AnnotationTypeFieldWriter writer) { + return new AnnotationTypeFieldBuilder(context, classDoc, + writer, VisibleMemberMap.ANNOTATION_TYPE_FIELDS); + } + + /** + * {@inheritDoc} + */ + public String getName() { + return "AnnotationTypeFieldDetails"; + } + + /** + * Returns a list of members that will be documented for the given class. + * This information can be used for doclet specific documentation + * generation. + * + * @param classDoc the {@link ClassDoc} we want to check. + * @return a list of members that will be documented. + */ + public List members(ClassDoc classDoc) { + return visibleMemberMap.getMembersFor(classDoc); + } + + /** + * Returns the visible member map for the members of this class. + * + * @return the visible member map for the members of this class. + */ + public VisibleMemberMap getVisibleMemberMap() { + return visibleMemberMap; + } + + /** + * summaryOrder.size() + */ + public boolean hasMembersToDocument() { + return members.size() > 0; + } + + /** + * Build the annotation type field documentation. + * + * @param node the XML element that specifies which components to document + * @param memberDetailsTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeField(XMLNode node, Content memberDetailsTree) { + buildAnnotationTypeMember(node, memberDetailsTree); + } + + /** + * Build the member documentation. + * + * @param node the XML element that specifies which components to document + * @param memberDetailsTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeMember(XMLNode node, Content memberDetailsTree) { + if (writer == null) { + return; + } + int size = members.size(); + if (size > 0) { + writer.addAnnotationFieldDetailsMarker(memberDetailsTree); + for (currentMemberIndex = 0; currentMemberIndex < size; + currentMemberIndex++) { + Content detailsTree = writer.getMemberTreeHeader(); + writer.addAnnotationDetailsTreeHeader(classDoc, detailsTree); + Content annotationDocTree = writer.getAnnotationDocTreeHeader( + (MemberDoc) members.get(currentMemberIndex), + detailsTree); + buildChildren(node, annotationDocTree); + detailsTree.addContent(writer.getAnnotationDoc( + annotationDocTree, (currentMemberIndex == size - 1))); + memberDetailsTree.addContent(writer.getAnnotationDetails(detailsTree)); + } + } + } + + /** + * Build the signature. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildSignature(XMLNode node, Content annotationDocTree) { + annotationDocTree.addContent( + writer.getSignature((MemberDoc) members.get(currentMemberIndex))); + } + + /** + * Build the deprecation information. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildDeprecationInfo(XMLNode node, Content annotationDocTree) { + writer.addDeprecated((MemberDoc) members.get(currentMemberIndex), + annotationDocTree); + } + + /** + * Build the comments for the member. Do nothing if + * {@link Configuration#nocomment} is set to true. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildMemberComments(XMLNode node, Content annotationDocTree) { + if(! configuration.nocomment){ + writer.addComments((MemberDoc) members.get(currentMemberIndex), + annotationDocTree); + } + } + + /** + * Build the tag information. + * + * @param node the XML element that specifies which components to document + * @param annotationDocTree the content tree to which the documentation will be added + */ + public void buildTagInfo(XMLNode node, Content annotationDocTree) { + writer.addTags((MemberDoc) members.get(currentMemberIndex), + annotationDocTree); + } + + /** + * Return the annotation type field writer for this builder. + * + * @return the annotation type field writer for this builder. + */ + public AnnotationTypeFieldWriter getWriter() { + return writer; + } +} diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java index 84ded901668..29ad9df370d 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java @@ -167,16 +167,17 @@ public class AnnotationTypeRequiredMemberBuilder extends AbstractMemberBuilder { } int size = members.size(); if (size > 0) { - writer.addAnnotationDetailsTreeHeader( - classDoc, memberDetailsTree); + writer.addAnnotationDetailsMarker(memberDetailsTree); for (currentMemberIndex = 0; currentMemberIndex < size; - currentMemberIndex++) { + currentMemberIndex++) { + Content detailsTree = writer.getMemberTreeHeader(); + writer.addAnnotationDetailsTreeHeader(classDoc, detailsTree); Content annotationDocTree = writer.getAnnotationDocTreeHeader( - (MemberDoc) members.get(currentMemberIndex), - memberDetailsTree); + (MemberDoc) members.get(currentMemberIndex), detailsTree); buildChildren(node, annotationDocTree); - memberDetailsTree.addContent(writer.getAnnotationDoc( + detailsTree.addContent(writer.getAnnotationDoc( annotationDocTree, (currentMemberIndex == size - 1))); + memberDetailsTree.addContent(writer.getAnnotationDetails(detailsTree)); } } } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java index 7152f2bd4f2..3509a06eac9 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java @@ -173,11 +173,27 @@ public class BuilderFactory { writerFactory.getMethodWriter(classWriter)); } + /** + * Return an instance of the annotation type fields builder for the given + * class. + * + * @return an instance of the annotation type field builder for the given + * annotation type. + */ + public AbstractBuilder getAnnotationTypeFieldsBuilder( + AnnotationTypeWriter annotationTypeWriter) + throws Exception { + return AnnotationTypeFieldBuilder.getInstance(context, + annotationTypeWriter.getAnnotationTypeDoc(), + writerFactory.getAnnotationTypeFieldWriter( + annotationTypeWriter)); + } + /** * Return an instance of the annotation type member builder for the given * class. * - * @return an instance of the annotation type memebr builder for the given + * @return an instance of the annotation type member builder for the given * annotation type. */ public AbstractBuilder getAnnotationTypeOptionalMemberBuilder( @@ -193,7 +209,7 @@ public class BuilderFactory { * Return an instance of the annotation type member builder for the given * class. * - * @return an instance of the annotation type memebr builder for the given + * @return an instance of the annotation type member builder for the given * annotation type. */ public AbstractBuilder getAnnotationTypeRequiredMemberBuilder( diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java index 8edb5dd2bad..fb4f14c8253 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java @@ -212,6 +212,20 @@ public class MemberSummaryBuilder extends AbstractMemberBuilder { addSummary(writer, visibleMemberMap, false, memberSummaryTree); } + /** + * Build the summary for fields. + * + * @param node the XML element that specifies which components to document + * @param memberSummaryTree the content tree to which the documentation will be added + */ + public void buildAnnotationTypeFieldsSummary(XMLNode node, Content memberSummaryTree) { + MemberSummaryWriter writer = + memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_FIELDS]; + VisibleMemberMap visibleMemberMap = + visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_FIELDS]; + addSummary(writer, visibleMemberMap, false, memberSummaryTree); + } + /** * Build the summary for the optional members. * diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml index aabaafff250..f7f2f9c7458 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclet.xml @@ -66,10 +66,19 @@ + + + + + + + + + diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java index 6c9870405f3..15d41773b4e 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java @@ -55,14 +55,15 @@ public class VisibleMemberMap { public static final int FIELDS = 2; public static final int CONSTRUCTORS = 3; public static final int METHODS = 4; - public static final int ANNOTATION_TYPE_MEMBER_OPTIONAL = 5; - public static final int ANNOTATION_TYPE_MEMBER_REQUIRED = 6; - public static final int PROPERTIES = 7; + public static final int ANNOTATION_TYPE_FIELDS = 5; + public static final int ANNOTATION_TYPE_MEMBER_OPTIONAL = 6; + public static final int ANNOTATION_TYPE_MEMBER_REQUIRED = 7; + public static final int PROPERTIES = 8; /** * The total number of member types is {@value}. */ - public static final int NUM_MEMBER_TYPES = 8; + public static final int NUM_MEMBER_TYPES = 9; public static final String STARTLEVEL = "start"; @@ -433,6 +434,9 @@ public class VisibleMemberMap { } ProgramElementDoc[] members = null; switch (kind) { + case ANNOTATION_TYPE_FIELDS: + members = cd.fields(filter); + break; case ANNOTATION_TYPE_MEMBER_OPTIONAL: members = cd.isAnnotationType() ? filter((AnnotationTypeDoc) cd, false) : diff --git a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java index 65a8e5d7cfa..5ffdbab12b2 100644 --- a/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java +++ b/langtools/test/com/sun/javadoc/testAnnotationTypes/TestAnnotationTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,20 +23,19 @@ /* * @test - * @bug 4973609 + * @bug 4973609 8015249 * @summary Make sure that annotation types with 0 members does not have * extra HR tags. * @author jamieh * @library ../lib/ - * @build JavadocTester - * @build TestAnnotationTypes + * @build JavadocTester TestAnnotationTypes * @run main TestAnnotationTypes */ public class TestAnnotationTypes extends JavadocTester { //Test information. - private static final String BUG_ID = "4973609"; + private static final String BUG_ID = "4973609-8015249"; //Javadoc arguments. private static final String[] ARGS = new String[] { @@ -44,7 +43,31 @@ public class TestAnnotationTypes extends JavadocTester { }; //Input for string search tests. - private static final String[][] TEST = NO_TEST; + private static final String[][] TEST = { + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "

  • Summary: 
  • " + NL + "
  • Field | 
  • "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "
  • Detail: 
  • " + NL + "
  • Field | 
  • "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + ""}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "

    Field Summary

    "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "DEFAULT_NAME" + + " "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + ""}, + {BUG_ID + FS + "pkg" + FS + "AnnotationTypeField.html", + "

    DEFAULT_NAME

    " + NL + "
    public static final java." +
    +            "lang.String DEFAULT_NAME
    "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + "
  • Summary: 
  • " + NL + "
  • Field | 
  • "}, + {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", + "
  • Detail: 
  • " + NL + "
  • Field | 
  • "}, + }; private static final String[][] NEGATED_TEST = { {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", "
    " + NL + NL + "

    " + NL + NL + "

    " + diff --git a/langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java b/langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java new file mode 100644 index 00000000000..1dabafcc8db --- /dev/null +++ b/langtools/test/com/sun/javadoc/testAnnotationTypes/pkg/AnnotationTypeField.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +import java.lang.annotation.*; + +/** + * This is just a test for annotation type fields. + */ +@Documented public @interface AnnotationTypeField { + String DEFAULT_NAME = "test"; + + String name() default DEFAULT_NAME; +} diff --git a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java index e16fd5450f2..ad0e024bfe6 100644 --- a/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/langtools/test/com/sun/javadoc/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -155,13 +155,13 @@ public class TestNewLanguageFeatures extends JavadocTester { //================================= //Make sure the summary links are correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "

  • Summary: 
  • " + NL + + "
  • Summary: 
  • " + NL + "
  • Field | 
  • " + NL + "
  • " + "Required | 
  • " + NL + "
  • " + "Optional
  • "}, //Make sure the detail links are correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", - "
  • Detail: 
  • " + NL + + "
  • Detail: 
  • " + NL + "
  • Field | 
  • " + NL + "
  • Element
  • "}, //Make sure the heading is correct. {BUG_ID + FS + "pkg" + FS + "AnnotationType.html", From 2be05076f8f9f4c589730cd174f85e656fcca7fb Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 18 Sep 2013 22:47:06 -0700 Subject: [PATCH 128/293] 8024096: some javadoc tests may contain false positive results Reviewed-by: jjg --- .../com/sun/javadoc/lib/JavadocTester.java | 77 ++++++++++++++++++- .../testDocFileDir/TestDocFileDir.java | 30 +++----- .../sun/javadoc/testEncoding/EncodeTest.java | 6 +- .../javadoc/testEncoding/TestEncoding.java | 8 +- .../testMethodTypes/TestMethodTypes.java | 6 +- .../javadoc/testProfiles/TestProfiles.java | 31 +++----- 6 files changed, 104 insertions(+), 54 deletions(-) diff --git a/langtools/test/com/sun/javadoc/lib/JavadocTester.java b/langtools/test/com/sun/javadoc/lib/JavadocTester.java index 23b8c80482e..e5af454fee8 100644 --- a/langtools/test/com/sun/javadoc/lib/JavadocTester.java +++ b/langtools/test/com/sun/javadoc/lib/JavadocTester.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,7 @@ public abstract class JavadocTester { protected static final String SRC_DIR = System.getProperty("test.src", "."); protected static final String JAVA_VERSION = System.getProperty("java.version"); protected static final String[][] NO_TEST = new String[][] {}; + protected static final String[] NO_FILE_TEST = new String[] {}; /** * Use this as the file name in the test array when you want to search @@ -165,6 +166,26 @@ public abstract class JavadocTester { return returnCode; } + /** + * Execute the tests. + * + * @param tester the tester to execute + * @param args the arguments to pass to Javadoc + * @param testArray the array of tests + * @param negatedTestArray the array of negated tests + * @param fileTestArray the array of file tests + * @param negatedFileTestArray the array of negated file tests + * @return the return code for the execution of Javadoc + */ + public static int run(JavadocTester tester, String[] args, + String[][] testArray, String[][] negatedTestArray, String[] fileTestArray, + String[] negatedFileTestArray) { + int returnCode = tester.runJavadoc(args); + tester.runTestsOnHTML(testArray, negatedTestArray); + tester.runTestsOnFile(fileTestArray, negatedFileTestArray); + return returnCode; + } + /** * Execute Javadoc using the default doclet. * @@ -243,6 +264,19 @@ public abstract class JavadocTester { runTestsOnHTML(negatedTestArray, true); } + /** + * Run array of tests on the generated files. + * This method accepts a fileTestArray for testing if a file is generated + * and a negatedFileTestArray for testing if a file is not found. + * + * @param testArray the array of file tests + * @param negatedTestArray the array of negated file tests + */ + public void runTestsOnFile(String[] fileTestArray, String[] negatedFileTestArray) { + runTestsOnFile(fileTestArray, false); + runTestsOnFile(negatedFileTestArray, true); + } + /** * Run the array of tests on the resulting HTML. * @@ -265,9 +299,11 @@ public abstract class JavadocTester { fileString = readFileToString(testArray[i][0]); } catch (Error e) { if (isNegated) { - numTestsPassed += 1; - System.out.println("Passed\n not found:\n" - + stringToFind + " in non-existent " + testArray[i][0] + "\n"); + System.out.println( "FAILED" + "\n" + + "for bug " + getBugId() + + " (" + getBugName() + ") " + + "due to " + + e + "\n"); continue; } throw e; @@ -290,6 +326,39 @@ public abstract class JavadocTester { } } + /** + * Run the array of file tests on the generated files. + * + * @param testArray the array of file tests + * @param isNegated true if test is negated; false otherwise + */ + private void runTestsOnFile(String[] testArray, boolean isNegated) { + String fileName; + String failedString; + String passedString; + for (int i = 0; i < testArray.length; i++) { + numTestsRun++; + fileName = testArray[i]; + failedString = "FAILED" + "\n" + + "for bug " + getBugId() + " (" + getBugName() + ") " + + "file (" + fileName + ") found" + "\n"; + passedString = "Passed" + "\n" + + "file (" + fileName + ") not found" + "\n"; + System.out.print("Running subtest #" + numTestsRun + "... "); + try { + File file = new File(fileName); + if ((file.exists() && !isNegated) || (!file.exists() && isNegated)) { + numTestsPassed += 1; + System.out.println(passedString); + } else { + System.out.println(failedString); + } + } catch (Error e) { + System.err.println(e); + } + } + } + /** * Iterate through the list of given file pairs and diff each file. * diff --git a/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java b/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java index c5dd3468443..1d1be4e5e02 100644 --- a/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java +++ b/langtools/test/com/sun/javadoc/testDocFileDir/TestDocFileDir.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ import java.io.File; /* * @test - * @bug 4258405 4973606 + * @bug 4258405 4973606 8024096 * @summary This test verifies that the doc-file directory does not * get overwritten when the sourcepath is equal to the destination * directory. @@ -47,25 +47,17 @@ public class TestDocFileDir extends JavadocTester { }; private static final String[][] NEGATED_TEST1 = NO_TEST; - private static final String[][] TEST2 = { - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used1" + + private static final String[] FILE_TEST2 = { + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used1" + FS + "testfile.txt", - "passed" - }, - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used2" + - FS + "testfile.txt", - "passed" - }, + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-used2" + + FS + "testfile.txt" }; - private static final String[][] NEGATED_TEST2 = { - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded1" + + private static final String[] FILE_NEGATED_TEST2 = { + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded1" + FS + "testfile.txt", - "passed" - }, - {BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded2" + - FS + "testfile.txt", - "passed" - }, + BUG_ID + "-2" + FS + "pkg" + FS + "doc-files" + FS + "subdir-excluded2" + + FS + "testfile.txt" }; private static final String[][] TEST0 = { @@ -106,7 +98,7 @@ public class TestDocFileDir extends JavadocTester { run(tester, ARGS0, TEST0, NEGATED_TEST0); copyDir(SRC_DIR + FS + "pkg", BUG_ID + "-1"); run(tester, ARGS1, TEST1, NEGATED_TEST1); - run(tester, ARGS2, TEST2, NEGATED_TEST2); + run(tester, ARGS2, NO_TEST, NO_TEST, FILE_TEST2, FILE_NEGATED_TEST2); tester.printSummary(); } diff --git a/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java b/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java index 3fa762d5bf6..393ba8f5de2 100644 --- a/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java +++ b/langtools/test/com/sun/javadoc/testEncoding/EncodeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,9 @@ /** - * ±ñÉ¿í ¹©¢! + * Testing en\u00e7\u00f4ded string. + * In the encoded comment string, Unicode U+00E7 is "Latin small letter C with cedilla" + * and Unicode U+00F4 is "Latin small letter O with circumflex" */ public class EncodeTest { } diff --git a/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java b/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java index 0e9f1b6f101..db627b69156 100644 --- a/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java +++ b/langtools/test/com/sun/javadoc/testEncoding/TestEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4661481 + * @bug 4661481 8024096 * @summary This test determines if the value of the -encoding option is * properly passed from Javadoc to the source file parser. * @author jamieh @@ -40,12 +40,12 @@ public class TestEncoding extends JavadocTester { //If ??? is found in the output, the source file was not read with the correct encoding setting. private static final String[][] NEGATED_TEST = { - {BUG_ID + FS + "EncodeTest.html", "???"} + {BUG_ID + FS + "EncodeTest.html", "??"} }; private static final String[] ARGS = new String[] { "-d", BUG_ID, "-sourcepath", SRC_DIR, - "-encoding", "SJIS", SRC_DIR + FS + "EncodeTest.java" + "-encoding", "iso-8859-1", SRC_DIR + FS + "EncodeTest.java" }; /** diff --git a/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java index 634ee4e4407..b0b79de0981 100644 --- a/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java +++ b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8002304 + * @bug 8002304 8024096 * @summary Test for various method types in the method summary table * @author Bhavesh Patel * @library ../lib/ @@ -107,7 +107,7 @@ public class TestMethodTypes extends JavadocTester { "" }, - {BUG_ID + FS + "pkg" + FS + "D.html", + {BUG_ID + FS + "pkg1" + FS + "D.html", "Methods " + "" }, diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java index 8dda141791c..4dd70ea2359 100644 --- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java +++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8006124 8009684 8016921 8023700 + * @bug 8006124 8009684 8016921 8023700 8024096 * @summary Test javadoc support for profiles. * @author Bhavesh Patel, Evgeniya Stepanova * @library ../lib/ @@ -187,26 +187,6 @@ public class TestProfiles extends JavadocTester { } }; private static final String[][] PACKAGES_NEGATED_TEST = { - {PACKAGE_BUG_ID + FS + "profile-overview-frame.html", - "All Packages" - }, - {PACKAGE_BUG_ID + FS + "compact2-frame.html", - "" - + "All PackagesAll Profiles" - }, - {PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html", - "" - + "compact2 - pkg2" - }, - {PACKAGE_BUG_ID + FS + "compact2-summary.html", - "

    Profile compact2

    " - }, - {PACKAGE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html", - "
    compact3
    " - }, {PACKAGE_BUG_ID + FS + "overview-frame.html", "All Profiles" @@ -222,6 +202,13 @@ public class TestProfiles extends JavadocTester { "" } }; + private static final String[] PACKAGES_NEGATED_FILE_TEST = { + PACKAGE_BUG_ID + FS + "profile-overview-frame.html", + PACKAGE_BUG_ID + FS + "compact2-frame.html", + PACKAGE_BUG_ID + FS + "pkg2" + FS + "compact2-package-frame.html", + PACKAGE_BUG_ID + FS + "compact2-summary.html", + PACKAGE_BUG_ID + FS + "pkg5" + FS + "compact3-package-summary.html" + }; /** * The entry point of the test. @@ -231,7 +218,7 @@ public class TestProfiles extends JavadocTester { public static void main(String[] args) { TestProfiles tester = new TestProfiles(); run(tester, ARGS1, PROFILES_TEST, PROFILES_NEGATED_TEST); - run(tester, ARGS2, PACKAGES_TEST, PACKAGES_NEGATED_TEST); + run(tester, ARGS2, PACKAGES_TEST, PACKAGES_NEGATED_TEST, NO_FILE_TEST, PACKAGES_NEGATED_FILE_TEST); tester.printSummary(); } From c2859f0bcad87c0bc9ba3fd23953ec4ccb00999d Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 19 Sep 2013 13:34:01 +0530 Subject: [PATCH 129/293] 8025048: true as case label results in ClassCastException Reviewed-by: lagergren --- .../jdk/nashorn/internal/codegen/Attr.java | 6 ++-- nashorn/test/script/basic/JDK-8025048-2.js | 36 +++++++++++++++++++ nashorn/test/script/basic/JDK-8025048.js | 36 +++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025048-2.js create mode 100644 nashorn/test/script/basic/JDK-8025048.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 813d3fc9083..55355c3efc8 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -807,9 +807,11 @@ final class Attr extends NodeOperatorVisitor { type = Type.OBJECT; } - type = Type.widest(type, newCaseNode.getTest().getType()); - if (type.isBoolean()) { + final Type newCaseType = newCaseNode.getTest().getType(); + if (newCaseType.isBoolean()) { type = Type.OBJECT; //booleans and integers aren't assignment compatible + } else { + type = Type.widest(type, newCaseType); } } diff --git a/nashorn/test/script/basic/JDK-8025048-2.js b/nashorn/test/script/basic/JDK-8025048-2.js new file mode 100644 index 00000000000..c11816bad53 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025048-2.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025048: true as case label results in ClassCastException + * + * @test + * @run + */ + +function func(x) { + switch(x) { + case 8: break; case false: + } +} + diff --git a/nashorn/test/script/basic/JDK-8025048.js b/nashorn/test/script/basic/JDK-8025048.js new file mode 100644 index 00000000000..75838a987d6 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025048.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025048: true as case label results in ClassCastException + * + * @test + * @run + */ + +function func(x) { + switch(x) { + case 8: break; case true: + } +} + From ca51d27ee3acebaf0475d789b58d3f1c4358c46b Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Thu, 19 Sep 2013 17:05:32 +0400 Subject: [PATCH 130/293] 8017248: Compiler Diacritics Issue Reviewed-by: naoto --- .../sun/tools/javac/file/RegularFileObject.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java index d99d729ac2c..055977f172e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java +++ b/langtools/src/share/classes/com/sun/tools/javac/file/RegularFileObject.java @@ -40,6 +40,7 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; import javax.tools.JavaFileObject; +import java.text.Normalizer; /** * A subclass of JavaFileObject representing regular files. @@ -57,6 +58,7 @@ class RegularFileObject extends BaseFileObject { private String name; final File file; private Reference absFileRef; + final static boolean isMacOS = System.getProperty("os.name", "").contains("OS X"); public RegularFileObject(JavacFileManager fileManager, File f) { this(fileManager, f.getName(), f); @@ -180,7 +182,19 @@ class RegularFileObject extends BaseFileObject { if (name.equals(n)) { return true; } - if (name.equalsIgnoreCase(n)) { + if (isMacOS && Normalizer.isNormalized(name, Normalizer.Form.NFD) + && Normalizer.isNormalized(n, Normalizer.Form.NFC)) { + // On Mac OS X it is quite possible to file name and class + // name normalized in a different way - in that case we have to normalize file name + // to the Normal Form Compised (NFC) + String normName = Normalizer.normalize(name, Normalizer.Form.NFC); + if (normName.equals(n)) { + this.name = normName; + return true; + } + } + + if (name.equalsIgnoreCase(n)) { try { // allow for Windows return file.getCanonicalFile().getName().equals(n); From 3d49dcdd9a8e5989b0bdbc6af6736f7064442b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 19 Sep 2013 15:39:01 +0200 Subject: [PATCH 131/293] 8023154: compileAllTests fails with: 2 tests failed to compile Reviewed-by: sundar, jlaskey --- nashorn/make/build-benchmark.xml | 8 ++++---- nashorn/make/build.xml | 14 ++++++++------ nashorn/make/project.properties | 7 ++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml index f1ce180a844..8f2296b028e 100644 --- a/nashorn/make/build-benchmark.xml +++ b/nashorn/make/build-benchmark.xml @@ -329,7 +329,7 @@ fork="true" dir="."> - + @@ -357,7 +357,7 @@ classpath="${run.test.classpath}" fork="true" dir="."> - + @@ -391,7 +391,7 @@ fork="true" dir="."> - + @@ -415,7 +415,7 @@ classpath="${run.test.classpath}" fork="true" dir="."> - + diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index 73644a6b523..4bc1a398b4d 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -66,6 +66,8 @@ + + @@ -320,7 +322,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -336,7 +338,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -352,7 +354,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -369,7 +371,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { - + @@ -387,7 +389,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { description="Run the shell with a sample script"> - + @@ -397,7 +399,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { description="Debug the shell with a sample script"> - + diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 5523f6cbab8..e6eea02eaa9 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -216,13 +216,14 @@ run.test.classpath=\ src.dir=src test.src.dir=test/src +# -Xmx is used for all tests, -Xms only for octane benchmark run.test.xmx=3G run.test.xms=2G run.test.user.language=tr run.test.user.country=TR -run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError +run.test.jvmargs.common=-server -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError #-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M # -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods @@ -231,12 +232,12 @@ run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfil run.test.jvmargs.main=${run.test.jvmargs.common} -ea #-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M -run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.common} +run.test.jvmargs.octane.main=${run.test.jvmargs.common} run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy # VM options for script tests with @fork option -test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} ${run.test.jvmsecurityargs} +test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} # path of rhino.jar for benchmarks rhino.jar= From a1f3a95880318c32169ff89dc8784a0dfc629eec Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Thu, 19 Sep 2013 11:04:23 -0400 Subject: [PATCH 132/293] 8024517: runtime/CDSCompressedKPtrs/XShareAuto.java failed with RuntimeException Make sure CDS is off by default when running server compiler. Reviewed-by: dholmes, coleenp --- hotspot/src/share/vm/runtime/arguments.cpp | 22 +++++++++++-------- .../CDSCompressedKPtrs/XShareAuto.java | 11 ++-------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 78b8338265d..36827a518cf 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1096,6 +1096,7 @@ void Arguments::set_mode_flags(Mode mode) { } } +#if defined(COMPILER2) || defined(_LP64) || !INCLUDE_CDS // Conflict: required to use shared spaces (-Xshare:on), but // incompatible command line options were chosen. @@ -1108,6 +1109,7 @@ static void no_shared_spaces() { FLAG_SET_DEFAULT(UseSharedSpaces, false); } } +#endif void Arguments::set_tiered_flags() { // With tiered, set default policy to AdvancedThresholdPolicy, which is 3. @@ -1492,16 +1494,18 @@ void Arguments::set_ergonomics_flags() { FLAG_SET_ERGO(bool, UseParallelGC, true); } } - // Shared spaces work fine with other GCs but causes bytecode rewriting - // to be disabled, which hurts interpreter performance and decreases - // server performance. On server class machines, keep the default - // off unless it is asked for. Future work: either add bytecode rewriting - // at link time, or rewrite bytecodes in non-shared methods. - if (!DumpSharedSpaces && !RequireSharedSpaces && - (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) { - no_shared_spaces(); - } } +#ifdef COMPILER2 + // Shared spaces work fine with other GCs but causes bytecode rewriting + // to be disabled, which hurts interpreter performance and decreases + // server performance. When -server is specified, keep the default off + // unless it is asked for. Future work: either add bytecode rewriting + // at link time, or rewrite bytecodes in non-shared methods. + if (!DumpSharedSpaces && !RequireSharedSpaces && + (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) { + no_shared_spaces(); + } +#endif #ifndef ZERO #ifdef _LP64 diff --git a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java index 7f36977ec70..9bd68e11733 100644 --- a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java +++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java @@ -33,16 +33,9 @@ import com.oracle.java.testlibrary.*; public class XShareAuto { public static void main(String[] args) throws Exception { - if (!Platform.is64bit()) { - System.out.println("ObjectAlignmentInBytes for CDS is only " + - "supported on 64bit platforms; this plaform is " + - System.getProperty("sun.arch.data.model")); - System.out.println("Skipping the test"); - return; - } ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", - "-Xshare:dump"); + "-server", "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("Loading classes to share"); output.shouldHaveExitValue(0); From 1c9e7a8edc07aa9038adca1cd97d9e98a36c7b15 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 19 Sep 2013 17:05:08 +0200 Subject: [PATCH 133/293] 8022567: Javac Should Generate Warnings For Raw Array Type Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Check.java | 18 ++++++++++++------ .../tools/javac/warnings/6747671/T6747671.java | 9 ++++++++- .../tools/javac/warnings/6747671/T6747671.out | 4 +++- 3 files changed, 23 insertions(+), 8 deletions(-) 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 5f6d1886bd8..d3f94fdba82 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 @@ -1245,6 +1245,7 @@ public class Check { */ class Validator extends JCTree.Visitor { + boolean checkRaw; boolean isOuter; Env env; @@ -1254,7 +1255,7 @@ public class Check { @Override public void visitTypeArray(JCArrayTypeTree tree) { - tree.elemtype.accept(this); + validateTree(tree.elemtype, checkRaw, isOuter); } @Override @@ -1345,15 +1346,20 @@ public class Check { } public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) { - try { - if (tree != null) { - this.isOuter = isOuter; + if (tree != null) { + boolean prevCheckRaw = this.checkRaw; + this.checkRaw = checkRaw; + this.isOuter = isOuter; + + try { tree.accept(this); if (checkRaw) checkRaw(tree, env); + } catch (CompletionFailure ex) { + completionError(tree.pos(), ex); + } finally { + this.checkRaw = prevCheckRaw; } - } catch (CompletionFailure ex) { - completionError(tree.pos(), ex); } } diff --git a/langtools/test/tools/javac/warnings/6747671/T6747671.java b/langtools/test/tools/javac/warnings/6747671/T6747671.java index c8060a06afd..2bb67ac132f 100644 --- a/langtools/test/tools/javac/warnings/6747671/T6747671.java +++ b/langtools/test/tools/javac/warnings/6747671/T6747671.java @@ -1,6 +1,6 @@ /** * @test /nodynamiccopyright/ - * @bug 6747671 + * @bug 6747671 8022567 * @summary -Xlint:rawtypes * @compile/ref=T6747671.out -XDrawDiagnostics -Xlint:rawtypes T6747671.java */ @@ -32,4 +32,11 @@ class T6747671 { A a2 = new A() {};//raw warning (2) a2.new Z() {};//raw warning } + + @TA B @TA[] arr = new @TA B @TA [0];//JDK-8022567: raw warning (2) + Class classes1;//no warning + Class[] classes2;//no warning + + @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_USE) + @interface TA { } } diff --git a/langtools/test/tools/javac/warnings/6747671/T6747671.out b/langtools/test/tools/javac/warnings/6747671/T6747671.out index 43069572c62..518804d68b5 100644 --- a/langtools/test/tools/javac/warnings/6747671/T6747671.out +++ b/langtools/test/tools/javac/warnings/6747671/T6747671.out @@ -7,4 +7,6 @@ T6747671.java:29:28: compiler.warn.raw.class.use: T6747671.B, T6747671.B T6747671.java:32:9: compiler.warn.raw.class.use: T6747671.A, T6747671.A T6747671.java:32:20: compiler.warn.raw.class.use: T6747671.A, T6747671.A T6747671.java:33:16: compiler.warn.raw.class.use: T6747671.A.Z, T6747671.A.Z -9 warnings +T6747671.java:36:9: compiler.warn.raw.class.use: @T6747671.TA T6747671.B, T6747671.B +T6747671.java:36:27: compiler.warn.raw.class.use: T6747671.B, T6747671.B +11 warnings From 5db62ec900bbdb41ba2a927eb41787326ae382f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Thu, 19 Sep 2013 08:26:26 -0700 Subject: [PATCH 134/293] 8024609: sjavac assertion fails during call to BuildState.collectArtifacts Reviewed-by: jjg --- .../classes/com/sun/tools/sjavac/BuildState.java | 16 ++++++++++------ .../share/classes/com/sun/tools/sjavac/Main.java | 8 ++++---- .../com/sun/tools/sjavac/server/JavacServer.java | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java b/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java index 9b90950290c..43606b2b715 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/BuildState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,12 +81,13 @@ public class BuildState { } /** - * Collect all packages, sources and artifacts for all modules - * into the build state. + * Store references to all packages, sources and artifacts for all modules + * into the build state. I.e. flatten the module tree structure + * into global maps stored in the BuildState for easy access. * * @param m The set of modules. */ - public void collectPackagesSourcesAndArtifacts(Map m) { + public void flattenPackagesSourcesAndArtifacts(Map m) { modules = m; // Extract all the found packages. for (Module i : modules.values()) { @@ -121,11 +122,12 @@ public class BuildState { } /** - * Collect all the artifacts of all modules and packages. + * Store references to all artifacts found in the module tree into the maps + * stored in the build state. * * @param m The set of modules. */ - public void collectArtifacts(Map m) { + public void flattenArtifacts(Map m) { modules = m; // Extract all the found packages. for (Module i : modules.values()) { @@ -270,6 +272,8 @@ public class BuildState { Module mnew = findModuleFromPackageName(pkg); Package pprev = prev.packages().get(pkg); mnew.addPackage(pprev); + // Do not forget to update the flattened data. + packages.put(pkg, pprev); } } } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java index f0ed51432ee..183ebb56e27 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java @@ -274,7 +274,7 @@ public class Main { // findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true); // Add the set of sources to the build database. - javac_state.now().collectPackagesSourcesAndArtifacts(modules); + javac_state.now().flattenPackagesSourcesAndArtifacts(modules); javac_state.now().checkInternalState("checking sources", false, sources); javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to); javac_state.setVisibleSources(sources_to_link_to); @@ -311,7 +311,7 @@ public class Main { Map generated_sources = new HashMap(); Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null, generated_sources, modules, current_module, false, true, false); - javac_state.now().collectPackagesSourcesAndArtifacts(modules); + javac_state.now().flattenPackagesSourcesAndArtifacts(modules); // Recheck the the source files and their timestamps again. javac_state.checkSourceStatus(true); @@ -336,8 +336,8 @@ public class Main { // Only update the state if the compile went well. if (rc[0]) { javac_state.save(); - // Collect all the artifacts. - javac_state.now().collectArtifacts(modules); + // Reflatten only the artifacts. + javac_state.now().flattenArtifacts(modules); // Remove artifacts that were generated during the last compile, but not this one. javac_state.removeSuperfluousArtifacts(recently_compiled); } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java index 2e59f275fd8..66e3022a76e 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java @@ -464,7 +464,7 @@ public class JavacServer { PrintStream err) { int rc = -3; try { - int port = portFile.getPort(); + int port = portFile.containsPortInfo() ? portFile.getPort() : 0; if (port == 0) { return ERROR_BUT_TRY_AGAIN; } From d6f64ae0092a69677ea4ec58865b63396330e25f Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 19 Sep 2013 21:20:47 +0530 Subject: [PATCH 135/293] 8025080: Object literal getter, setter function with number format property name results in ClassFormatError Reviewed-by: lagergren, hannesw --- .../nashorn/internal/ir/debug/JSONWriter.java | 3 +- .../jdk/nashorn/internal/parser/Parser.java | 5 ++- nashorn/test/script/basic/JDK-8025080.js | 43 +++++++++++++++++++ .../test/script/basic/JDK-8025080.js.EXPECTED | 4 ++ .../basic/parser/objectLitExpr.js.EXPECTED | 10 +---- 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025080.js create mode 100644 nashorn/test/script/basic/JDK-8025080.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index dabc7e36bf1..4702057a34c 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -410,7 +410,8 @@ public final class JSONWriter extends NodeVisitor { comma(); property("id"); - if (functionNode.isAnonymous()) { + final FunctionNode.Kind kind = functionNode.getKind(); + if (functionNode.isAnonymous() || kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) { nullValue(); } else { functionNode.getIdent().accept(this); diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index d051917149e..9663401ff5e 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -59,6 +59,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import jdk.internal.dynalink.support.NameCodec; import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.Namespace; import jdk.nashorn.internal.ir.AccessNode; @@ -2108,7 +2109,7 @@ loop: case "get": final PropertyKey getIdent = propertyName(); final String getterName = getIdent.getPropertyName(); - final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + getterName); + final IdentNode getNameNode = new IdentNode(((Node)getIdent).getToken(), finish, "get " + NameCodec.encode(getterName)); expect(LPAREN); expect(RPAREN); functionNode = functionBody(getSetToken, getNameNode, new ArrayList(), FunctionNode.Kind.GETTER); @@ -2117,7 +2118,7 @@ loop: case "set": final PropertyKey setIdent = propertyName(); final String setterName = setIdent.getPropertyName(); - final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + setterName); + final IdentNode setNameNode = new IdentNode(((Node)setIdent).getToken(), finish, "set " + NameCodec.encode(setterName)); expect(LPAREN); final IdentNode argIdent = getIdent(); verifyStrictIdent(argIdent, "setter argument"); diff --git a/nashorn/test/script/basic/JDK-8025080.js b/nashorn/test/script/basic/JDK-8025080.js new file mode 100644 index 00000000000..1ea46efa530 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025080.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025080: Object literal getter, setter function with number format property name results in ClassFormatError + * + * @test + * @run + */ + +var obj = { + get 1e81() { print("1e81 getter"); }, + set 1e81(x) { print("1e81 setter"); }, + get 3.14e-2() { print("3.14e-2 getter");}, + set 3.14e-2(x) { print("3.14e-2 setter"); } +}; + +obj[1e81]; +obj[1e81] = 23; + +obj[3.14e-2]; +obj[3.14e-2] = 42; + diff --git a/nashorn/test/script/basic/JDK-8025080.js.EXPECTED b/nashorn/test/script/basic/JDK-8025080.js.EXPECTED new file mode 100644 index 00000000000..e19e8ae9621 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025080.js.EXPECTED @@ -0,0 +1,4 @@ +1e81 getter +1e81 setter +3.14e-2 getter +3.14e-2 setter diff --git a/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED index 067c506ab95..7968d9a4a0f 100644 --- a/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED +++ b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED @@ -126,10 +126,7 @@ }, "value": { "type": "FunctionExpression", - "id": { - "type": "Identifier", - "name": "get x" - }, + "id": null, "params": [], "defaults": [], "rest": null, @@ -157,10 +154,7 @@ }, "value": { "type": "FunctionExpression", - "id": { - "type": "Identifier", - "name": "get y" - }, + "id": null, "params": [], "defaults": [], "rest": null, From ff9c0f87c4dd3f17fb075bc0cba65b3dd4762c5c Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:36:42 -0700 Subject: [PATCH 136/293] Added tag jdk8-b108 for changeset 345aa6f8d18a --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index d83fa5ca611..fbcdb0977c0 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -229,3 +229,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105 8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 +9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108 From 62ae29e3cad403385213865a0a1c920643d91482 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:36:44 -0700 Subject: [PATCH 137/293] Added tag jdk8-b108 for changeset 78407de2df2f --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index e24845b3555..7271ad7b3fa 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -229,3 +229,4 @@ d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105 2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107 +a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108 From 6e53556facbfe6dbcaa9107947b8d65d137c0f0b Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:36:51 -0700 Subject: [PATCH 138/293] Added tag jdk8-b108 for changeset be8d551c4d00 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 370ade6688d..024f5b4d0ee 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -377,3 +377,4 @@ aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49 5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107 a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 +85072013aad46050a362d10ab78e963121c8014c jdk8-b108 From bfcf677949ddfc9881716d2e57a4512304bb989a Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:02 -0700 Subject: [PATCH 139/293] Added tag jdk8-b108 for changeset 261ae91f2b65 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index e136f4f7d31..f3166e9d9df 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -229,3 +229,4 @@ a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104 09a46ec11f880154886c70be03aff5ab2ddf0ab7 jdk8-b105 d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106 d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107 +8ade3eed63da87067a7137c111f684a821e9e531 jdk8-b108 From e8367de47cb63d71d4b42083feb2cc65a29e8cd5 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:05 -0700 Subject: [PATCH 140/293] Added tag jdk8-b108 for changeset 815fb8808c4b --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 164a718d39c..6a23622251b 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -229,3 +229,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98 88390df7ed2cf128298a02c5e6d978f0a603cd58 jdk8-b105 6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106 e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107 +d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108 From f0b751a85487dc289e5bd6635fa68041611c9fdd Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:13 -0700 Subject: [PATCH 141/293] Added tag jdk8-b108 for changeset f45d281bd0de --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 3e3a625970b..6eef7251ea8 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -229,3 +229,4 @@ f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105 c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 +006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108 From cb06edc1bf96e8683ce735eb0da0da771bf996b0 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:26 -0700 Subject: [PATCH 142/293] Added tag jdk8-b108 for changeset 669e1adcbf50 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index f3ac2a1e9ab..2210809d462 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -229,3 +229,4 @@ dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104 375834b5cf086dd7ce9e49f602d81bb51d3e0fa9 jdk8-b105 fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106 3f274927ec1863544b8214262ab02b7de2970da6 jdk8-b107 +252f872b8a2f81a416f9127e77924ca56a4578b0 jdk8-b108 From 1c1306bb1d06768a13f1b9daad7727829c6507a3 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 19 Sep 2013 09:37:28 -0700 Subject: [PATCH 143/293] Added tag jdk8-b108 for changeset 3afa46cd7e01 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 05fbb43822b..10aa318ed1d 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -217,3 +217,4 @@ afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104 f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105 bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106 f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107 +445ad3f6d3b4ba62ebc483323e1919110a304053 jdk8-b108 From 996bf0feefdb5384f74e44e3713dfea4dc7154ef Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 19 Sep 2013 23:48:37 +0530 Subject: [PATCH 144/293] 8025090: 'while' statement with 'test' using var before being declared in body results in VerifyError Reviewed-by: jlaskey --- .../jdk/nashorn/internal/ir/WhileNode.java | 9 +++-- nashorn/test/script/basic/JDK-8025090.js | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025090.js diff --git a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java index 3c0046c0879..97e7ca54fc1 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java @@ -79,13 +79,12 @@ public final class WhileNode extends LoopNode { if (visitor.enterWhileNode(this)) { if (isDoWhile()) { return visitor.leaveWhileNode( - setTest(lc, (Expression)test.accept(visitor)). - setBody(lc, (Block)body.accept(visitor))); + setBody(lc, (Block)body.accept(visitor)). + setTest(lc, (Expression)test.accept(visitor))); } return visitor.leaveWhileNode( - setBody(lc, (Block)body.accept(visitor)). - setTest(lc, (Expression)test.accept(visitor))); - + setTest(lc, (Expression)test.accept(visitor)). + setBody(lc, (Block)body.accept(visitor))); } return this; } diff --git a/nashorn/test/script/basic/JDK-8025090.js b/nashorn/test/script/basic/JDK-8025090.js new file mode 100644 index 00000000000..8e42099cf47 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025090.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025090: 'while' statement with 'test' using var before being declared in body results in VerifyError + * + * @test + * @run + */ + +// The following used to result in VerifyError +function f() { + while (x += 2) { var x = 44 } +} + From e3d450e3d306cdcd8f2c3762239e96b21d31176c Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 19 Sep 2013 20:57:37 +0100 Subject: [PATCH 145/293] 8024437: Inferring the exception thrown: sometimes fails to compile Reviewed-by: jjg --- .../com/sun/tools/javac/code/Flags.java | 2 +- .../com/sun/tools/javac/jvm/ClassReader.java | 7 ++ .../ExceptionInferenceFromClassFileTest.java | 74 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index 3a4084ed2a8..2f59cfab7fd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -261,7 +261,7 @@ public class Flags { public static final long SIGNATURE_POLYMORPHIC = 1L<<46; /** - * Flag that marks inference variables used in a 'throws' clause + * Flag that indicates that an inference variable is used in a 'throws' clause. */ public static final long THROWS = 1L<<47; 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 d3d9d302f1e..1b57b13cf36 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 @@ -56,6 +56,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.CLASS; +import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.jvm.ClassFile.*; import static com.sun.tools.javac.jvm.ClassFile.Version.*; @@ -703,6 +704,12 @@ public class ClassReader { sigp++; thrown = thrown.prepend(sigToType()); } + // if there is a typevar in the throws clause we should state it. + for (List l = thrown; l.nonEmpty(); l = l.tail) { + if (l.head.hasTag(TYPEVAR)) { + l.head.tsym.flags_field |= THROWS; + } + } return new MethodType(argtypes, restype, thrown.reverse(), diff --git a/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java b/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java new file mode 100644 index 00000000000..250b18a0614 --- /dev/null +++ b/langtools/test/tools/javac/T8024437/ExceptionInferenceFromClassFileTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024437 + * @summary Inferring the exception thrown by a lambda: sometimes fails to compile + * @library /tools/javac/lib + * @build ToolBox + * @run main ExceptionInferenceFromClassFileTest + */ + +import java.nio.file.Files; +import java.nio.file.Paths; + +public class ExceptionInferenceFromClassFileTest { + + static final String ABSrc = + "class B {\n" + + " public static void t(A a) throws E {\n" + + " a.run();\n" + + " }\n" + + "}\n" + + + "interface A {\n" + + " void run() throws E;\n" + + "}"; + + static final String CSrc = + "class C {\n" + + " public void d() {\n" + + " B.t(null);\n" + + " }\n" + + "}"; + + public static void main(String[] args) throws Exception { + Files.createDirectory(Paths.get("out")); + + ToolBox.JavaToolArgs compileABParams = + new ToolBox.JavaToolArgs() + .setOptions("-d", "out") + .setSources(ABSrc); + ToolBox.javac(compileABParams); + + ToolBox.JavaToolArgs compileCParams = + new ToolBox.JavaToolArgs() + .setOptions("-d", "out", "-cp", "out") + .setSources(CSrc); + ToolBox.javac(compileCParams); + } + +} From 8b909ba5580011b7d810eef7cf9781dc83a1d6b3 Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Thu, 19 Sep 2013 19:18:37 -0700 Subject: [PATCH 146/293] 8025110: TreeCopier does not correctly copy LabeledStatementTree Reviewed-by: jjg --- .../src/share/classes/com/sun/tools/javac/tree/TreeCopier.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java index aa2ce423b4b..1ccbb53518e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -234,7 +234,7 @@ public class TreeCopier

    implements TreeVisitor { public JCTree visitLabeledStatement(LabeledStatementTree node, P p) { JCLabeledStatement t = (JCLabeledStatement) node; JCStatement body = copy(t.body, p); - return M.at(t.pos).Labelled(t.label, t.body); + return M.at(t.pos).Labelled(t.label, body); } public JCTree visitLiteral(LiteralTree node, P p) { From 337cfe593f82a081b9a21e11b3e1449f28931e15 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 20 Sep 2013 12:56:07 +0530 Subject: [PATCH 147/293] 8025111: undefined or null 'with' expression in empty with block should throw TypeError Reviewed-by: lagergren, hannesw --- .../internal/codegen/CodeGenerator.java | 9 +++- nashorn/test/script/basic/JDK-8025111.js | 48 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025111.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 6307e2f9dbe..d16a1e5ba1f 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -2174,8 +2174,9 @@ final class CodeGenerator extends NodeOperatorVisitor Date: Fri, 20 Sep 2013 10:53:28 +0200 Subject: [PATCH 148/293] 8024974: Incorrect use of GC_locker::is_active() SymbolTable and StringTable can make calls to GC_locker::is_active() outside a safepoint. This isn't safe because the GC_locker active state (lock count) is only updated at a safepoint and only remains valid as long as _needs_gc is true. However, outside a safepoint_needs_gc can change to false at any time, which makes it impossible to do a correct call to is_active() in that context. In this case these calls can just be removed since the input argument to basic_add() should never be on the heap and so there's no need to check the GC_locker state. This change also adjusts the assert() in is_active() to makes sure all calls to this function are always done under a safepoint. Reviewed-by: brutisso, dcubed --- hotspot/src/share/vm/classfile/symbolTable.cpp | 4 ++-- hotspot/src/share/vm/memory/gcLocker.cpp | 2 +- hotspot/src/share/vm/memory/gcLocker.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index c00e9581759..d0d33d878fe 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -341,7 +341,7 @@ Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) { Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len, unsigned int hashValue_arg, bool c_heap, TRAPS) { - assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), + assert(!Universe::heap()->is_in_reserved(name), "proposed name of symbol must be stable"); // Don't allow symbols to be created which cannot fit in a Symbol*. @@ -685,7 +685,7 @@ oop StringTable::intern(Handle string_or_null, jchar* name, if (found_string != NULL) return found_string; debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); - assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), + assert(!Universe::heap()->is_in_reserved(name), "proposed name of symbol must be stable"); Handle string; diff --git a/hotspot/src/share/vm/memory/gcLocker.cpp b/hotspot/src/share/vm/memory/gcLocker.cpp index eda728b7047..1b0c94ee171 100644 --- a/hotspot/src/share/vm/memory/gcLocker.cpp +++ b/hotspot/src/share/vm/memory/gcLocker.cpp @@ -122,7 +122,7 @@ void GC_locker::jni_unlock(JavaThread* thread) { // strictly needed. It's added here to make it clear that // the GC will NOT be performed if any other caller // of GC_locker::lock() still needs GC locked. - if (!is_active()) { + if (!is_active_internal()) { _doing_gc = true; { // Must give up the lock while at a safepoint diff --git a/hotspot/src/share/vm/memory/gcLocker.hpp b/hotspot/src/share/vm/memory/gcLocker.hpp index 8ede8fb275b..45b8a8f89e7 100644 --- a/hotspot/src/share/vm/memory/gcLocker.hpp +++ b/hotspot/src/share/vm/memory/gcLocker.hpp @@ -88,7 +88,7 @@ class GC_locker: public AllStatic { public: // Accessors static bool is_active() { - assert(_needs_gc || SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); + assert(SafepointSynchronize::is_at_safepoint(), "only read at safepoint"); return is_active_internal(); } static bool needs_gc() { return _needs_gc; } From bbb009b580e819519598c582446b6db98f5950e5 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 20 Sep 2013 11:00:38 +0200 Subject: [PATCH 149/293] 8025059: Metspace::should_expand mixes bytes and words in check against MaxMetaspaceSize Reviewed-by: coleenp, brutisso, mgerdin, jmasa --- hotspot/src/share/vm/memory/metaspace.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index c12c0b8637b..0a741d674ca 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1342,8 +1342,9 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { // reserved space, because this is a larger space prereserved for compressed // class pointers. if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { - size_t real_allocated = Metaspace::space_list()->reserved_words() + - MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); + size_t nonclass_allocated = MetaspaceAux::reserved_bytes(Metaspace::NonClassType); + size_t class_allocated = MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); + size_t real_allocated = nonclass_allocated + class_allocated; if (real_allocated >= MaxMetaspaceSize) { return false; } From 82156b393c325e6778983623c5e8f0ed74589694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 20 Sep 2013 12:11:08 +0200 Subject: [PATCH 150/293] 8022587: ClassCache is not optimal and leaks Source instances Reviewed-by: lagergren, attila --- .../jdk/nashorn/internal/objects/Global.java | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index b7a902b745e..161909bb3f6 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.reflect.Field; import java.util.Arrays; @@ -691,17 +692,41 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { * Cache for compiled script classes. */ @SuppressWarnings("serial") - private static class ClassCache extends LinkedHashMap>> { + private static class ClassCache extends LinkedHashMap { private final int size; + private final ReferenceQueue> queue; ClassCache(int size) { super(size, 0.75f, true); this.size = size; + this.queue = new ReferenceQueue<>(); + } + + void cache(final Source source, final Class clazz) { + put(source, new ClassReference(clazz, queue, source)); } @Override - protected boolean removeEldestEntry(final Map.Entry>> eldest) { - return size() >= size; + protected boolean removeEldestEntry(final Map.Entry eldest) { + return size() > size; + } + + @Override + public ClassReference get(Object key) { + for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) { + remove(ref.source); + } + return super.get(key); + } + + } + + private static class ClassReference extends SoftReference> { + private final Source source; + + ClassReference(final Class clazz, final ReferenceQueue> queue, final Source source) { + super(clazz, queue); + this.source = source; } } @@ -709,22 +734,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { @Override public Class findCachedClass(final Source source) { assert classCache != null : "Class cache used without being initialized"; - SoftReference> ref = classCache.get(source); - if (ref != null) { - final Class clazz = ref.get(); - if (clazz == null) { - classCache.remove(source); - } - return clazz; - } - - return null; + ClassReference ref = classCache.get(source); + return ref != null ? ref.get() : null; } @Override public void cacheClass(final Source source, final Class clazz) { assert classCache != null : "Class cache used without being initialized"; - classCache.put(source, new SoftReference>(clazz)); + classCache.cache(source, clazz); } private static T getLazilyCreatedValue(final Object key, final Callable creator, final Map map) { From ec5e07f810933f5fdbda6729a1ed609f5f600c14 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 20 Sep 2013 09:30:02 -0400 Subject: [PATCH 151/293] 8022887: Assertion hit while using class and redefining it with RedefineClasses simultaneously Need to refetch each method from InstanceKlass after all safepoints. Removed leaky PreviousVersionInfo code. Reviewed-by: dcubed, sspitsyn --- .../src/share/vm/memory/metaspaceShared.cpp | 5 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 157 +++++------------- hotspot/src/share/vm/oops/instanceKlass.hpp | 71 ++------ hotspot/src/share/vm/prims/jvm.cpp | 117 ++++++------- hotspot/src/share/vm/prims/jvmtiImpl.cpp | 78 ++++----- .../share/vm/prims/jvmtiRedefineClasses.cpp | 39 ++--- hotspot/src/share/vm/runtime/handles.hpp | 4 +- .../src/share/vm/runtime/handles.inline.hpp | 2 + 8 files changed, 169 insertions(+), 304 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index 2a9873957a8..ef51c926662 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -103,9 +103,10 @@ static void calculate_fingerprints() { if (k->oop_is_instance()) { InstanceKlass* ik = InstanceKlass::cast(k); for (int i = 0; i < ik->methods()->length(); i++) { - ResourceMark rm; Method* m = ik->methods()->at(i); - (new Fingerprinter(m))->fingerprint(); + Fingerprinter fp(m); + // The side effect of this call sets method's fingerprint field. + fp.fingerprint(); } } } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 29c77a07ccb..6e932830b3a 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -2847,24 +2847,17 @@ void InstanceKlass::print_on(outputStream* st) const { st->print(BULLET"field annotations: "); fields_annotations()->print_value_on(st); st->cr(); st->print(BULLET"field type annotations: "); fields_type_annotations()->print_value_on(st); st->cr(); { - ResourceMark rm; - // PreviousVersionInfo objects returned via PreviousVersionWalker - // contain a GrowableArray of handles. We have to clean up the - // GrowableArray _after_ the PreviousVersionWalker destructor - // has destroyed the handles. - { - bool have_pv = false; - PreviousVersionWalker pvw((InstanceKlass*)this); - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); - pv_info != NULL; pv_info = pvw.next_previous_version()) { - if (!have_pv) - st->print(BULLET"previous version: "); - have_pv = true; - pv_info->prev_constant_pool_handle()()->print_value_on(st); - } - if (have_pv) st->cr(); - } // pvw is cleaned up - } // rm is cleaned up + bool have_pv = false; + PreviousVersionWalker pvw(Thread::current(), (InstanceKlass*)this); + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); + pv_node != NULL; pv_node = pvw.next_previous_version()) { + if (!have_pv) + st->print(BULLET"previous version: "); + have_pv = true; + pv_node->prev_constant_pool()->print_value_on(st); + } + if (have_pv) st->cr(); + } // pvw is cleaned up if (generic_signature() != NULL) { st->print(BULLET"generic signature: "); @@ -3392,34 +3385,34 @@ void InstanceKlass::add_previous_version(instanceKlassHandle ikh, Array* old_methods = ikh->methods(); if (cp_ref->on_stack()) { - PreviousVersionNode * pv_node = NULL; - if (emcp_method_count == 0) { + PreviousVersionNode * pv_node = NULL; + if (emcp_method_count == 0) { // non-shared ConstantPool gets a reference - pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), NULL); - RC_TRACE(0x00000400, - ("add: all methods are obsolete; flushing any EMCP refs")); - } else { - int local_count = 0; + pv_node = new PreviousVersionNode(cp_ref, NULL); + RC_TRACE(0x00000400, + ("add: all methods are obsolete; flushing any EMCP refs")); + } else { + int local_count = 0; GrowableArray* method_refs = new (ResourceObj::C_HEAP, mtClass) - GrowableArray(emcp_method_count, true); - for (int i = 0; i < old_methods->length(); i++) { - if (emcp_methods->at(i)) { - // this old method is EMCP. Save it only if it's on the stack - Method* old_method = old_methods->at(i); - if (old_method->on_stack()) { - method_refs->append(old_method); + GrowableArray(emcp_method_count, true); + for (int i = 0; i < old_methods->length(); i++) { + if (emcp_methods->at(i)) { + // this old method is EMCP. Save it only if it's on the stack + Method* old_method = old_methods->at(i); + if (old_method->on_stack()) { + method_refs->append(old_method); + } + if (++local_count >= emcp_method_count) { + // no more EMCP methods so bail out now + break; } - if (++local_count >= emcp_method_count) { - // no more EMCP methods so bail out now - break; } } - } // non-shared ConstantPool gets a reference - pv_node = new PreviousVersionNode(cp_ref, !cp_ref->is_shared(), method_refs); + pv_node = new PreviousVersionNode(cp_ref, method_refs); } // append new previous version. - _previous_versions->append(pv_node); + _previous_versions->append(pv_node); } // Since the caller is the VMThread and we are at a safepoint, this @@ -3520,6 +3513,8 @@ Method* InstanceKlass::method_with_idnum(int idnum) { return m; } } + // None found, return null for the caller to handle. + return NULL; } return m; } @@ -3536,10 +3531,9 @@ unsigned char * InstanceKlass::get_cached_class_file_bytes() { // Construct a PreviousVersionNode entry for the array hung off // the InstanceKlass. PreviousVersionNode::PreviousVersionNode(ConstantPool* prev_constant_pool, - bool prev_cp_is_weak, GrowableArray* prev_EMCP_methods) { + GrowableArray* prev_EMCP_methods) { _prev_constant_pool = prev_constant_pool; - _prev_cp_is_weak = prev_cp_is_weak; _prev_EMCP_methods = prev_EMCP_methods; } @@ -3555,99 +3549,38 @@ PreviousVersionNode::~PreviousVersionNode() { } } - -// Construct a PreviousVersionInfo entry -PreviousVersionInfo::PreviousVersionInfo(PreviousVersionNode *pv_node) { - _prev_constant_pool_handle = constantPoolHandle(); // NULL handle - _prev_EMCP_method_handles = NULL; - - ConstantPool* cp = pv_node->prev_constant_pool(); - assert(cp != NULL, "constant pool ref was unexpectedly cleared"); - if (cp == NULL) { - return; // robustness - } - - // make the ConstantPool* safe to return - _prev_constant_pool_handle = constantPoolHandle(cp); - - GrowableArray* method_refs = pv_node->prev_EMCP_methods(); - if (method_refs == NULL) { - // the InstanceKlass did not have any EMCP methods - return; - } - - _prev_EMCP_method_handles = new GrowableArray(10); - - int n_methods = method_refs->length(); - for (int i = 0; i < n_methods; i++) { - Method* method = method_refs->at(i); - assert (method != NULL, "method has been cleared"); - if (method == NULL) { - continue; // robustness - } - // make the Method* safe to return - _prev_EMCP_method_handles->append(methodHandle(method)); - } -} - - -// Destroy a PreviousVersionInfo -PreviousVersionInfo::~PreviousVersionInfo() { - // Since _prev_EMCP_method_handles is not C-heap allocated, we - // don't have to delete it. -} - - // Construct a helper for walking the previous versions array -PreviousVersionWalker::PreviousVersionWalker(InstanceKlass *ik) { +PreviousVersionWalker::PreviousVersionWalker(Thread* thread, InstanceKlass *ik) { + _thread = thread; _previous_versions = ik->previous_versions(); _current_index = 0; - // _hm needs no initialization _current_p = NULL; -} - - -// Destroy a PreviousVersionWalker -PreviousVersionWalker::~PreviousVersionWalker() { - // Delete the current info just in case the caller didn't walk to - // the end of the previous versions list. No harm if _current_p is - // already NULL. - delete _current_p; - - // When _hm is destroyed, all the Handles returned in - // PreviousVersionInfo objects will be destroyed. - // Also, after this destructor is finished it will be - // safe to delete the GrowableArray allocated in the - // PreviousVersionInfo objects. + _current_constant_pool_handle = constantPoolHandle(thread, ik->constants()); } // Return the interesting information for the next previous version // of the klass. Returns NULL if there are no more previous versions. -PreviousVersionInfo* PreviousVersionWalker::next_previous_version() { +PreviousVersionNode* PreviousVersionWalker::next_previous_version() { if (_previous_versions == NULL) { // no previous versions so nothing to return return NULL; } - delete _current_p; // cleanup the previous info for the caller - _current_p = NULL; // reset to NULL so we don't delete same object twice + _current_p = NULL; // reset to NULL + _current_constant_pool_handle = NULL; int length = _previous_versions->length(); while (_current_index < length) { PreviousVersionNode * pv_node = _previous_versions->at(_current_index++); - PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass) - PreviousVersionInfo(pv_node); - constantPoolHandle cp_h = pv_info->prev_constant_pool_handle(); - assert (!cp_h.is_null(), "null cp found in previous version"); - - // The caller will need to delete pv_info when they are done with it. - _current_p = pv_info; - return pv_info; + // Save a handle to the constant pool for this previous version, + // which keeps all the methods from being deallocated. + _current_constant_pool_handle = constantPoolHandle(_thread, pv_node->prev_constant_pool()); + _current_p = pv_node; + return pv_node; } - // all of the underlying nodes' info has been deleted return NULL; } // end next_previous_version() diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp index 123f6b17911..4815294118e 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp @@ -1136,21 +1136,11 @@ 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. 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. +// version(s) of an InstanceKlass. A GrowableArray of PreviousVersionNodes +// is attached to the InstanceKlass as needed. See PreviousVersionWalker below. class PreviousVersionNode : public CHeapObj { private: - // 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. - ConstantPool* _prev_constant_pool; // regular or weak reference - bool _prev_cp_is_weak; // true if not a shared ConstantPool + ConstantPool* _prev_constant_pool; // If the previous version of the InstanceKlass doesn't have any // EMCP methods, then _prev_EMCP_methods will be NULL. If all the @@ -1159,8 +1149,8 @@ class PreviousVersionNode : public CHeapObj { GrowableArray* _prev_EMCP_methods; public: - PreviousVersionNode(ConstantPool* prev_constant_pool, bool prev_cp_is_weak, - GrowableArray* prev_EMCP_methods); + PreviousVersionNode(ConstantPool* prev_constant_pool, + GrowableArray* prev_EMCP_methods); ~PreviousVersionNode(); ConstantPool* prev_constant_pool() const { return _prev_constant_pool; @@ -1171,59 +1161,26 @@ public: }; -// A Handle-ized version of PreviousVersionNode. -class PreviousVersionInfo : public ResourceObj { - private: - constantPoolHandle _prev_constant_pool_handle; - // If the previous version of the InstanceKlass doesn't have any - // EMCP methods, then _prev_EMCP_methods will be NULL. Since the - // methods cannot be collected while we hold a handle, - // _prev_EMCP_methods should never have a length of zero. - GrowableArray* _prev_EMCP_method_handles; - -public: - PreviousVersionInfo(PreviousVersionNode *pv_node); - ~PreviousVersionInfo(); - constantPoolHandle prev_constant_pool_handle() const { - return _prev_constant_pool_handle; - } - GrowableArray* prev_EMCP_method_handles() const { - return _prev_EMCP_method_handles; - } -}; - - -// Helper object for walking previous versions. This helper cleans up -// the Handles that it allocates when the helper object is destroyed. -// The PreviousVersionInfo object returned by next_previous_version() -// is only valid until a subsequent call to next_previous_version() or -// the helper object is destroyed. +// Helper object for walking previous versions. class PreviousVersionWalker : public StackObj { private: + Thread* _thread; GrowableArray* _previous_versions; int _current_index; - // Fields for cleaning up when we are done walking the previous versions: - // A HandleMark for the PreviousVersionInfo handles: - HandleMark _hm; - // It would be nice to have a ResourceMark field in this helper also, - // but the ResourceMark code says to be careful to delete handles held - // in GrowableArrays _before_ deleting the GrowableArray. Since we - // can't guarantee the order in which the fields are destroyed, we - // have to let the creator of the PreviousVersionWalker object do - // the right thing. Also, adding a ResourceMark here causes an - // include loop. + // A pointer to the current node object so we can handle the deletes. + PreviousVersionNode* _current_p; - // A pointer to the current info object so we can handle the deletes. - PreviousVersionInfo * _current_p; + // The constant pool handle keeps all the methods in this class from being + // deallocated from the metaspace during class unloading. + constantPoolHandle _current_constant_pool_handle; public: - PreviousVersionWalker(InstanceKlass *ik); - ~PreviousVersionWalker(); + PreviousVersionWalker(Thread* thread, InstanceKlass *ik); // Return the interesting information for the next previous version // of the klass. Returns NULL if there are no more previous versions. - PreviousVersionInfo* next_previous_version(); + PreviousVersionNode* next_previous_version(); }; diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index caed2d13612..e138df82a24 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1835,16 +1835,27 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, } JVM_END -JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) -{ - JVMWrapper("JVM_GetClassDeclaredMethods"); +static bool select_method(methodHandle method, bool want_constructor) { + if (want_constructor) { + return (method->is_initializer() && !method->is_static()); + } else { + return (!method->is_initializer() && !method->is_overpass()); + } +} + +static jobjectArray get_class_declared_methods_helper( + JNIEnv *env, + jclass ofClass, jboolean publicOnly, + bool want_constructor, + Klass* klass, TRAPS) { + JvmtiVMObjectAllocEventCollector oam; // Exclude primitive types and array types if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { // Return empty array - oop res = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), 0, CHECK_NULL); + oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL); return (jobjectArray) JNIHandles::make_local(env, res); } @@ -1855,87 +1866,67 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, Array* methods = k->methods(); int methods_length = methods->length(); + + // Save original method_idnum in case of redefinition, which can change + // the idnum of obsolete methods. The new method will have the same idnum + // but if we refresh the methods array, the counts will be wrong. + ResourceMark rm(THREAD); + GrowableArray* idnums = new GrowableArray(methods_length); int num_methods = 0; - int i; - for (i = 0; i < methods_length; i++) { + for (int i = 0; i < methods_length; i++) { methodHandle method(THREAD, methods->at(i)); - if (!method->is_initializer() && !method->is_overpass()) { + if (select_method(method, want_constructor)) { if (!publicOnly || method->is_public()) { + idnums->push(method->method_idnum()); ++num_methods; } } } // Allocate result - objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), num_methods, CHECK_NULL); + objArrayOop r = oopFactory::new_objArray(klass, num_methods, CHECK_NULL); objArrayHandle result (THREAD, r); - int out_idx = 0; - for (i = 0; i < methods_length; i++) { - methodHandle method(THREAD, methods->at(i)); - if (!method->is_initializer() && !method->is_overpass()) { - if (!publicOnly || method->is_public()) { - oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); - result->obj_at_put(out_idx, m); - ++out_idx; + // Now just put the methods that we selected above, but go by their idnum + // in case of redefinition. The methods can be redefined at any safepoint, + // so above when allocating the oop array and below when creating reflect + // objects. + for (int i = 0; i < num_methods; i++) { + methodHandle method(THREAD, k->method_with_idnum(idnums->at(i))); + if (method.is_null()) { + // Method may have been deleted and seems this API can handle null + // Otherwise should probably put a method that throws NSME + result->obj_at_put(i, NULL); + } else { + oop m; + if (want_constructor) { + m = Reflection::new_constructor(method, CHECK_NULL); + } else { + m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); } + result->obj_at_put(i, m); } } - assert(out_idx == num_methods, "just checking"); + return (jobjectArray) JNIHandles::make_local(env, result()); } + +JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) +{ + JVMWrapper("JVM_GetClassDeclaredMethods"); + return get_class_declared_methods_helper(env, ofClass, publicOnly, + /*want_constructor*/ false, + SystemDictionary::reflect_Method_klass(), THREAD); +} JVM_END JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)) { JVMWrapper("JVM_GetClassDeclaredConstructors"); - JvmtiVMObjectAllocEventCollector oam; - - // Exclude primitive types and array types - if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) - || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { - // Return empty array - oop res = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0 , CHECK_NULL); - return (jobjectArray) JNIHandles::make_local(env, res); - } - - instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); - - // Ensure class is linked - k->link_class(CHECK_NULL); - - Array* methods = k->methods(); - int methods_length = methods->length(); - int num_constructors = 0; - - int i; - for (i = 0; i < methods_length; i++) { - methodHandle method(THREAD, methods->at(i)); - if (method->is_initializer() && !method->is_static()) { - if (!publicOnly || method->is_public()) { - ++num_constructors; - } - } - } - - // Allocate result - objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), num_constructors, CHECK_NULL); - objArrayHandle result(THREAD, r); - - int out_idx = 0; - for (i = 0; i < methods_length; i++) { - methodHandle method(THREAD, methods->at(i)); - if (method->is_initializer() && !method->is_static()) { - if (!publicOnly || method->is_public()) { - oop m = Reflection::new_constructor(method, CHECK_NULL); - result->obj_at_put(out_idx, m); - ++out_idx; - } - } - } - assert(out_idx == num_constructors, "just checking"); - return (jobjectArray) JNIHandles::make_local(env, result()); + return get_class_declared_methods_helper(env, ofClass, publicOnly, + /*want_constructor*/ true, + SystemDictionary::reflect_Constructor_klass(), THREAD); } JVM_END diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.cpp b/hotspot/src/share/vm/prims/jvmtiImpl.cpp index 6f8b41297a4..0fcd1ba94ed 100644 --- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp +++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp @@ -273,59 +273,49 @@ void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { // add/remove breakpoint to/from versions of the method that // are EMCP. Directly or transitively obsolete methods are - // not saved in the PreviousVersionInfo. + // not saved in the PreviousVersionNodes. Thread *thread = Thread::current(); instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); Symbol* m_name = _method->name(); Symbol* m_signature = _method->signature(); - { - ResourceMark rm(thread); - // PreviousVersionInfo objects returned via PreviousVersionWalker - // contain a GrowableArray of handles. We have to clean up the - // GrowableArray _after_ the PreviousVersionWalker destructor - // has destroyed the handles. - { - // search previous versions if they exist - PreviousVersionWalker pvw((InstanceKlass *)ikh()); - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); - pv_info != NULL; pv_info = pvw.next_previous_version()) { - GrowableArray* methods = - pv_info->prev_EMCP_method_handles(); + // search previous versions if they exist + PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh()); + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); + pv_node != NULL; pv_node = pvw.next_previous_version()) { + GrowableArray* methods = pv_node->prev_EMCP_methods(); - if (methods == NULL) { - // We have run into a PreviousVersion generation where - // all methods were made obsolete during that generation's - // RedefineClasses() operation. At the time of that - // operation, all EMCP methods were flushed so we don't - // have to go back any further. - // - // A NULL methods array is different than an empty methods - // array. We cannot infer any optimizations about older - // generations from an empty methods array for the current - // generation. - break; - } + if (methods == NULL) { + // We have run into a PreviousVersion generation where + // all methods were made obsolete during that generation's + // RedefineClasses() operation. At the time of that + // operation, all EMCP methods were flushed so we don't + // have to go back any further. + // + // A NULL methods array is different than an empty methods + // array. We cannot infer any optimizations about older + // generations from an empty methods array for the current + // generation. + break; + } - for (int i = methods->length() - 1; i >= 0; i--) { - methodHandle method = methods->at(i); - // obsolete methods that are running are not deleted from - // previous version array, but they are skipped here. - if (!method->is_obsolete() && - method->name() == m_name && - method->signature() == m_signature) { - RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", - meth_act == &Method::set_breakpoint ? "sett" : "clear", - method->name()->as_C_string(), - method->signature()->as_C_string())); + for (int i = methods->length() - 1; i >= 0; i--) { + Method* method = methods->at(i); + // obsolete methods that are running are not deleted from + // previous version array, but they are skipped here. + if (!method->is_obsolete() && + method->name() == m_name && + method->signature() == m_signature) { + RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", + meth_act == &Method::set_breakpoint ? "sett" : "clear", + method->name()->as_C_string(), + method->signature()->as_C_string())); - ((Method*)method()->*meth_act)(_bci); - break; - } - } + (method->*meth_act)(_bci); + break; } - } // pvw is cleaned up - } // rm is cleaned up + } + } } void JvmtiBreakpoint::set() { diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp index 6894ec3f1f4..60bf9c4bdb5 100644 --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp @@ -2807,28 +2807,20 @@ void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { &trace_name_printed); } } - { - ResourceMark rm(_thread); - // PreviousVersionInfo objects returned via PreviousVersionWalker - // contain a GrowableArray of handles. We have to clean up the - // GrowableArray _after_ the PreviousVersionWalker destructor - // has destroyed the handles. - { - // the previous versions' constant pool caches may need adjustment - PreviousVersionWalker pvw(ik); - for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); - pv_info != NULL; pv_info = pvw.next_previous_version()) { - other_cp = pv_info->prev_constant_pool_handle(); - cp_cache = other_cp->cache(); - if (cp_cache != NULL) { - cp_cache->adjust_method_entries(_matching_old_methods, - _matching_new_methods, - _matching_methods_length, - &trace_name_printed); - } - } - } // pvw is cleaned up - } // rm is cleaned up + + // the previous versions' constant pool caches may need adjustment + PreviousVersionWalker pvw(_thread, ik); + for (PreviousVersionNode * pv_node = pvw.next_previous_version(); + pv_node != NULL; pv_node = pvw.next_previous_version()) { + other_cp = pv_node->prev_constant_pool(); + cp_cache = other_cp->cache(); + if (cp_cache != NULL) { + cp_cache->adjust_method_entries(_matching_old_methods, + _matching_new_methods, + _matching_methods_length, + &trace_name_printed); + } + } } } @@ -2942,10 +2934,9 @@ void VM_RedefineClasses::check_methods_and_mark_as_obsolete( // obsolete methods need a unique idnum u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum(); if (num != ConstMethod::UNSET_IDNUM) { -// u2 old_num = old_method->method_idnum(); old_method->set_method_idnum(num); -// TO DO: attach obsolete annotations to obsolete method's new idnum } + // With tracing we try not to "yack" too much. The position of // this trace assumes there are fewer obsolete methods than // EMCP methods. diff --git a/hotspot/src/share/vm/runtime/handles.hpp b/hotspot/src/share/vm/runtime/handles.hpp index dc254227971..c2ce4b38c5a 100644 --- a/hotspot/src/share/vm/runtime/handles.hpp +++ b/hotspot/src/share/vm/runtime/handles.hpp @@ -136,7 +136,7 @@ DEF_HANDLE(typeArray , is_typeArray ) // Specific Handles for different oop types #define DEF_METADATA_HANDLE(name, type) \ class name##Handle; \ - class name##Handle { \ + class name##Handle : public StackObj { \ type* _value; \ Thread* _thread; \ protected: \ @@ -175,7 +175,7 @@ DEF_METADATA_HANDLE(constantPool, ConstantPool) // Writing this class explicitly, since DEF_METADATA_HANDLE(klass) doesn't // provide the necessary Klass* <-> Klass* conversions. This Klass // could be removed when we don't have the Klass* typedef anymore. -class KlassHandle { +class KlassHandle : public StackObj { Klass* _value; protected: Klass* obj() const { return _value; } diff --git a/hotspot/src/share/vm/runtime/handles.inline.hpp b/hotspot/src/share/vm/runtime/handles.inline.hpp index 9530b127aea..5a0f3f773c2 100644 --- a/hotspot/src/share/vm/runtime/handles.inline.hpp +++ b/hotspot/src/share/vm/runtime/handles.inline.hpp @@ -79,6 +79,7 @@ inline name##Handle::name##Handle(const name##Handle &h) { \ } else { \ _thread = Thread::current(); \ } \ + assert (_thread->is_in_stack((address)this), "not on stack?"); \ _thread->metadata_handles()->push((Metadata*)_value); \ } else { \ _thread = NULL; \ @@ -95,6 +96,7 @@ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ } else { \ _thread = Thread::current(); \ } \ + assert (_thread->is_in_stack((address)this), "not on stack?"); \ _thread->metadata_handles()->push((Metadata*)_value); \ } else { \ _thread = NULL; \ From 9f6d1df7471c00374d81685f3dfd7a8fe3b1c978 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Fri, 20 Sep 2013 16:33:35 +0200 Subject: [PATCH 152/293] 8023835: TreeMaker.QualIdent() too leafy Reviewed-by: jjg --- .../com/sun/tools/javac/tree/TreeMaker.java | 1 + .../test/tools/javac/tree/MakeQualIdent.java | 77 ++++++++++++ .../test/tools/javac/tree/ScopeTest.java | 114 ++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 langtools/test/tools/javac/tree/MakeQualIdent.java create mode 100644 langtools/test/tools/javac/tree/ScopeTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 4e6ef7ba6ff..b39fd06471e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -946,6 +946,7 @@ public class TreeMaker implements JCTree.Factory { boolean isUnqualifiable(Symbol sym) { if (sym.name == names.empty || sym.owner == null || + sym.owner == syms.rootPackage || sym.owner.kind == MTH || sym.owner.kind == VAR) { return true; } else if (sym.kind == TYP && toplevel != null) { diff --git a/langtools/test/tools/javac/tree/MakeQualIdent.java b/langtools/test/tools/javac/tree/MakeQualIdent.java new file mode 100644 index 00000000000..e4b71179672 --- /dev/null +++ b/langtools/test/tools/javac/tree/MakeQualIdent.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8023835 + * @summary Verify that TreeMaker.QualIdent(Symbol) field access cascade ends with + * the top-level package (when no toplevel is set in TreeMaker) + * @run main MakeQualIdent + */ + +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import java.util.ArrayList; + +public class MakeQualIdent { + public static void main(String... args) throws Exception { + JavacTool tool = JavacTool.create(); + JavacTask task = tool.getTask(null, null, null, new ArrayList(), null, null); + Context ctx = ((JavacTaskImpl)task).getContext(); + TreeMaker treeMaker = TreeMaker.instance(ctx); + Symtab syms = Symtab.instance(ctx); + + String stringTree = printTree(treeMaker.QualIdent(syms.stringType.tsym)); + + if (!"java.lang.String".equals(stringTree)) { + throw new IllegalStateException(stringTree); + } + } + + private static String printTree(Tree tree) { + final StringBuilder result = new StringBuilder(); + + new TreeScanner() { + @Override public Void visitIdentifier(IdentifierTree node, Void p) { + result.append(node.getName()); + return super.visitIdentifier(node, p); + } + @Override public Void visitMemberSelect(MemberSelectTree node, Void p) { + scan(node.getExpression(), null); + result.append("."); + result.append(node.getIdentifier()); + return null; + } + }.scan(tree, null); + + return result.toString(); + } +} diff --git a/langtools/test/tools/javac/tree/ScopeTest.java b/langtools/test/tools/javac/tree/ScopeTest.java new file mode 100644 index 00000000000..5df625eacd0 --- /dev/null +++ b/langtools/test/tools/javac/tree/ScopeTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8023835 + * @summary Verify that implicit type of lambda parameter is correctly attributed + * in Scope + * @run main ScopeTest + */ + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Scope; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.model.JavacTypes; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import javax.lang.model.element.Element; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.SimpleJavaFileObject; + +public class ScopeTest { + + private static final String SOURCE_CODE = + "public class Test {\n" + + " private static void test() {\n" + + " InvokeOn f = null;\n" + + " f.run(x -> { x.correct(); });\n" + + " }\n" + + " public static final class FooBar {\n" + + " public void dontRun() { }\n" + + " }\n" + + "}\n" + + "class InvokeOn {\n" + + " public void run(I i) { }\n" + + "}\n" + + "class FooBar {\n" + + " public void correct() { }\n" + + "}\n" + + "interface I {\n" + + " public void run(FooBar f);\n" + + "}"; + + public static void main(String... args) throws Exception { + verifyLambdaScopeCorrect(""); + verifyLambdaScopeCorrect("package test;"); + } + + private static void verifyLambdaScopeCorrect(final String packageClause) throws Exception { + JavacTool tool = JavacTool.create(); + JavaFileObject source = new SimpleJavaFileObject(URI.create("mem://Test.java"), Kind.SOURCE) { + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return packageClause + SOURCE_CODE; + } + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + return true; + } + }; + Iterable fos = Collections.singletonList(source); + JavacTask task = tool.getTask(null, null, null, new ArrayList(), null, fos); + final Types types = JavacTypes.instance(((JavacTaskImpl) task).getContext()); + final Trees trees = Trees.instance(task); + CompilationUnitTree cu = task.parse().iterator().next(); + + task.analyze(); + + new TreePathScanner() { + @Override public Void visitMemberSelect(MemberSelectTree node, Void p) { + if (node.getIdentifier().contentEquals("correct")) { + TypeMirror xType = trees.getTypeMirror(new TreePath(getCurrentPath(), node.getExpression())); + Scope scope = trees.getScope(getCurrentPath()); + for (Element l : scope.getLocalElements()) { + if (!l.getSimpleName().contentEquals("x")) continue; + if (!types.isSameType(xType, l.asType())) { + throw new IllegalStateException("Incorrect variable type in scope: " + l.asType() + "; should be: " + xType); + } + } + } + return super.visitMemberSelect(node, p); + } + }.scan(cu, null); + } +} From f996a92b3bf181e1e4a4cbdf6d53a1fe52b3c1d5 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 20 Sep 2013 20:55:43 +0530 Subject: [PATCH 153/293] 8025147: Trailing comma is not allowed in JSONArray and JSONObject Reviewed-by: hannesw, jlaskey --- .../nashorn/internal/parser/JSONParser.java | 8 ++++ .../runtime/resources/Messages.properties | 1 + nashorn/test/script/basic/JDK-8025147.js | 41 +++++++++++++++++++ .../test/script/basic/JDK-8025147.js.EXPECTED | 6 +++ 4 files changed, 56 insertions(+) create mode 100644 nashorn/test/script/basic/JDK-8025147.js create mode 100644 nashorn/test/script/basic/JDK-8025147.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java index cb14fcdf0b8..51988f6a13a 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java @@ -349,6 +349,10 @@ loop: case COMMARIGHT: next(); + // check for trailing comma - not allowed in JSON + if (type == RBRACKET) { + throw error(AbstractParser.message("trailing.comma.in.json", type.getNameOrType())); + } break; default: @@ -388,6 +392,10 @@ loop: case COMMARIGHT: next(); + // check for trailing comma - not allowed in JSON + if (type == RBRACE) { + throw error(AbstractParser.message("trailing.comma.in.json", type.getNameOrType())); + } break; default: diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 5115e2ce0c7..1a37ba7bf76 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -57,6 +57,7 @@ parser.error.missing.catch.or.finally=Missing catch or finally after try parser.error.regex.unsupported.flag=Unsupported RegExp flag: {0} parser.error.regex.repeated.flag=Repeated RegExp flag: {0} parser.error.regex.syntax={0} +parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON # strict mode error messages parser.error.strict.no.with="with" statement cannot be used in strict mode diff --git a/nashorn/test/script/basic/JDK-8025147.js b/nashorn/test/script/basic/JDK-8025147.js new file mode 100644 index 00000000000..905a1c9c320 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025147.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025147: Trailing comma is not allowed in JSONArray and JSONObject + * + * @test + * @run + */ + +function check(str) { + try { + JSON.parse(str); + fail("should have thrown SyntaxError for " + str); + } catch (e) { + print(e); + } +} + +check("{ \"a\": 333, }"); +check("[ 4343, ]"); diff --git a/nashorn/test/script/basic/JDK-8025147.js.EXPECTED b/nashorn/test/script/basic/JDK-8025147.js.EXPECTED new file mode 100644 index 00000000000..3afb20a8204 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025147.js.EXPECTED @@ -0,0 +1,6 @@ +SyntaxError: Invalid JSON: :1:12 Trailing comma is not allowed in JSON +{ "a": 333, } + ^ +SyntaxError: Invalid JSON: :1:8 Trailing comma is not allowed in JSON +[ 4343, ] + ^ From e259f899133916dd5976e37821a52818b0960506 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Fri, 20 Sep 2013 22:37:08 +0530 Subject: [PATCH 154/293] 8025149: JSON.stringify does not handle 'space' argument as per the spec Reviewed-by: jlaskey, hannesw --- .../nashorn/internal/objects/NativeJSON.java | 33 +++++++------ nashorn/test/script/basic/JDK-8025149.js | 47 +++++++++++++++++++ .../test/script/basic/JDK-8025149.js.EXPECTED | 9 ++++ 3 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025149.js create mode 100644 nashorn/test/script/basic/JDK-8025149.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java index b2fa46d2b52..344b6da90d9 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java @@ -162,22 +162,27 @@ public final class NativeJSON extends ScriptObject { String gap; - if (space instanceof Number || space instanceof NativeNumber) { - int indent; - if (space instanceof NativeNumber) { - indent = ((NativeNumber)space).intValue(); + // modifiable 'space' - parameter is final + Object modSpace = space; + if (modSpace instanceof NativeNumber) { + modSpace = JSType.toNumber(JSType.toPrimitive(modSpace, Number.class)); + } else if (modSpace instanceof NativeString) { + modSpace = JSType.toString(JSType.toPrimitive(modSpace, String.class)); + } + + if (modSpace instanceof Number) { + int indent = Math.min(10, JSType.toInteger(modSpace)); + if (indent < 1) { + gap = ""; } else { - indent = ((Number)space).intValue(); + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) { + sb.append(' '); + } + gap = sb.toString(); } - - final StringBuilder sb = new StringBuilder(); - for (int i = 0; i < Math.min(10, indent); i++) { - sb.append(' '); - } - gap = sb.toString(); - - } else if (space instanceof String || space instanceof ConsString || space instanceof NativeString) { - final String str = (space instanceof String) ? (String)space : space.toString(); + } else if (modSpace instanceof String || modSpace instanceof ConsString) { + final String str = modSpace.toString(); gap = str.substring(0, Math.min(10, str.length())); } else { gap = ""; diff --git a/nashorn/test/script/basic/JDK-8025149.js b/nashorn/test/script/basic/JDK-8025149.js new file mode 100644 index 00000000000..b1d33a1a3ce --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025149.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025149: JSON.stringify does not handle 'space' argument as per the spec. + * + * @test + * @run + */ + +print(JSON.stringify({ foo : 23, bar: { x : 22} }, undefined ,new Number(Infinity))); + +print(JSON.stringify({ foo : 23, bar: { x : 22} }, undefined ,new Number(-Infinity))); + +try { + JSON.stringify({},[], + (n = new Number(0), n.valueOf = function() { throw ("inside n.valueOf") }, n)); +} catch (e) { + print(e); +} + +try { + JSON.stringify({},[], + (s = new String(""), s.toString = function() { throw ("inside s.toString") }, s)); +} catch (e) { + print(e); +} diff --git a/nashorn/test/script/basic/JDK-8025149.js.EXPECTED b/nashorn/test/script/basic/JDK-8025149.js.EXPECTED new file mode 100644 index 00000000000..10fd8641cbc --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025149.js.EXPECTED @@ -0,0 +1,9 @@ +{ + "foo": 23, + "bar": { + "x": 22 + } +} +{"foo":23,"bar":{"x":22}} +inside n.valueOf +inside s.toString From 0f9d70232f18cf1b9f233c8cd22c67140f4894bb Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 20 Sep 2013 11:09:26 -0700 Subject: [PATCH 155/293] Added tag hs25-b51 for changeset e446e24611f9 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 024f5b4d0ee..d218a0c962d 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -378,3 +378,4 @@ aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107 a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 85072013aad46050a362d10ab78e963121c8014c jdk8-b108 +566db1b0e6efca31f181456e54c8911d0192410d hs25-b51 From c368a33bf7c9aa2b62a82937f40bbfba68ed86fc Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 20 Sep 2013 11:17:04 -0700 Subject: [PATCH 156/293] 8025127: new hotspot build - hs25-b52 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index fa4d6554e16..dc0872c1db3 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=51 +HS_BUILD_NUMBER=52 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From 3f2082ef809c6f4827d70ebcfeba3a36b9632e74 Mon Sep 17 00:00:00 2001 From: Bill Pittore Date: Fri, 20 Sep 2013 15:06:23 -0400 Subject: [PATCH 157/293] 8014911: Should use SUPPORTS_NATIVE_CX8 define to help C/C++ compiler elide blocks of code If SUPPORTS_NATIVE_CX8 true then supports_cx8() function hard coded to return 'true' Reviewed-by: kvn, twisti, dholmes --- hotspot/src/share/vm/runtime/vm_version.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/runtime/vm_version.hpp b/hotspot/src/share/vm/runtime/vm_version.hpp index c901b260de5..f03b77ca326 100644 --- a/hotspot/src/share/vm/runtime/vm_version.hpp +++ b/hotspot/src/share/vm/runtime/vm_version.hpp @@ -78,7 +78,13 @@ class Abstract_VM_Version: AllStatic { static const char* jre_release_version(); // does HW support an 8-byte compare-exchange operation? - static bool supports_cx8() {return _supports_cx8;} + static bool supports_cx8() { +#ifdef SUPPORTS_NATIVE_CX8 + return true; +#else + return _supports_cx8; +#endif + } // does HW support atomic get-and-set or atomic get-and-add? Used // to guide intrinsification decisions for Unsafe atomic ops static bool supports_atomic_getset4() {return _supports_atomic_getset4;} From 42589e0f11eac8224f59fe01496aa30a5ba4f81d Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 20 Sep 2013 18:34:00 -0400 Subject: [PATCH 158/293] 8014956: nashorn/api/javaaccess/MethodAccessTest.java test fails on sparc-solaris 64 Reference_map[] array had uninitialized junk that was causing a bogus bootstrap method to be found. Reviewed-by: hseigel, dcubed, sspitsyn --- hotspot/src/share/vm/oops/constantPool.cpp | 26 ++++++++-------------- hotspot/src/share/vm/oops/constantPool.hpp | 1 - 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 8033d7e3850..82b99d5a1e2 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -108,16 +108,16 @@ objArrayOop ConstantPool::resolved_references() const { void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data, intStack reference_map, int constant_pool_map_length, - TRAPS) { + TRAPS) { // Initialized the resolved object cache. int map_length = reference_map.length(); if (map_length > 0) { // Only need mapping back to constant pool entries. The map isn't used for - // invokedynamic resolved_reference entries. The constant pool cache index - // has the mapping back to both the constant pool and to the resolved - // reference index. + // invokedynamic resolved_reference entries. For invokedynamic entries, + // the constant pool cache index has the mapping back to both the constant + // pool and to the resolved reference index. if (constant_pool_map_length > 0) { - Array* om = MetadataFactory::new_array(loader_data, map_length, CHECK); + Array* om = MetadataFactory::new_array(loader_data, constant_pool_map_length, CHECK); for (int i = 0; i < constant_pool_map_length; i++) { int x = reference_map.at(i); @@ -182,16 +182,9 @@ oop ConstantPool::lock() { int ConstantPool::cp_to_object_index(int cp_index) { // this is harder don't do this so much. - for (int i = 0; i< reference_map()->length(); i++) { - if (reference_map()->at(i) == cp_index) return i; - // Zero entry is divider between constant pool indices for strings, - // method handles and method types. After that the index is a constant - // pool cache index for invokedynamic. Stop when zero (which can never - // be a constant pool index) - if (reference_map()->at(i) == 0) break; - } - // We might not find the index. - return _no_index_sentinel; + int i = reference_map()->find(cp_index); + // We might not find the index for jsr292 call. + return (i < 0) ? _no_index_sentinel : i; } Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { @@ -866,8 +859,7 @@ oop ConstantPool::string_at_impl(constantPoolHandle this_oop, int which, int obj // If the string has already been interned, this entry will be non-null oop str = this_oop->resolved_references()->obj_at(obj_index); if (str != NULL) return str; - - Symbol* sym = this_oop->unresolved_string_at(which); + Symbol* sym = this_oop->unresolved_string_at(which); str = StringTable::intern(sym, CHECK_(NULL)); this_oop->string_at_put(which, obj_index, str); assert(java_lang_String::is_instance(str), "must be string"); diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index eca2dcd9c56..fb64930fb52 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -231,7 +231,6 @@ class ConstantPool : public Metadata { static int cache_offset_in_bytes() { return offset_of(ConstantPool, _cache); } static int pool_holder_offset_in_bytes() { return offset_of(ConstantPool, _pool_holder); } static int resolved_references_offset_in_bytes() { return offset_of(ConstantPool, _resolved_references); } - static int reference_map_offset_in_bytes() { return offset_of(ConstantPool, _reference_map); } // Storing constants From 22272f50435943f0404b126d1695082dbed41a1f Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Sat, 21 Sep 2013 10:09:42 +0200 Subject: [PATCH 159/293] 8025096: Move the ChunkManager instances out of the VirtualSpaceLists Reviewed-by: coleenp, mgerdin, jmasa --- hotspot/src/share/vm/memory/metaspace.cpp | 221 ++++++++++------------ hotspot/src/share/vm/memory/metaspace.hpp | 22 ++- 2 files changed, 116 insertions(+), 127 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 0a741d674ca..8498242e848 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" #include "gc_interface/collectedHeap.hpp" +#include "memory/allocation.hpp" #include "memory/binaryTreeDictionary.hpp" #include "memory/freeList.hpp" #include "memory/collectorPolicy.hpp" @@ -111,7 +112,7 @@ typedef class FreeList ChunkList; // Has three lists of free chunks, and a total size and // count that includes all three -class ChunkManager VALUE_OBJ_CLASS_SPEC { +class ChunkManager : public CHeapObj { // Free list of chunks of different sizes. // SpecializedChunk @@ -158,7 +159,12 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { public: - ChunkManager() : _free_chunks_total(0), _free_chunks_count(0) {} + ChunkManager(size_t specialized_size, size_t small_size, size_t medium_size) + : _free_chunks_total(0), _free_chunks_count(0) { + _free_chunks[SpecializedIndex].set_size(specialized_size); + _free_chunks[SmallIndex].set_size(small_size); + _free_chunks[MediumIndex].set_size(medium_size); + } // add or delete (return) a chunk to the global freelist. Metachunk* chunk_freelist_allocate(size_t word_size); @@ -219,7 +225,7 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC { void locked_print_free_chunks(outputStream* st); void locked_print_sum_free_chunks(outputStream* st); - void print_on(outputStream* st); + void print_on(outputStream* st) const; }; // Used to manage the free list of Metablocks (a block corresponds @@ -276,11 +282,6 @@ class VirtualSpaceNode : public CHeapObj { // VirtualSpace Metachunk* first_chunk() { return (Metachunk*) bottom(); } - void inc_container_count(); -#ifdef ASSERT - uint container_count_slow(); -#endif - public: VirtualSpaceNode(size_t byte_size); @@ -314,8 +315,10 @@ class VirtualSpaceNode : public CHeapObj { void inc_top(size_t word_size) { _top += word_size; } uintx container_count() { return _container_count; } + void inc_container_count(); void dec_container_count(); #ifdef ASSERT + uint container_count_slow(); void verify_container_count(); #endif @@ -421,8 +424,6 @@ class VirtualSpaceList : public CHeapObj { VirtualSpaceNode* _virtual_space_list; // virtual space currently being used for allocations VirtualSpaceNode* _current_virtual_space; - // Free chunk list for all other metadata - ChunkManager _chunk_manager; // Can this virtual list allocate >1 spaces? Also, used to determine // whether to allocate unlimited small chunks in this virtual space @@ -475,7 +476,6 @@ class VirtualSpaceList : public CHeapObj { return _current_virtual_space; } - ChunkManager* chunk_manager() { return &_chunk_manager; } bool is_class() const { return _is_class; } // Allocate the first virtualspace. @@ -494,14 +494,7 @@ class VirtualSpaceList : public CHeapObj { void dec_virtual_space_count(); // Unlink empty VirtualSpaceNodes and free it. - void purge(); - - // Used and capacity in the entire list of virtual spaces. - // These are global values shared by all Metaspaces - size_t capacity_words_sum(); - size_t capacity_bytes_sum() { return capacity_words_sum() * BytesPerWord; } - size_t used_words_sum(); - size_t used_bytes_sum() { return used_words_sum() * BytesPerWord; } + void purge(ChunkManager* chunk_manager); bool contains(const void *ptr); @@ -582,18 +575,12 @@ class SpaceManager : public CHeapObj { // Type of metadata allocated. Metaspace::MetadataType _mdtype; - // Chunk related size - size_t _medium_chunk_bunch; - // List of chunks in use by this SpaceManager. Allocations // are done from the current chunk. The list is used for deallocating // chunks when the SpaceManager is freed. Metachunk* _chunks_in_use[NumberOfInUseLists]; Metachunk* _current_chunk; - // Virtual space where allocation comes from. - VirtualSpaceList* _vs_list; - // Number of small chunks to allocate to a manager // If class space manager, small chunks are unlimited static uint const _small_chunk_limit; @@ -626,7 +613,9 @@ class SpaceManager : public CHeapObj { } Metaspace::MetadataType mdtype() { return _mdtype; } - VirtualSpaceList* vs_list() const { return _vs_list; } + + VirtualSpaceList* vs_list() const { return Metaspace::get_space_list(_mdtype); } + ChunkManager* chunk_manager() const { return Metaspace::get_chunk_manager(_mdtype); } Metachunk* current_chunk() const { return _current_chunk; } void set_current_chunk(Metachunk* v) { @@ -648,18 +637,19 @@ class SpaceManager : public CHeapObj { public: SpaceManager(Metaspace::MetadataType mdtype, - Mutex* lock, - VirtualSpaceList* vs_list); + Mutex* lock); ~SpaceManager(); enum ChunkMultiples { MediumChunkMultiple = 4 }; + bool is_class() { return _mdtype == Metaspace::ClassType; } + // Accessors size_t specialized_chunk_size() { return SpecializedChunk; } - size_t small_chunk_size() { return (size_t) vs_list()->is_class() ? ClassSmallChunk : SmallChunk; } - size_t medium_chunk_size() { return (size_t) vs_list()->is_class() ? ClassMediumChunk : MediumChunk; } + size_t small_chunk_size() { return (size_t) is_class() ? ClassSmallChunk : SmallChunk; } + size_t medium_chunk_size() { return (size_t) is_class() ? ClassMediumChunk : MediumChunk; } size_t medium_chunk_bunch() { return medium_chunk_size() * MediumChunkMultiple; } size_t allocated_blocks_words() const { return _allocated_blocks_words; } @@ -762,7 +752,7 @@ void VirtualSpaceNode::inc_container_count() { _container_count++; assert(_container_count == container_count_slow(), err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT - "container_count_slow() " SIZE_FORMAT, + " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); } @@ -775,7 +765,7 @@ void VirtualSpaceNode::dec_container_count() { void VirtualSpaceNode::verify_container_count() { assert(_container_count == container_count_slow(), err_msg("Inconsistency in countainer_count _container_count " SIZE_FORMAT - "container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); + " container_count_slow() " SIZE_FORMAT, _container_count, container_count_slow())); } #endif @@ -1020,7 +1010,7 @@ void ChunkManager::remove_chunk(Metachunk* chunk) { // Walk the list of VirtualSpaceNodes and delete // nodes with a 0 container_count. Remove Metachunks in // the node from their respective freelists. -void VirtualSpaceList::purge() { +void VirtualSpaceList::purge(ChunkManager* chunk_manager) { assert_lock_strong(SpaceManager::expand_lock()); // Don't use a VirtualSpaceListIterator because this // list is being changed and a straightforward use of an iterator is not safe. @@ -1042,7 +1032,7 @@ void VirtualSpaceList::purge() { prev_vsl->set_next(vsl->next()); } - vsl->purge(chunk_manager()); + vsl->purge(chunk_manager); dec_reserved_words(vsl->reserved_words()); dec_committed_words(vsl->committed_words()); dec_virtual_space_count(); @@ -1064,36 +1054,6 @@ void VirtualSpaceList::purge() { #endif } -size_t VirtualSpaceList::used_words_sum() { - size_t allocated_by_vs = 0; - VirtualSpaceListIterator iter(virtual_space_list()); - while (iter.repeat()) { - VirtualSpaceNode* vsl = iter.get_next(); - // Sum used region [bottom, top) in each virtualspace - allocated_by_vs += vsl->used_words_in_vs(); - } - assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(), - err_msg("Total in free chunks " SIZE_FORMAT - " greater than total from virtual_spaces " SIZE_FORMAT, - allocated_by_vs, chunk_manager()->free_chunks_total_words())); - size_t used = - allocated_by_vs - chunk_manager()->free_chunks_total_words(); - return used; -} - -// Space available in all MetadataVirtualspaces allocated -// for metadata. This is the upper limit on the capacity -// of chunks allocated out of all the MetadataVirtualspaces. -size_t VirtualSpaceList::capacity_words_sum() { - size_t capacity = 0; - VirtualSpaceListIterator iter(virtual_space_list()); - while (iter.repeat()) { - VirtualSpaceNode* vsl = iter.get_next(); - capacity += vsl->capacity_words_in_vs(); - } - return capacity; -} - VirtualSpaceList::VirtualSpaceList(size_t word_size ) : _is_class(false), _virtual_space_list(NULL), @@ -1104,10 +1064,6 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) : MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); bool initialization_succeeded = grow_vs(word_size); - - _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk); - _chunk_manager.free_chunks(SmallIndex)->set_size(SmallChunk); - _chunk_manager.free_chunks(MediumIndex)->set_size(MediumChunk); assert(initialization_succeeded, " VirtualSpaceList initialization should not fail"); } @@ -1123,9 +1079,6 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) : Mutex::_no_safepoint_check_flag); VirtualSpaceNode* class_entry = new VirtualSpaceNode(rs); bool succeeded = class_entry->initialize(); - _chunk_manager.free_chunks(SpecializedIndex)->set_size(SpecializedChunk); - _chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk); - _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk); assert(succeeded, " VirtualSpaceList initialization should not fail"); link_vs(class_entry); } @@ -1195,15 +1148,8 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, size_t grow_chunks_by_words, size_t medium_chunk_bunch) { - // Get a chunk from the chunk freelist - Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); - - if (next != NULL) { - next->container()->inc_container_count(); - } else { - // Allocate a chunk out of the current virtual space. - next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); - } + // Allocate a chunk out of the current virtual space. + Metachunk* next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words); if (next == NULL) { // Not enough room in current virtual space. Try to commit @@ -1537,15 +1483,15 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm, if (dummy_chunk == NULL) { break; } - vsl->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); + sm->chunk_manager()->chunk_freelist_deallocate(dummy_chunk); if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print("Metadebug::deallocate_chunk_a_lot: %d) ", sm->sum_count_in_chunks_in_use()); dummy_chunk->print_on(gclog_or_tty); gclog_or_tty->print_cr(" Free chunks total %d count %d", - vsl->chunk_manager()->free_chunks_total_words(), - vsl->chunk_manager()->free_chunks_count()); + sm->chunk_manager()->free_chunks_total_words(), + sm->chunk_manager()->free_chunks_count()); } } } else { @@ -1797,6 +1743,8 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) { // work. chunk->set_is_free(false); #endif + chunk->container()->inc_container_count(); + slow_locked_verify(); return chunk; } @@ -1831,9 +1779,9 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) { return chunk; } -void ChunkManager::print_on(outputStream* out) { +void ChunkManager::print_on(outputStream* out) const { if (PrintFLSStatistics != 0) { - humongous_dictionary()->report_statistics(); + const_cast(this)->humongous_dictionary()->report_statistics(); } } @@ -1980,8 +1928,8 @@ void SpaceManager::locked_print_chunks_in_use_on(outputStream* st) const { } } - vs_list()->chunk_manager()->locked_print_free_chunks(st); - vs_list()->chunk_manager()->locked_print_sum_free_chunks(st); + chunk_manager()->locked_print_free_chunks(st); + chunk_manager()->locked_print_sum_free_chunks(st); } size_t SpaceManager::calc_chunk_size(size_t word_size) { @@ -2085,9 +2033,7 @@ void SpaceManager::print_on(outputStream* st) const { } SpaceManager::SpaceManager(Metaspace::MetadataType mdtype, - Mutex* lock, - VirtualSpaceList* vs_list) : - _vs_list(vs_list), + Mutex* lock) : _mdtype(mdtype), _allocated_blocks_words(0), _allocated_chunks_words(0), @@ -2173,9 +2119,7 @@ SpaceManager::~SpaceManager() { MutexLockerEx fcl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - ChunkManager* chunk_manager = vs_list()->chunk_manager(); - - chunk_manager->slow_locked_verify(); + chunk_manager()->slow_locked_verify(); dec_total_from_size_metrics(); @@ -2189,8 +2133,8 @@ SpaceManager::~SpaceManager() { // Have to update before the chunks_in_use lists are emptied // below. - chunk_manager->inc_free_chunks_total(allocated_chunks_words(), - sum_count_in_chunks_in_use()); + chunk_manager()->inc_free_chunks_total(allocated_chunks_words(), + sum_count_in_chunks_in_use()); // Add all the chunks in use by this space manager // to the global list of free chunks. @@ -2205,11 +2149,11 @@ SpaceManager::~SpaceManager() { chunk_size_name(i)); } Metachunk* chunks = chunks_in_use(i); - chunk_manager->return_chunks(i, chunks); + chunk_manager()->return_chunks(i, chunks); set_chunks_in_use(i, NULL); if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print_cr("updated freelist count %d %s", - chunk_manager->free_chunks(i)->count(), + chunk_manager()->free_chunks(i)->count(), chunk_size_name(i)); } assert(i != HumongousIndex, "Humongous chunks are handled explicitly later"); @@ -2246,16 +2190,16 @@ SpaceManager::~SpaceManager() { humongous_chunks->word_size(), HumongousChunkGranularity)); Metachunk* next_humongous_chunks = humongous_chunks->next(); humongous_chunks->container()->dec_container_count(); - chunk_manager->humongous_dictionary()->return_chunk(humongous_chunks); + chunk_manager()->humongous_dictionary()->return_chunk(humongous_chunks); humongous_chunks = next_humongous_chunks; } if (TraceMetadataChunkAllocation && Verbose) { gclog_or_tty->print_cr(""); gclog_or_tty->print_cr("updated dictionary count %d %s", - chunk_manager->humongous_dictionary()->total_count(), + chunk_manager()->humongous_dictionary()->total_count(), chunk_size_name(HumongousIndex)); } - chunk_manager->slow_locked_verify(); + chunk_manager()->slow_locked_verify(); } const char* SpaceManager::chunk_size_name(ChunkIndex index) const { @@ -2344,9 +2288,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) { gclog_or_tty->print("SpaceManager::add_chunk: %d) ", sum_count_in_chunks_in_use()); new_chunk->print_on(gclog_or_tty); - if (vs_list() != NULL) { - vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty); - } + chunk_manager()->locked_print_free_chunks(gclog_or_tty); } } @@ -2362,10 +2304,14 @@ void SpaceManager::retire_current_chunk() { Metachunk* SpaceManager::get_new_chunk(size_t word_size, size_t grow_chunks_by_words) { + // Get a chunk from the chunk freelist + Metachunk* next = chunk_manager()->chunk_freelist_allocate(grow_chunks_by_words); - Metachunk* next = vs_list()->get_new_chunk(word_size, - grow_chunks_by_words, - medium_chunk_bunch()); + if (next == NULL) { + next = vs_list()->get_new_chunk(word_size, + grow_chunks_by_words, + medium_chunk_bunch()); + } if (TraceMetadataHumongousAllocation && next != NULL && SpaceManager::is_humongous(next->word_size())) { @@ -2645,13 +2591,12 @@ size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) { size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); } size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) { - VirtualSpaceList* list = Metaspace::get_space_list(mdtype); - if (list == NULL) { + ChunkManager* chunk_manager = Metaspace::get_chunk_manager(mdtype); + if (chunk_manager == NULL) { return 0; } - ChunkManager* chunk = list->chunk_manager(); - chunk->slow_verify(); - return chunk->free_chunks_total_words(); + chunk_manager->slow_verify(); + return chunk_manager->free_chunks_total_words(); } size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) { @@ -2802,9 +2747,9 @@ void MetaspaceAux::dump(outputStream* out) { } void MetaspaceAux::verify_free_chunks() { - Metaspace::space_list()->chunk_manager()->verify(); + Metaspace::chunk_manager_metadata()->verify(); if (Metaspace::using_class_space()) { - Metaspace::class_space_list()->chunk_manager()->verify(); + Metaspace::chunk_manager_class()->verify(); } } @@ -2875,6 +2820,9 @@ Metaspace::~Metaspace() { VirtualSpaceList* Metaspace::_space_list = NULL; VirtualSpaceList* Metaspace::_class_space_list = NULL; +ChunkManager* Metaspace::_chunk_manager_metadata = NULL; +ChunkManager* Metaspace::_chunk_manager_class = NULL; + #define VIRTUALSPACEMULTIPLIER 2 #ifdef _LP64 @@ -2982,6 +2930,7 @@ void Metaspace::initialize_class_space(ReservedSpace rs) { err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize)); assert(using_class_space(), "Must be using class space"); _class_space_list = new VirtualSpaceList(rs); + _chunk_manager_class = new ChunkManager(SpecializedChunk, ClassSmallChunk, ClassMediumChunk); } #endif @@ -3007,6 +2956,7 @@ void Metaspace::global_initialize() { // remainder is the misc code and data chunks. cds_total = FileMapInfo::shared_spaces_size(); _space_list = new VirtualSpaceList(cds_total/wordSize); + _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); #ifdef _LP64 // Set the compressed klass pointer base so that decoding of these pointers works @@ -3074,15 +3024,30 @@ void Metaspace::global_initialize() { size_t word_size = VIRTUALSPACEMULTIPLIER * first_chunk_word_size(); // Initialize the list of virtual spaces. _space_list = new VirtualSpaceList(word_size); + _chunk_manager_metadata = new ChunkManager(SpecializedChunk, SmallChunk, MediumChunk); } } +Metachunk* Metaspace::get_initialization_chunk(MetadataType mdtype, + size_t chunk_word_size, + size_t chunk_bunch) { + // Get a chunk from the chunk freelist + Metachunk* chunk = get_chunk_manager(mdtype)->chunk_freelist_allocate(chunk_word_size); + if (chunk != NULL) { + return chunk; + } + + return get_space_list(mdtype)->get_initialization_chunk(chunk_word_size, chunk_bunch); +} + void Metaspace::initialize(Mutex* lock, MetaspaceType type) { assert(space_list() != NULL, "Metadata VirtualSpaceList has not been initialized"); + assert(chunk_manager_metadata() != NULL, + "Metadata ChunkManager has not been initialized"); - _vsm = new SpaceManager(NonClassType, lock, space_list()); + _vsm = new SpaceManager(NonClassType, lock); if (_vsm == NULL) { return; } @@ -3091,11 +3056,13 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) { vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size); if (using_class_space()) { - assert(class_space_list() != NULL, - "Class VirtualSpaceList has not been initialized"); + assert(class_space_list() != NULL, + "Class VirtualSpaceList has not been initialized"); + assert(chunk_manager_class() != NULL, + "Class ChunkManager has not been initialized"); // Allocate SpaceManager for classes. - _class_vsm = new SpaceManager(ClassType, lock, class_space_list()); + _class_vsm = new SpaceManager(ClassType, lock); if (_class_vsm == NULL) { return; } @@ -3104,9 +3071,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); // Allocate chunk for metadata objects - Metachunk* new_chunk = - space_list()->get_initialization_chunk(word_size, - vsm()->medium_chunk_bunch()); + Metachunk* new_chunk = get_initialization_chunk(NonClassType, + word_size, + vsm()->medium_chunk_bunch()); assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks"); if (new_chunk != NULL) { // Add to this manager's list of chunks in use and current_chunk(). @@ -3115,9 +3082,9 @@ void Metaspace::initialize(Mutex* lock, MetaspaceType type) { // Allocate chunk for class metadata objects if (using_class_space()) { - Metachunk* class_chunk = - class_space_list()->get_initialization_chunk(class_word_size, - class_vsm()->medium_chunk_bunch()); + Metachunk* class_chunk = get_initialization_chunk(ClassType, + class_word_size, + class_vsm()->medium_chunk_bunch()); if (class_chunk != NULL) { class_vsm()->add_chunk(class_chunk, true); } @@ -3334,12 +3301,16 @@ void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) { } } +void Metaspace::purge(MetadataType mdtype) { + get_space_list(mdtype)->purge(get_chunk_manager(mdtype)); +} + void Metaspace::purge() { MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); - space_list()->purge(); + purge(NonClassType); if (using_class_space()) { - class_space_list()->purge(); + purge(ClassType); } } diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 242fa61b1cc..29c07e15179 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -56,12 +56,15 @@ // +-------------------+ // +class ChunkManager; class ClassLoaderData; class Metablock; +class Metachunk; class MetaWord; class Mutex; class outputStream; class SpaceManager; +class VirtualSpaceList; // Metaspaces each have a SpaceManager and allocations // are done by the SpaceManager. Allocations are done @@ -76,8 +79,6 @@ class SpaceManager; // allocate() method returns a block for use as a // quantum of metadata. -class VirtualSpaceList; - class Metaspace : public CHeapObj { friend class VMStructs; friend class SpaceManager; @@ -102,6 +103,10 @@ class Metaspace : public CHeapObj { private: void initialize(Mutex* lock, MetaspaceType type); + Metachunk* get_initialization_chunk(MetadataType mdtype, + size_t chunk_word_size, + size_t chunk_bunch); + // Align up the word size to the allocation word size static size_t align_word_size_up(size_t); @@ -134,6 +139,10 @@ class Metaspace : public CHeapObj { static VirtualSpaceList* _space_list; static VirtualSpaceList* _class_space_list; + static ChunkManager* _chunk_manager_metadata; + static ChunkManager* _chunk_manager_class; + + public: static VirtualSpaceList* space_list() { return _space_list; } static VirtualSpaceList* class_space_list() { return _class_space_list; } static VirtualSpaceList* get_space_list(MetadataType mdtype) { @@ -141,6 +150,14 @@ class Metaspace : public CHeapObj { return mdtype == ClassType ? class_space_list() : space_list(); } + static ChunkManager* chunk_manager_metadata() { return _chunk_manager_metadata; } + static ChunkManager* chunk_manager_class() { return _chunk_manager_class; } + static ChunkManager* get_chunk_manager(MetadataType mdtype) { + assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype"); + return mdtype == ClassType ? chunk_manager_class() : chunk_manager_metadata(); + } + + private: // This is used by DumpSharedSpaces only, where only _vsm is used. So we will // maintain a single list for now. void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size); @@ -199,6 +216,7 @@ class Metaspace : public CHeapObj { void dump(outputStream* const out) const; // Free empty virtualspaces + static void purge(MetadataType mdtype); static void purge(); void print_on(outputStream* st) const; From 1508b37a51e131d470c776a12f155a2a9fadbb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Sat, 21 Sep 2013 10:11:15 +0200 Subject: [PATCH 160/293] 8025163: Date methods should not return -0 Reviewed-by: lagergren, jlaskey --- .../nashorn/internal/objects/NativeDate.java | 128 +++++++++--------- nashorn/test/script/basic/JDK-8025163.js | 39 ++++++ .../test/script/basic/JDK-8025163.js.EXPECTED | 8 ++ 3 files changed, 110 insertions(+), 65 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025163.js create mode 100644 nashorn/test/script/basic/JDK-8025163.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java index 859745f3dca..935285f02ad 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java @@ -75,11 +75,11 @@ public final class NativeDate extends ScriptObject { private static final int FORMAT_LOCAL_TIME = 5; // Constants defined in ECMA 15.9.1.10 - private static final double hoursPerDay = 24; - private static final double minutesPerHour = 60; - private static final double secondsPerMinute = 60; - private static final double msPerSecond = 1_000; - private static final double msPerMinute = 60_000; + private static final int hoursPerDay = 24; + private static final int minutesPerHour = 60; + private static final int secondsPerMinute = 60; + private static final int msPerSecond = 1_000; + private static final int msPerMinute = 60_000; private static final double msPerHour = 3_600_000; private static final double msPerDay = 86_400_000; @@ -926,13 +926,13 @@ public final class NativeDate extends ScriptObject { case FORMAT_DATE : case FORMAT_LOCAL_DATE_TIME: // EEE MMM dd yyyy - sb.append(weekDays[(int) weekDay(t)]) + sb.append(weekDays[weekDay(t)]) .append(' ') - .append(months[(int) monthFromTime(t)]) + .append(months[monthFromTime(t)]) .append(' '); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append(' '); - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); if (format == FORMAT_DATE) { break; } @@ -948,11 +948,11 @@ public final class NativeDate extends ScriptObject { offset = (offset / 60) * 100 + offset % 60; // HH:mm:ss GMT+HHmm - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append(" GMT") .append(offset < 0 ? '-' : '+'); zeroPad(sb, Math.abs(offset), 4); @@ -963,20 +963,20 @@ public final class NativeDate extends ScriptObject { case FORMAT_LOCAL_DATE: // yyyy-MM-dd - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append('-'); - zeroPad(sb, (int) monthFromTime(t) + 1, 2); + zeroPad(sb, monthFromTime(t) + 1, 2); sb.append('-'); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); break; case FORMAT_LOCAL_TIME: // HH:mm:ss - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); break; default: @@ -996,19 +996,19 @@ public final class NativeDate extends ScriptObject { final StringBuilder sb = new StringBuilder(29); final double t = nd.getTime(); // EEE, dd MMM yyyy HH:mm:ss z - sb.append(weekDays[(int) weekDay(t)]) + sb.append(weekDays[weekDay(t)]) .append(", "); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append(' ') - .append(months[(int) monthFromTime(t)]) + .append(months[monthFromTime(t)]) .append(' '); - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append(' '); - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append(" GMT"); return sb.toString(); } @@ -1023,19 +1023,19 @@ public final class NativeDate extends ScriptObject { final StringBuilder sb = new StringBuilder(24); final double t = nd.getTime(); // yyyy-MM-dd'T'HH:mm:ss.SSS'Z' - zeroPad(sb, (int) yearFromTime(t), 4); + zeroPad(sb, yearFromTime(t), 4); sb.append('-'); - zeroPad(sb, (int) monthFromTime(t) + 1, 2); + zeroPad(sb, monthFromTime(t) + 1, 2); sb.append('-'); - zeroPad(sb, (int) dayFromTime(t), 2); + zeroPad(sb, dayFromTime(t), 2); sb.append('T'); - zeroPad(sb, (int) hourFromTime(t), 2); + zeroPad(sb, hourFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) minFromTime(t), 2); + zeroPad(sb, minFromTime(t), 2); sb.append(':'); - zeroPad(sb, (int) secFromTime(t), 2); + zeroPad(sb, secFromTime(t), 2); sb.append('.'); - zeroPad(sb, (int) msFromTime(t), 3); + zeroPad(sb, msFromTime(t), 3); sb.append("Z"); return sb.toString(); } @@ -1072,29 +1072,30 @@ public final class NativeDate extends ScriptObject { } // ECMA 15.9.1.3 Year Number - private static double timeFromYear(final double y) { + private static double timeFromYear(final int y) { return dayFromYear(y) * msPerDay; } - private static double yearFromTime(final double t) { - double y = Math.floor(t / (msPerDay * 365.2425)) + 1970; + // ECMA 15.9.1.3 Year Number + private static int yearFromTime(final double t) { + int y = (int) Math.floor(t / (msPerDay * 365.2425)) + 1970; final double t2 = timeFromYear(y); if (t2 > t) { y--; - } else if (t2 + msPerDay * daysInYear((int) y) <= t) { + } else if (t2 + msPerDay * daysInYear(y) <= t) { y++; } return y; } - private static double dayWithinYear(final double t, final double year) { - return day(t) - dayFromYear(year); + private static int dayWithinYear(final double t, final int year) { + return (int) (day(t) - dayFromYear(year)); } - private static double monthFromTime(final double t) { - final double year = yearFromTime(t); - final double day = dayWithinYear(t, year); - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; + private static int monthFromTime(final double t) { + final int year = yearFromTime(t); + final int day = dayWithinYear(t, year); + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; int month = 0; while (month < 11 && firstDay[month + 1] <= day) { @@ -1103,10 +1104,10 @@ public final class NativeDate extends ScriptObject { return month; } - private static double dayFromTime(final double t) { - final double year = yearFromTime(t); - final double day = dayWithinYear(t, year); - final int[] firstDay = firstDayInMonth[isLeapYear((int) year) ? 1 : 0]; + private static int dayFromTime(final double t) { + final int year = yearFromTime(t); + final int day = dayWithinYear(t, year); + final int[] firstDay = firstDayInMonth[isLeapYear(year) ? 1 : 0]; int month = 0; while (month < 11 && firstDay[month + 1] <= day) { @@ -1121,11 +1122,8 @@ public final class NativeDate extends ScriptObject { return firstDay[month]; } - private static double weekDay(final double time) { - if (isNaN(time)) { - return NaN; - } - final double day = (day(time) + 4) % 7; + private static int weekDay(final double time) { + final int day = (int) (day(time) + 4) % 7; return day < 0 ? day + 7 : day; } @@ -1140,26 +1138,26 @@ public final class NativeDate extends ScriptObject { } // ECMA 15.9.1.10 Hours, Minutes, Second, and Milliseconds - private static double hourFromTime(final double t) { - final double h = Math.floor(t / msPerHour) % hoursPerDay; + private static int hourFromTime(final double t) { + final int h = (int) (Math.floor(t / msPerHour) % hoursPerDay); return h < 0 ? h + hoursPerDay: h; } - private static double minFromTime(final double t) { - final double m = Math.floor(t / msPerMinute) % minutesPerHour; + private static int minFromTime(final double t) { + final int m = (int) (Math.floor(t / msPerMinute) % minutesPerHour); return m < 0 ? m + minutesPerHour : m; } - private static double secFromTime(final double t) { - final double s = Math.floor(t / msPerSecond) % secondsPerMinute; + private static int secFromTime(final double t) { + final int s = (int) (Math.floor(t / msPerSecond) % secondsPerMinute); return s < 0 ? s + secondsPerMinute : s; } - private static double msFromTime(final double t) { - final double m = t % msPerSecond; + private static int msFromTime(final double t) { + final int m = (int) (t % msPerSecond); return m < 0 ? m + msPerSecond : m; } - private static double valueFromTime(final int unit, final double t) { + private static int valueFromTime(final int unit, final double t) { switch (unit) { case YEAR: return yearFromTime(t); case MONTH: return monthFromTime(t); @@ -1180,12 +1178,12 @@ public final class NativeDate extends ScriptObject { // ECMA 15.9.1.12 MakeDay (year, month, date) private static double makeDay(final double year, final double month, final double date) { final double y = year + Math.floor(month / 12); - double m = month % 12; + int m = (int) (month % 12); if (m < 0) { m += 12; } - double d = Math.floor(dayFromYear(y)); - d += dayFromMonth((int) m, (int) y); + double d = dayFromYear(y); + d += dayFromMonth(m, (int) y); return d + date - 1; } @@ -1257,13 +1255,13 @@ public final class NativeDate extends ScriptObject { nullReturn = true; } - if (! nullReturn) { + if (!nullReturn && !isNaN(time)) { d[i - start] = valueFromTime(i, time); } } } - return nullReturn? null : d; + return nullReturn ? null : d; } // ECMA 15.9.1.14 TimeClip (time) diff --git a/nashorn/test/script/basic/JDK-8025163.js b/nashorn/test/script/basic/JDK-8025163.js new file mode 100644 index 00000000000..1eaa98e82c2 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025163.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025163: Date methods should not return -0 + * + * @test + * @run + */ + +print(1 / (new Date(0, 0, 1)).getYear()); +print(1 / (new Date(1969, 1, 2)).getDay()); +print(1 / (new Date(1969, 0, 1)).getHours()); +print(1 / (new Date(1969, 0, 1)).getHours()); +print(1 / (new Date(1969, 0, 1)).getMinutes()); +print(1 / (new Date(1969, 0, 1)).getSeconds()); +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); +print(1 / (new Date(1969, 0, 1)).getMilliseconds()); + diff --git a/nashorn/test/script/basic/JDK-8025163.js.EXPECTED b/nashorn/test/script/basic/JDK-8025163.js.EXPECTED new file mode 100644 index 00000000000..cde7e1933e7 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025163.js.EXPECTED @@ -0,0 +1,8 @@ +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity +Infinity From 70e873ec737ba10be69b27cface7ea50413cad10 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Sun, 22 Sep 2013 12:53:03 +0100 Subject: [PATCH 161/293] 8024696: Missing null check in bound method reference capture Reviewed-by: jjg, briangoetz --- .../sun/tools/javac/comp/LambdaToMethod.java | 4 ++ .../tools/javac/lambda/8023558/T8023558a.java | 8 +++- .../MethodReferenceNullCheckTest.java | 47 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index b2a501d27d6..d22ebfa36e3 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -153,6 +153,8 @@ public class LambdaToMethod extends TreeTranslator { return instance; } + private Attr attr; + private LambdaToMethod(Context context) { diags = JCDiagnostic.Factory.instance(context); log = Log.instance(context); @@ -166,6 +168,7 @@ public class LambdaToMethod extends TreeTranslator { analyzer = new LambdaAnalyzerPreprocessor(); Options options = Options.instance(context); dumpLambdaToMethodStats = options.isSet("dumpLambdaToMethodStats"); + attr = Attr.instance(context); } // @@ -368,6 +371,7 @@ public class LambdaToMethod extends TreeTranslator { case BOUND: /** Expr :: instMethod */ init = tree.getQualifierExpression(); + init = attr.makeNullCheck(init); break; case UNBOUND: /** Type :: instMethod */ diff --git a/langtools/test/tools/javac/lambda/8023558/T8023558a.java b/langtools/test/tools/javac/lambda/8023558/T8023558a.java index 205ff9eefdc..be3ba6494f0 100644 --- a/langtools/test/tools/javac/lambda/8023558/T8023558a.java +++ b/langtools/test/tools/javac/lambda/8023558/T8023558a.java @@ -31,8 +31,14 @@ public class T8023558a { T get(); } + static class K implements SAM { + public T get() { + return (T)this; + } + } + public static void main(String[] args) { - SAM sam = new SAM() { public SAM get() { return null; } }; + SAM sam = new SAM() { public SAM get() { return new K<>(); } }; SAM temp = sam.get()::get; } } diff --git a/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java new file mode 100644 index 00000000000..fd2bf655649 --- /dev/null +++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceNullCheckTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8024696 + * @summary Missing null check in bound method reference capture + */ + +import com.sun.tools.javac.util.Assert; +import java.util.function.*; + +public class MethodReferenceNullCheckTest { + public static void main(String[] args) { + String s = null; + boolean npeFired = false; + try { + Supplier ss = s::isEmpty; + } catch (NullPointerException npe) { + npeFired = true; + } finally { + Assert.check(npeFired, "NPE should have been thrown"); + } + } +} From 5bc8cd08aa15355b35fd273e71d36b710ba99b43 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Sun, 22 Sep 2013 06:31:43 -0700 Subject: [PATCH 162/293] 6989981: jstack causes "fatal error: ExceptionMark destructor expects no pending exceptions" Reviewed-by: sla, dsamersoff --- .../src/share/vm/services/attachListener.cpp | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp index bf002e7fa88..e30c3eeff8c 100644 --- a/hotspot/src/share/vm/services/attachListener.cpp +++ b/hotspot/src/share/vm/services/attachListener.cpp @@ -470,7 +470,17 @@ void AttachListener::init() { vmSymbols::threadgroup_string_void_signature(), thread_group, string, - CHECK); + THREAD); + + if (HAS_PENDING_EXCEPTION) { + tty->print_cr("Exception in VM (AttachListener::init) : "); + java_lang_Throwable::print(PENDING_EXCEPTION, tty); + tty->cr(); + + CLEAR_PENDING_EXCEPTION; + + return; + } KlassHandle group(THREAD, SystemDictionary::ThreadGroup_klass()); JavaCalls::call_special(&result, @@ -479,7 +489,17 @@ void AttachListener::init() { vmSymbols::add_method_name(), vmSymbols::thread_void_signature(), thread_oop, // ARG 1 - CHECK); + THREAD); + + if (HAS_PENDING_EXCEPTION) { + tty->print_cr("Exception in VM (AttachListener::init) : "); + java_lang_Throwable::print(PENDING_EXCEPTION, tty); + tty->cr(); + + CLEAR_PENDING_EXCEPTION; + + return; + } { MutexLocker mu(Threads_lock); JavaThread* listener_thread = new JavaThread(&attach_listener_thread_entry); From 4d6a0655f9a953638db8c5a1fbf6c641dde016f6 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Sun, 22 Sep 2013 18:49:09 +0400 Subject: [PATCH 163/293] 7133122: SA throws sun.jvm.hotspot.debugger.UnmappedAddressException when it should not Replace PT_LOAD segment with library segment when necessary Reviewed-by: dholmes, sla --- hotspot/agent/src/os/linux/ps_core.c | 67 ++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/hotspot/agent/src/os/linux/ps_core.c b/hotspot/agent/src/os/linux/ps_core.c index 85abab802e0..c1620407894 100644 --- a/hotspot/agent/src/os/linux/ps_core.c +++ b/hotspot/agent/src/os/linux/ps_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -698,29 +698,58 @@ err: // read segments of a shared object static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) { - int i = 0; - ELF_PHDR* phbuf; - ELF_PHDR* lib_php = NULL; + int i = 0; + ELF_PHDR* phbuf; + ELF_PHDR* lib_php = NULL; - if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) - return false; + int page_size=sysconf(_SC_PAGE_SIZE); - // we want to process only PT_LOAD segments that are not writable. - // i.e., text segments. The read/write/exec (data) segments would - // have been already added from core file segments. - for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) { - if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { - if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL) - goto err; + if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) { + return false; + } + + // we want to process only PT_LOAD segments that are not writable. + // i.e., text segments. The read/write/exec (data) segments would + // have been already added from core file segments. + for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) { + if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) { + + uintptr_t target_vaddr = lib_php->p_vaddr + lib_base; + map_info *existing_map = core_lookup(ph, target_vaddr); + + if (existing_map == NULL){ + if (add_map_info(ph, lib_fd, lib_php->p_offset, + target_vaddr, lib_php->p_filesz) == NULL) { + goto err; + } + } else { + if ((existing_map->memsz != page_size) && + (existing_map->fd != lib_fd) && + (existing_map->memsz != lib_php->p_filesz)){ + + print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)", + target_vaddr, lib_php->p_filesz, lib_php->p_flags); + goto err; + } + + /* replace PT_LOAD segment with library segment */ + print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n", + existing_map->memsz, lib_php->p_filesz); + + existing_map->fd = lib_fd; + existing_map->offset = lib_php->p_offset; + existing_map->memsz = lib_php->p_filesz; } - lib_php++; - } + } - free(phbuf); - return true; + lib_php++; + } + + free(phbuf); + return true; err: - free(phbuf); - return false; + free(phbuf); + return false; } // process segments from interpreter (ld.so or ld-linux.so) From a2a38c6b65c0f837c3bccb3987b6243d4e189e17 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Mon, 23 Sep 2013 10:10:07 +0200 Subject: [PATCH 164/293] 8024988: javac, LVT test harness should generate tests .class files in the scratch folder Set the CLASS_OUTPUT location to the scratch directory. Changed the argument to checkClassFile accordingly. Reviewed-by: jjg, vromero --- .../test/tools/javac/flow/LVTHarness.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/langtools/test/tools/javac/flow/LVTHarness.java b/langtools/test/tools/javac/flow/LVTHarness.java index 7794ded19dd..9aac87c4f00 100644 --- a/langtools/test/tools/javac/flow/LVTHarness.java +++ b/langtools/test/tools/javac/flow/LVTHarness.java @@ -64,6 +64,7 @@ import com.sun.tools.classfile.Method; import static javax.tools.StandardLocation.*; import static com.sun.tools.classfile.LocalVariableTable_attribute.Entry; +import static javax.tools.JavaFileObject.Kind.SOURCE; public class LVTHarness { @@ -73,10 +74,14 @@ public class LVTHarness { static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); public static void main(String[] args) throws Exception { - fm.setLocation(SOURCE_PATH, - Arrays.asList(new File(System.getProperty("test.src"), "tests"))); - for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", - Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { + + String testDir = System.getProperty("test.src"); + fm.setLocation(SOURCE_PATH, Arrays.asList(new File(testDir, "tests"))); + + // Make sure classes are written to scratch dir. + fm.setLocation(CLASS_OUTPUT, Arrays.asList(new File("."))); + + for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(SOURCE), true)) { new LVTHarness(jfo).check(); } if (nerrors > 0) { @@ -86,8 +91,7 @@ public class LVTHarness { JavaFileObject jfo; - Map aliveRangeMap = - new HashMap(); + Map aliveRangeMap = new HashMap<>(); Set declaredKeys = new HashSet<>(); List seenAliveRanges = new ArrayList<>(); @@ -96,15 +100,19 @@ public class LVTHarness { } protected void check() throws Exception { - JavacTask ct = (JavacTask)comp.getTask(null, fm, null, Arrays.asList("-g"), - null, Arrays.asList(jfo)); - System.err.println("compiling code " + jfo.toString()); + + JavacTask ct = (JavacTask) comp.getTask(null, fm, null, Arrays.asList("-g"), + null, Arrays.asList(jfo)); + System.err.println("compiling code " + jfo); ct.setProcessors(Collections.singleton(new AliveRangeFinder())); if (!ct.call()) { throw new AssertionError("Error during compilation"); } - checkClassFile(new File(jfo.getName().replace(".java", ".class"))); + + File javaFile = new File(jfo.getName()); + File classFile = new File(javaFile.getName().replace(".java", ".class")); + checkClassFile(classFile); //check all candidates have been used up for (Map.Entry entry : aliveRangeMap.entrySet()) { From 48774216f24dfa733f0f53ad0730c5b20d9a06b8 Mon Sep 17 00:00:00 2001 From: Andreas Lundblad Date: Mon, 23 Sep 2013 10:42:38 +0200 Subject: [PATCH 165/293] 6386236: Please rename com.sun.tools.javac.util.ListBuffer.lb() Static factory method ListBuffer.lb removed. Replaced by constructor calls. Reviewed-by: jfranck, jjg --- .../sun/tools/javac/api/JavacTaskImpl.java | 2 +- .../tools/javac/code/DeferredLintHandler.java | 2 +- .../com/sun/tools/javac/code/Printer.java | 4 +-- .../com/sun/tools/javac/code/Symbol.java | 2 +- .../com/sun/tools/javac/code/Type.java | 10 +++--- .../javac/code/TypeAnnotationPosition.java | 4 +-- .../sun/tools/javac/code/TypeAnnotations.java | 12 +++---- .../com/sun/tools/javac/code/Types.java | 31 +++++++++--------- .../com/sun/tools/javac/comp/Attr.java | 16 +++++----- .../com/sun/tools/javac/comp/Check.java | 4 +-- .../sun/tools/javac/comp/DeferredAttr.java | 2 +- .../com/sun/tools/javac/comp/Flow.java | 8 ++--- .../com/sun/tools/javac/comp/Infer.java | 18 +++++------ .../sun/tools/javac/comp/LambdaToMethod.java | 32 +++++++++---------- .../com/sun/tools/javac/comp/Lower.java | 6 ++-- .../com/sun/tools/javac/comp/Resolve.java | 8 ++--- .../com/sun/tools/javac/comp/TransTypes.java | 2 +- .../com/sun/tools/javac/jvm/ClassReader.java | 9 +++--- .../com/sun/tools/javac/jvm/ClassWriter.java | 4 +-- .../classes/com/sun/tools/javac/jvm/Code.java | 2 +- .../sun/tools/javac/main/JavaCompiler.java | 17 +++++----- .../javac/model/JavacAnnoConstructs.java | 4 +-- .../sun/tools/javac/parser/JavacParser.java | 11 +++---- .../com/sun/tools/javac/parser/Tokens.java | 4 +-- .../com/sun/tools/javac/util/GraphUtils.java | 6 ++-- .../com/sun/tools/javac/util/List.java | 8 ++--- .../com/sun/tools/javac/util/ListBuffer.java | 6 +--- .../classes/com/sun/tools/javac/util/Log.java | 2 +- .../IntersectionTypeCastTest.java | 2 +- .../IntersectionTargetTypeTest.java | 4 +-- .../scope/7017664/CompoundScopeTest.java | 4 +-- .../test/tools/javac/types/TypeHarness.java | 4 +-- 32 files changed, 121 insertions(+), 129 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java index f5f5a4b120e..e0dde3de7b2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java @@ -472,7 +472,7 @@ public class JavacTaskImpl extends BasicJavacTask { for (TypeElement item: classes) set.add(item); - ListBuffer> defer = ListBuffer.>lb(); + ListBuffer> defer = new ListBuffer<>(); while (list.peek() != null) { Env env = list.remove(); ClassSymbol csym = env.enclClass.sym; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java index 9392046bb2d..0691498aeb5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/DeferredLintHandler.java @@ -81,7 +81,7 @@ public class DeferredLintHandler { } else { ListBuffer loggers = loggersQueue.get(currentPos); if (loggers == null) { - loggersQueue.put(currentPos, loggers = ListBuffer.lb()); + loggersQueue.put(currentPos, loggers = new ListBuffer<>()); } loggers.append(logger); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java index aa05cc29204..d46631504b2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java @@ -103,7 +103,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi * @return localized string representation */ public String visitTypes(List ts, Locale locale) { - ListBuffer sbuf = ListBuffer.lb(); + ListBuffer sbuf = new ListBuffer<>(); for (Type t : ts) { sbuf.append(visit(t, locale)); } @@ -118,7 +118,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi * @return localized string representation */ public String visitSymbols(List ts, Locale locale) { - ListBuffer sbuf = ListBuffer.lb(); + ListBuffer sbuf = new ListBuffer<>(); for (Symbol t : ts) { sbuf.append(visit(t, locale)); } 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 65459ec3daf..7a65bd04b10 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 @@ -614,7 +614,7 @@ public abstract class Symbol implements Element { } public List getTypeParameters() { - ListBuffer l = ListBuffer.lb(); + ListBuffer l = new ListBuffer<>(); for (Type t : type.getTypeArguments()) { Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER); l.append((TypeVariableSymbol)t.tsym); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index fb6308ba9bd..a6e4642ce51 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -433,7 +433,7 @@ public abstract class Type implements TypeMirror { } public static List filter(List ts, Filter tf) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { if (tf.accepts(t)) { buf.append(t); @@ -1496,7 +1496,7 @@ public abstract class Type implements TypeMirror { /** get all bounds of a given kind */ public List getBounds(InferenceBound... ibs) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (InferenceBound ib : ibs) { buf.appendList(bounds.get(ib)); } @@ -1505,7 +1505,7 @@ public abstract class Type implements TypeMirror { /** get the list of declared (upper) bounds */ public List getDeclaredBounds() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); int count = 0; for (Type b : getBounds(InferenceBound.UPPER)) { if (count++ == declaredCount) break; @@ -1565,8 +1565,8 @@ public abstract class Type implements TypeMirror { for (Map.Entry> _entry : bounds.entrySet()) { InferenceBound ib = _entry.getKey(); List prevBounds = _entry.getValue(); - ListBuffer newBounds = ListBuffer.lb(); - ListBuffer deps = ListBuffer.lb(); + ListBuffer newBounds = new ListBuffer<>(); + ListBuffer deps = new ListBuffer<>(); //step 1 - re-add bounds that are not dependent on ivars for (Type t : prevBounds) { if (!t.containsAny(instVars)) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java index 89f6ea40799..c481ea5d3e0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java @@ -304,7 +304,7 @@ public class TypeAnnotationPosition { * @param list The bytecode representation of the type path. */ public static List getTypePathFromBinary(java.util.List list) { - ListBuffer loc = ListBuffer.lb(); + ListBuffer loc = new ListBuffer<>(); Iterator iter = list.iterator(); while (iter.hasNext()) { Integer fst = iter.next(); @@ -316,7 +316,7 @@ public class TypeAnnotationPosition { } public static List getBinaryFromTypePath(java.util.List locs) { - ListBuffer loc = ListBuffer.lb(); + ListBuffer loc = new ListBuffer<>(); for (TypePathEntry tpe : locs) { loc = loc.append(tpe.tag.tag); loc = loc.append(tpe.arg); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 642de5d4c4a..56acb0e8eb2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -233,7 +233,7 @@ public class TypeAnnotations { * When traversing the AST we keep the "frames" of visited * trees in order to determine the position of annotations. */ - private ListBuffer frames = ListBuffer.lb(); + private ListBuffer frames = new ListBuffer<>(); protected void push(JCTree t) { frames = frames.prepend(t); } protected JCTree pop() { return frames.next(); } @@ -381,7 +381,7 @@ public class TypeAnnotations { } JCArrayTypeTree arTree = arrayTypeTree(typetree); - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); depth = depth.append(TypePathEntry.ARRAY); while (arType.elemtype.hasTag(TypeTag.ARRAY)) { if (arType.elemtype.isAnnotated()) { @@ -473,7 +473,7 @@ public class TypeAnnotations { // the correct nesting. // The genericLocation for the annotation. - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); Type topTy = enclTy; while (enclEl != null && @@ -793,7 +793,7 @@ public class TypeAnnotations { } case ARRAY_TYPE: { - ListBuffer index = ListBuffer.lb(); + ListBuffer index = new ListBuffer<>(); index = index.append(TypePathEntry.ARRAY); List newPath = path.tail; while (true) { @@ -956,7 +956,7 @@ public class TypeAnnotations { private static void locateNestedTypes(Type type, TypeAnnotationPosition p) { // The number of "steps" to get from the full type to the // left-most outer type. - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); Type encl = type.getEnclosingType(); while (encl != null && @@ -1226,7 +1226,7 @@ public class TypeAnnotations { public void visitNewArray(JCNewArray tree) { findPosition(tree, tree, tree.annotations); int dimAnnosCount = tree.dimAnnotations.size(); - ListBuffer depth = ListBuffer.lb(); + ListBuffer depth = new ListBuffer<>(); // handle annotations associated with dimensions for (int i = 0; i < dimAnnosCount; ++i) { 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 0d060b60bb7..996bcd88018 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 @@ -51,7 +51,6 @@ import static com.sun.tools.javac.code.Symbol.*; import static com.sun.tools.javac.code.Type.*; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.jvm.ClassFile.externalize; -import static com.sun.tools.javac.util.ListBuffer.lb; /** * Utility class containing various operations on types. @@ -411,7 +410,7 @@ public class Types { throw failure("not.a.functional.intf", origin); } - final ListBuffer abstracts = ListBuffer.lb(); + final ListBuffer abstracts = new ListBuffer<>(); for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { Type mtype = memberType(origin.type, sym); if (abstracts.isEmpty() || @@ -434,7 +433,7 @@ public class Types { FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); if (descRes == null) { //we can get here if the functional interface is ill-formed - ListBuffer descriptors = ListBuffer.lb(); + ListBuffer descriptors = new ListBuffer<>(); for (Symbol desc : abstracts) { String key = desc.type.getThrownTypes().nonEmpty() ? "descriptor.throws" : "descriptor"; @@ -596,7 +595,7 @@ public class Types { Type capturedSite = capture(site); if (capturedSite != site) { Type formalInterface = site.tsym.type; - ListBuffer typeargs = ListBuffer.lb(); + ListBuffer typeargs = new ListBuffer<>(); List actualTypeargs = site.getTypeArguments(); List capturedTypeargs = capturedSite.getTypeArguments(); //simply replace the wildcards with its bound @@ -662,7 +661,7 @@ public class Types { Assert.check(isFunctionalInterface(origin)); Symbol descSym = findDescriptorSymbol(origin); CompoundScope members = membersClosure(origin.type, false); - ListBuffer overridden = ListBuffer.lb(); + ListBuffer overridden = new ListBuffer<>(); outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) { if (m2 == descSym) continue; else if (descSym.overrides(m2, origin, Types.this, false)) { @@ -885,12 +884,12 @@ public class Types { private Type rewriteSupers(Type t) { if (!t.isParameterized()) return t; - ListBuffer from = lb(); - ListBuffer to = lb(); + ListBuffer from = new ListBuffer<>(); + ListBuffer to = new ListBuffer<>(); adaptSelf(t, from, to); if (from.isEmpty()) return t; - ListBuffer rewrite = lb(); + ListBuffer rewrite = new ListBuffer<>(); boolean changed = false; for (Type orig : to.toList()) { Type s = rewriteSupers(orig); @@ -2744,7 +2743,7 @@ public class Types { } public List prune(List methods) { - ListBuffer methodsMin = ListBuffer.lb(); + ListBuffer methodsMin = new ListBuffer<>(); for (MethodSymbol m1 : methods) { boolean isMin_m1 = true; for (MethodSymbol m2 : methods) { @@ -3001,7 +3000,7 @@ public class Types { List to) { if (tvars.isEmpty()) return tvars; - ListBuffer newBoundsBuf = lb(); + ListBuffer newBoundsBuf = new ListBuffer<>(); boolean changed = false; // calculate new bounds for (Type t : tvars) { @@ -3013,7 +3012,7 @@ public class Types { } if (!changed) return tvars; - ListBuffer newTvars = lb(); + ListBuffer newTvars = new ListBuffer<>(); // create new type variables without bounds for (Type t : tvars) { newTvars.append(new TypeVar(t.tsym, null, syms.botType)); @@ -3440,15 +3439,15 @@ public class Types { * compoundMin or glb. */ private List closureMin(List cl) { - ListBuffer classes = lb(); - ListBuffer interfaces = lb(); + ListBuffer classes = new ListBuffer<>(); + ListBuffer interfaces = new ListBuffer<>(); while (!cl.isEmpty()) { Type current = cl.head; if (current.isInterface()) interfaces.append(current); else classes.append(current); - ListBuffer candidates = lb(); + ListBuffer candidates = new ListBuffer<>(); for (Type t : cl.tail) { if (!isSubtypeNoCapture(current, t)) candidates.append(t); @@ -3564,7 +3563,7 @@ public class Types { } // where List erasedSupertypes(Type t) { - ListBuffer buf = lb(); + ListBuffer buf = new ListBuffer<>(); for (Type sup : closure(t)) { if (sup.hasTag(TYPEVAR)) { buf.append(sup); @@ -3914,7 +3913,7 @@ public class Types { } // where public List freshTypeVariables(List types) { - ListBuffer result = lb(); + ListBuffer result = new ListBuffer<>(); for (Type t : types) { if (t.hasTag(WILDCARD)) { t = t.unannotatedType(); 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 cb2337f936c..3813a6acd7a 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 @@ -1724,7 +1724,7 @@ public class Attr extends JCTree.Visitor { boolean isConstructorCall = methName == names._this || methName == names._super; - ListBuffer argtypesBuf = ListBuffer.lb(); + ListBuffer argtypesBuf = new ListBuffer<>(); if (isConstructorCall) { // We are seeing a ...this(...) or ...super(...) call. // Check that this is the first statement in a constructor. @@ -1989,7 +1989,7 @@ public class Attr extends JCTree.Visitor { } // Attribute constructor arguments. - ListBuffer argtypesBuf = ListBuffer.lb(); + ListBuffer argtypesBuf = new ListBuffer<>(); int pkind = attribArgs(tree.args, localEnv, argtypesBuf); List argtypes = argtypesBuf.toList(); List typeargtypes = attribTypes(tree.typeargs, localEnv); @@ -2476,8 +2476,8 @@ public class Attr extends JCTree.Visitor { } private TypeSymbol makeNotionalInterface(IntersectionClassType ict) { - ListBuffer targs = ListBuffer.lb(); - ListBuffer supertypes = ListBuffer.lb(); + ListBuffer targs = new ListBuffer<>(); + ListBuffer supertypes = new ListBuffer<>(); for (Type i : ict.interfaces_field) { if (i.isParameterized()) { targs.appendList(i.tsym.type.allparams()); @@ -2907,7 +2907,7 @@ public class Attr extends JCTree.Visitor { } }); } else { - ListBuffer targets = ListBuffer.lb(); + ListBuffer targets = new ListBuffer<>(); if (pt.hasTag(CLASS)) { if (pt.isCompound()) { targets.append(types.removeWildcards(primaryTarget)); //this goes first @@ -3903,7 +3903,7 @@ public class Attr extends JCTree.Visitor { } public void visitTypeUnion(JCTypeUnion tree) { - ListBuffer multicatchTypes = ListBuffer.lb(); + ListBuffer multicatchTypes = new ListBuffer<>(); ListBuffer all_multicatchTypes = null; // lazy, only if needed for (JCExpression typeTree : tree.alternatives) { Type ctype = attribType(typeTree, env); @@ -3930,7 +3930,7 @@ public class Attr extends JCTree.Visitor { all_multicatchTypes.append(ctype); } else { if (all_multicatchTypes == null) { - all_multicatchTypes = ListBuffer.lb(); + all_multicatchTypes = new ListBuffer<>(); all_multicatchTypes.appendList(multicatchTypes); } all_multicatchTypes.append(ctype); @@ -4085,7 +4085,7 @@ public class Attr extends JCTree.Visitor { if (annotations.isEmpty()) return List.nil(); - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (JCAnnotation anno : annotations) { if (anno.attribute != null) { // TODO: this null-check is only needed for an obscure 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 d3f94fdba82..a9ad0a68299 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 @@ -2452,8 +2452,8 @@ public class Check { Assert.check(m.kind == MTH); List prov = types.interfaceCandidates(site, (MethodSymbol)m); if (prov.size() > 1) { - ListBuffer abstracts = ListBuffer.lb(); - ListBuffer defaults = ListBuffer.lb(); + ListBuffer abstracts = new ListBuffer<>(); + ListBuffer defaults = new ListBuffer<>(); for (MethodSymbol provSym : prov) { if ((provSym.flags() & DEFAULT) != 0) { defaults = defaults.append(provSym); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 4db110579f7..6357419cf3d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -637,7 +637,7 @@ public class DeferredAttr extends JCTree.Visitor { Env localEnv = env.dup(tree); JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv, attr.memberReferenceQualifierResult(tree)); - ListBuffer argtypes = ListBuffer.lb(); + ListBuffer argtypes = new ListBuffer<>(); for (Type t : types.findDescriptorType(pt).getParameterTypes()) { argtypes.append(Type.noType); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index 252124370e5..8c69c814965 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -713,7 +713,7 @@ public class Flow { ListBuffer prevPending = pendingExits; boolean prevAlive = alive; try { - pendingExits = ListBuffer.lb(); + pendingExits = new ListBuffer<>(); alive = true; scanStat(tree.body); tree.canCompleteNormally = alive; @@ -1265,7 +1265,7 @@ public class Flow { List prevThrown = thrown; ListBuffer prevPending = pendingExits; try { - pendingExits = ListBuffer.lb(); + pendingExits = new ListBuffer<>(); caught = tree.getDescriptorType(types).getThrownTypes(); thrown = List.nil(); scan(tree.body); @@ -1338,7 +1338,7 @@ public class Flow { ListBuffer prevPending = pendingExits; inLambda = true; try { - pendingExits = ListBuffer.lb(); + pendingExits = new ListBuffer<>(); caught = List.of(syms.throwableType); thrown = List.nil(); scan(tree.body); @@ -2030,7 +2030,7 @@ public class Flow { void reportWarning(Lint.LintCategory lc, DiagnosticPosition pos, String key, Object ... args) {} public void visitTry(JCTry tree) { - ListBuffer resourceVarDecls = ListBuffer.lb(); + ListBuffer resourceVarDecls = new ListBuffer<>(); final Bits uninitsTryPrev = new Bits(uninitsTry); ListBuffer

    prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); 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 4c9568eb32c..61f75f068fa 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 @@ -277,7 +277,7 @@ public class Infer { * Infer cyclic inference variables as described in 15.12.2.8. */ private void instantiateAsUninferredVars(List vars, InferenceContext inferenceContext) { - ListBuffer todo = ListBuffer.lb(); + ListBuffer todo = new ListBuffer<>(); //step 1 - create fresh tvars for (Type t : vars) { UndetVar uv = (UndetVar)inferenceContext.asFree(t); @@ -1832,7 +1832,7 @@ public class Infer { } private List filterVars(Filter fu) { - ListBuffer res = ListBuffer.lb(); + ListBuffer res = new ListBuffer<>(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; if (fu.accepts(uv)) { @@ -1860,7 +1860,7 @@ public class Infer { * Returns a list of free variables in a given type */ final List freeVarsIn(Type t) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type iv : inferenceVars()) { if (t.contains(iv)) { buf.add(iv); @@ -1870,11 +1870,11 @@ public class Infer { } final List freeVarsIn(List ts) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { buf.appendList(freeVarsIn(t)); } - ListBuffer buf2 = ListBuffer.lb(); + ListBuffer buf2 = new ListBuffer<>(); for (Type t : buf) { if (!buf2.contains(t)) { buf2.add(t); @@ -1893,7 +1893,7 @@ public class Infer { } final List asFree(List ts) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { buf.append(asFree(t)); } @@ -1901,7 +1901,7 @@ public class Infer { } List instTypes() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; buf.append(uv.inst != null ? uv.inst : uv.qtype); @@ -1919,7 +1919,7 @@ public class Infer { } List asInstTypes(List ts) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { buf.append(asInstType(t)); } @@ -1967,7 +1967,7 @@ public class Infer { * Save the state of this inference context */ List save() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index d22ebfa36e3..eb15ef65c11 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -126,7 +126,7 @@ public class LambdaToMethod extends TreeTranslator { private final VarSymbol deserParamSym; private KlassInfo(Symbol kSym) { - appendedMethodList = ListBuffer.lb(); + appendedMethodList = new ListBuffer<>(); deserializeCases = new HashMap>(); long flags = PRIVATE | STATIC | SYNTHETIC; MethodType type = new MethodType(List.of(syms.serializedLambdaType), syms.objectType, @@ -191,7 +191,7 @@ public class LambdaToMethod extends TreeTranslator { } List translate(List trees, TranslationContext newContext) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (T tree : trees) { buf.append(translate(tree, newContext)); } @@ -304,7 +304,7 @@ public class LambdaToMethod extends TreeTranslator { // * the "this" argument if it is an instance method // * enclosing locals captured by the lambda expression - ListBuffer syntheticInits = ListBuffer.lb(); + ListBuffer syntheticInits = new ListBuffer<>(); if (!sym.isStatic()) { syntheticInits.append(makeThis( @@ -469,7 +469,7 @@ public class LambdaToMethod extends TreeTranslator { } else if (isLambda_void && isTarget_Void) { //void to Void conversion: // BODY; return null; - ListBuffer stats = ListBuffer.lb(); + ListBuffer stats = new ListBuffer<>(); stats.append(make.Exec(expr)); stats.append(make.Return(make.Literal(BOT, null).setType(syms.botType))); return make.Block(0, stats.toList()); @@ -531,8 +531,8 @@ public class LambdaToMethod extends TreeTranslator { } private JCMethodDecl makeDeserializeMethod(Symbol kSym) { - ListBuffer cases = ListBuffer.lb(); - ListBuffer breaks = ListBuffer.lb(); + ListBuffer cases = new ListBuffer<>(); + ListBuffer breaks = new ListBuffer<>(); for (Map.Entry> entry : kInfo.deserializeCases.entrySet()) { JCBreak br = make.Break(null); breaks.add(br); @@ -594,11 +594,11 @@ public class LambdaToMethod extends TreeTranslator { String implMethodSignature = methodSig(types.erasure(refSym.type)); JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), make.Literal(implMethodKind)); - ListBuffer serArgs = ListBuffer.lb(); + ListBuffer serArgs = new ListBuffer<>(); int i = 0; for (Type t : indyType.getParameterTypes()) { - List indexAsArg = ListBuffer.lb().append(make.Literal(i)).toList(); - List argTypes = ListBuffer.lb().append(syms.intType).toList(); + List indexAsArg = new ListBuffer().append(make.Literal(i)).toList(); + List argTypes = new ListBuffer().append(syms.intType).toList(); serArgs.add(make.TypeCast(types.erasure(t), deserGetter("getCapturedArg", syms.objectType, argTypes, indexAsArg))); ++i; } @@ -618,7 +618,7 @@ public class LambdaToMethod extends TreeTranslator { null); ListBuffer stmts = kInfo.deserializeCases.get(implMethodName); if (stmts == null) { - stmts = ListBuffer.lb(); + stmts = new ListBuffer<>(); kInfo.deserializeCases.put(implMethodName, stmts); } /**** @@ -728,8 +728,8 @@ public class LambdaToMethod extends TreeTranslator { private final JCMemberReference tree; private final ReferenceTranslationContext localContext; - private final ListBuffer args = ListBuffer.lb(); - private final ListBuffer params = ListBuffer.lb(); + private final ListBuffer args = new ListBuffer<>(); + private final ListBuffer params = new ListBuffer<>(); MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) { this.tree = tree; @@ -934,7 +934,7 @@ public class LambdaToMethod extends TreeTranslator { typeToMethodType(tree.getDescriptorType(types))); //computed indy arg types - ListBuffer indy_args_types = ListBuffer.lb(); + ListBuffer indy_args_types = new ListBuffer<>(); for (JCExpression arg : indy_args) { indy_args_types.append(arg.type); } @@ -949,7 +949,7 @@ public class LambdaToMethod extends TreeTranslator { names.altMetafactory : names.metafactory; if (context.needsAltMetafactory()) { - ListBuffer markers = ListBuffer.lb(); + ListBuffer markers = new ListBuffer<>(); for (Type t : tree.targets.tail) { if (t.tsym != syms.serializableType.tsym) { markers.append(t.tsym); @@ -1027,7 +1027,7 @@ public class LambdaToMethod extends TreeTranslator { } //where private List bsmStaticArgToTypes(List args) { - ListBuffer argtypes = ListBuffer.lb(); + ListBuffer argtypes = new ListBuffer<>(); for (Object arg : args) { argtypes.append(bsmStaticArgToType(arg)); } @@ -1851,7 +1851,7 @@ public class LambdaToMethod extends TreeTranslator { (thisReferenced? (inInterface? DEFAULT : 0) : STATIC); //compute synthetic params - ListBuffer params = ListBuffer.lb(); + ListBuffer params = new ListBuffer<>(); // The signature of the method is augmented with the following // synthetic parameters: 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 cb054fe80f2..51588257c9b 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 @@ -3725,7 +3725,7 @@ public class Lower extends TreeTranslator { (JCVariableDecl)make.VarDef(dollar_tmp, make.Literal(INT, -1)).setType(dollar_tmp.type); dollar_tmp_def.init.type = dollar_tmp.type = syms.intType; stmtList.append(dollar_tmp_def); - ListBuffer caseBuffer = ListBuffer.lb(); + ListBuffer caseBuffer = new ListBuffer<>(); // hashCode will trigger nullcheck on original switch expression JCMethodInvocation hashCodeCall = makeCall(make.Ident(dollar_s), names.hashCode, @@ -3749,7 +3749,7 @@ public class Lower extends TreeTranslator { elsepart); } - ListBuffer lb = ListBuffer.lb(); + ListBuffer lb = new ListBuffer<>(); JCBreak breakStmt = make.Break(null); breakStmt.target = switch1; lb.append(elsepart).append(breakStmt); @@ -3764,7 +3764,7 @@ public class Lower extends TreeTranslator { // with corresponding integer ones from the label to // position map. - ListBuffer lb = ListBuffer.lb(); + ListBuffer lb = new ListBuffer<>(); JCSwitch switch2 = make.Switch(make.Ident(dollar_tmp), lb.toList()); for(JCCase oneCase : caseList ) { // Rewire up old unlabeled break statements to the 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 e3c427413ec..87eb36668f4 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 @@ -213,7 +213,7 @@ public class Resolve { int pos = 0; int mostSpecificPos = -1; - ListBuffer subDiags = ListBuffer.lb(); + ListBuffer subDiags = new ListBuffer<>(); for (Candidate c : currentResolutionContext.candidates) { if (currentResolutionContext.step != c.step || (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || @@ -783,7 +783,7 @@ public class Resolve { }; List dummyArgs(int length) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (int i = 0 ; i < length ; i++) { buf.append(Type.noType); } @@ -3173,7 +3173,7 @@ public class Resolve { } //where private List pruneInterfaces(Type t) { - ListBuffer result = ListBuffer.lb(); + ListBuffer result = new ListBuffer<>(); for (Type t1 : types.interfaces(t)) { boolean shouldAdd = true; for (Type t2 : types.interfaces(t)) { @@ -3286,7 +3286,7 @@ public class Resolve { if (argtypes == null || argtypes.isEmpty()) { return noArgs; } else { - ListBuffer diagArgs = ListBuffer.lb(); + ListBuffer diagArgs = new ListBuffer<>(); for (Type t : argtypes) { if (t.hasTag(DEFERRED)) { diagArgs.append(((DeferredAttr.DeferredType)t).tree); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java index d747a2b5156..48bd03c7a66 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -887,7 +887,7 @@ public class TransTypes extends TreeTranslator { private List addOverrideBridgesIfNeeded(DiagnosticPosition pos, final ClassSymbol c) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); if (c.isInterface() || !boundsRestricted(c)) return buf.toList(); Type t = types.supertype(c.type); 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 1b57b13cf36..397069589ff 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 @@ -1446,8 +1446,7 @@ public class ClassReader { void attachTypeAnnotations(final Symbol sym) { int numAttributes = nextChar(); if (numAttributes != 0) { - ListBuffer proxies = - ListBuffer.lb(); + ListBuffer proxies = new ListBuffer<>(); for (int i = 0; i < numAttributes; i++) proxies.append(readTypeAnnotation()); annotate.normal(new TypeAnnotationCompleter(sym, proxies.toList())); @@ -1596,7 +1595,7 @@ public class ClassReader { { // See whether there is location info and read it int len = nextByte(); - ListBuffer loc = ListBuffer.lb(); + ListBuffer loc = new ListBuffer<>(); for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i) loc = loc.append(nextByte()); position.location = TypeAnnotationPosition.getTypePathFromBinary(loc.toList()); @@ -1946,7 +1945,7 @@ public class ClassReader { } List deproxyTypeCompoundList(List proxies) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (TypeAnnotationProxy proxy: proxies) { Attribute.Compound compound = deproxyCompound(proxy.compound); Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position); @@ -2033,7 +2032,7 @@ public class ClassReader { boolean isVarargs = (flags & VARARGS) != 0; if (isVarargs) { Type varargsElem = args.last(); - ListBuffer adjustedArgs = ListBuffer.lb(); + ListBuffer adjustedArgs = new ListBuffer<>(); for (Type t : args) { adjustedArgs.append(t != varargsElem ? t : diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java index 6698c7fde27..54122430380 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java @@ -766,8 +766,8 @@ public class ClassWriter extends ClassFile { int writeTypeAnnotations(List typeAnnos, boolean inCode) { if (typeAnnos.isEmpty()) return 0; - ListBuffer visibles = ListBuffer.lb(); - ListBuffer invisibles = ListBuffer.lb(); + ListBuffer visibles = new ListBuffer<>(); + ListBuffer invisibles = new ListBuffer<>(); for (Attribute.TypeCompound tc : typeAnnos) { if (tc.hasUnknownPosition()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java index d0ed7ec559c..6276a24ad2f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java @@ -1595,7 +1595,7 @@ public class Code { public void compressCatchTable() { - ListBuffer compressedCatchInfo = ListBuffer.lb(); + ListBuffer compressedCatchInfo = new ListBuffer<>(); List handlerPcs = List.nil(); for (char[] catchEntry : catchInfo) { handlerPcs = handlerPcs.prepend((int)catchEntry[2]); 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 ba369172f43..39a59f662ff 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 @@ -67,7 +67,6 @@ import com.sun.tools.javac.util.Log.WriterKind; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.main.Option.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; -import static com.sun.tools.javac.util.ListBuffer.lb; /** This class could be the main entry point for GJC when GJC is used as a @@ -586,7 +585,7 @@ public class JavaCompiler { } protected final Queue stopIfError(CompileState cs, Queue queue) { - return shouldStop(cs) ? ListBuffer.lb() : queue; + return shouldStop(cs) ? new ListBuffer() : queue; } protected final List stopIfError(CompileState cs, List list) { @@ -952,7 +951,7 @@ public class JavaCompiler { return List.nil(); //parse all files - ListBuffer trees = lb(); + ListBuffer trees = new ListBuffer<>(); Set filesSoFar = new HashSet(); for (JavaFileObject fileObject : fileObjects) { if (!filesSoFar.contains(fileObject)) { @@ -1002,7 +1001,7 @@ public class JavaCompiler { // then remember the classes declared in // the original compilation units listed on the command line. if (needRootClasses || sourceOutput || stubOutput) { - ListBuffer cdefs = lb(); + ListBuffer cdefs = new ListBuffer<>(); for (JCCompilationUnit unit : roots) { for (List defs = unit.defs; defs.nonEmpty(); @@ -1226,7 +1225,7 @@ public class JavaCompiler { * @returns a list of environments for attributd classes. */ public Queue> attribute(Queue> envs) { - ListBuffer> results = lb(); + ListBuffer> results = new ListBuffer<>(); while (!envs.isEmpty()) results.append(attribute(envs.remove())); return stopIfError(CompileState.ATTR, results); @@ -1291,7 +1290,7 @@ public class JavaCompiler { * @returns the list of attributed parse trees */ public Queue> flow(Queue> envs) { - ListBuffer> results = lb(); + ListBuffer> results = new ListBuffer<>(); for (Env env: envs) { flow(env, results); } @@ -1302,7 +1301,7 @@ public class JavaCompiler { * Perform dataflow checks on an attributed parse tree. */ public Queue> flow(Env env) { - ListBuffer> results = lb(); + ListBuffer> results = new ListBuffer<>(); flow(env, results); return stopIfError(CompileState.FLOW, results); } @@ -1356,7 +1355,7 @@ public class JavaCompiler { * @returns a list containing the classes to be generated */ public Queue, JCClassDecl>> desugar(Queue> envs) { - ListBuffer, JCClassDecl>> results = lb(); + ListBuffer, JCClassDecl>> results = new ListBuffer<>(); for (Env env: envs) desugar(env, results); return stopIfError(CompileState.FLOW, results); @@ -1605,7 +1604,7 @@ public class JavaCompiler { } @Override public void visitClassDef(JCClassDecl tree) { - ListBuffer newdefs = lb(); + ListBuffer newdefs = new ListBuffer<>(); for (List it = tree.defs; it.tail != null; it = it.tail) { JCTree t = it.head; switch (t.getTag()) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java index a2cd3c55de7..c05662cbcbb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacAnnoConstructs.java @@ -207,7 +207,7 @@ public class JavacAnnoConstructs { Attribute[] contained0 = null; if (container != null) contained0 = unpackAttributes(container); - ListBuffer compounds = ListBuffer.lb(); + ListBuffer compounds = new ListBuffer<>(); if (contained0 != null) { for (Attribute a : contained0) if (a instanceof Attribute.Compound) @@ -328,7 +328,7 @@ public class JavacAnnoConstructs { Attribute[] contained0 = null; if (container != null) contained0 = unpackAttributes(container); - ListBuffer compounds = ListBuffer.lb(); + ListBuffer compounds = new ListBuffer<>(); if (contained0 != null) { for (Attribute a : contained0) if (a instanceof Attribute.Compound) diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 182f21158ca..57a492f3a3a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -48,7 +48,6 @@ import static com.sun.tools.javac.parser.Tokens.TokenKind.GT; import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT; import static com.sun.tools.javac.parser.Tokens.TokenKind.LT; import static com.sun.tools.javac.tree.JCTree.Tag.*; -import static com.sun.tools.javac.util.ListBuffer.lb; /** The parser maps a token sequence into an abstract syntax * tree. It operates by recursive descent, with code derived @@ -1767,7 +1766,7 @@ public class JavacParser implements Parser { /** Arguments = "(" [Expression { COMMA Expression }] ")" */ List arguments() { - ListBuffer args = lb(); + ListBuffer args = new ListBuffer<>(); if (token.kind == LPAREN) { nextToken(); if (token.kind != RPAREN) { @@ -1834,7 +1833,7 @@ public class JavacParser implements Parser { nextToken(); return List.nil(); } else { - ListBuffer args = ListBuffer.lb(); + ListBuffer args = new ListBuffer<>(); args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); while (token.kind == COMMA) { nextToken(); @@ -2175,7 +2174,7 @@ public class JavacParser implements Parser { ListBuffer dims = new ListBuffer(); // maintain array dimension type annotations - ListBuffer> dimAnnotations = ListBuffer.lb(); + ListBuffer> dimAnnotations = new ListBuffer<>(); dimAnnotations.append(annos); dims.append(parseExpression()); @@ -2626,7 +2625,7 @@ public class JavacParser implements Parser { } List catchTypes() { - ListBuffer catchTypes = ListBuffer.lb(); + ListBuffer catchTypes = new ListBuffer<>(); catchTypes.add(parseType()); while (token.kind == BAR) { checkMulticatch(); @@ -2708,7 +2707,7 @@ public class JavacParser implements Parser { * | { FINAL | '@' Annotation } Type VariableDeclarators */ List forInit() { - ListBuffer stats = lb(); + ListBuffer stats = new ListBuffer<>(); int pos = token.pos; if (token.kind == FINAL || token.kind == MONKEYS_AT) { return variableDeclarators(optFinal(0), parseType(), stats).toList(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java index d55defedf73..fcb19dcb5fb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/Tokens.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -402,7 +402,7 @@ public class Tokens { if (comments == null) { return List.nil(); } else { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (Comment c : comments) { if (c.getStyle() == style) { buf.add(c); diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java index aa9899ed210..f1be519d6c9 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/GraphUtils.java @@ -103,8 +103,8 @@ public class GraphUtils { * directed graph in linear time. Works on TarjanNode. */ public static > List> tarjan(Iterable nodes) { - ListBuffer> cycles = ListBuffer.lb(); - ListBuffer stack = ListBuffer.lb(); + ListBuffer> cycles = new ListBuffer<>(); + ListBuffer stack = new ListBuffer<>(); int index = 0; for (N node: nodes) { if (node.index == -1) { @@ -132,7 +132,7 @@ public class GraphUtils { } if (v.lowlink == v.index) { N n; - ListBuffer cycle = ListBuffer.lb(); + ListBuffer cycle = new ListBuffer<>(); do { n = stack.remove(); n.active = false; diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/List.java b/langtools/src/share/classes/com/sun/tools/javac/util/List.java index dee69807e2c..3ba7d8b59dc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/List.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/List.java @@ -97,7 +97,7 @@ public class List extends AbstractCollection implements java.util.List } public List intersect(List that) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (A el : this) { if (that.contains(el)) { buf.append(el); @@ -107,7 +107,7 @@ public class List extends AbstractCollection implements java.util.List } public List diff(List that) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (A el : this) { if (!that.contains(el)) { buf.append(el); @@ -120,7 +120,7 @@ public class List extends AbstractCollection implements java.util.List * Create a new list from the first {@code n} elements of this list */ public List take(int n) { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); int count = 0; for (A el : this) { if (count++ == n) break; @@ -167,7 +167,7 @@ public class List extends AbstractCollection implements java.util.List } public static List from(Iterable coll) { - ListBuffer xs = ListBuffer.lb(); + ListBuffer xs = new ListBuffer<>(); for (A a : coll) { xs.append(a); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java b/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java index 0aa751ffe96..6d9c1ccda55 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,10 +40,6 @@ import java.util.NoSuchElementException; */ public class ListBuffer extends AbstractQueue { - public static ListBuffer lb() { - return new ListBuffer(); - } - public static ListBuffer of(T x) { ListBuffer lb = new ListBuffer(); lb.add(x); 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 5ed6d784103..d0d9d5934a6 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 @@ -123,7 +123,7 @@ public class Log extends AbstractLog { * active diagnostic handler. */ public static class DeferredDiagnosticHandler extends DiagnosticHandler { - private Queue deferred = ListBuffer.lb(); + private Queue deferred = new ListBuffer<>(); private final Filter filter; public DeferredDiagnosticHandler(Log log) { diff --git a/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java b/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java index 7aea2d42476..a398ec1791b 100644 --- a/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java +++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java @@ -237,7 +237,7 @@ public class IntersectionTypeCastTest } static List allCastInfo() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (CastKind kind : CastKind.values()) { for (ClassKind clazz : ClassKind.values()) { if (kind == CastKind.INTERFACE && clazz != ClassKind.OBJECT) { diff --git a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java index 660721ec849..36e18611ba5 100644 --- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java +++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -196,7 +196,7 @@ public class IntersectionTargetTypeTest { } static List allCastInfo() { - ListBuffer buf = ListBuffer.lb(); + ListBuffer buf = new ListBuffer<>(); for (CastKind kind : CastKind.values()) { for (TypeKind b1 : TypeKind.values()) { if (kind.nbounds == 1) { diff --git a/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java b/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java index 075a750a310..e9d44a84d41 100644 --- a/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java +++ b/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java @@ -176,7 +176,7 @@ public class CompoundScopeTest { */ void checkElems(CompoundScope cs, Filter sf) { int count = 0; - ListBuffer found = ListBuffer.lb(); + ListBuffer found = new ListBuffer<>(); List allSymbols = sf == null ? elems : filter(elems, sf); @@ -216,7 +216,7 @@ public class CompoundScopeTest { } List filter(List elems, Filter sf) { - ListBuffer res = ListBuffer.lb(); + ListBuffer res = new ListBuffer<>(); for (Symbol s : elems) { if (sf.accepts(s)) { res.append(s); diff --git a/langtools/test/tools/javac/types/TypeHarness.java b/langtools/test/tools/javac/types/TypeHarness.java index a53d94761ba..b4837907820 100644 --- a/langtools/test/tools/javac/types/TypeHarness.java +++ b/langtools/test/tools/javac/types/TypeHarness.java @@ -213,8 +213,8 @@ public class TypeHarness { /** compute a type substitution on 't' given a list of type mappings */ public Type subst(Type t, Mapping... maps) { - ListBuffer from = ListBuffer.lb(); - ListBuffer to = ListBuffer.lb(); + ListBuffer from = new ListBuffer<>(); + ListBuffer to = new ListBuffer<>(); for (Mapping tm : maps) { from.append(tm.from); to.append(tm.to); From eacd2bcb72f3c8bc5b17fc31dae78f06a39e3394 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Mon, 23 Sep 2013 17:27:38 +0400 Subject: [PATCH 166/293] 7154966: CRs found to be in Fixed state with no test and no noreg- keyword Reviewed-by: ksrini --- langtools/test/tools/javac/T7090499.java | 14 ++++++++++++++ langtools/test/tools/javac/T7090499.out | 2 ++ langtools/test/tools/javac/T7120463.java | 11 +++++++++++ langtools/test/tools/javac/T7120463.out | 3 +++ langtools/test/tools/javac/T7126754.java | 19 +++++++++++++++++++ 5 files changed, 49 insertions(+) create mode 100644 langtools/test/tools/javac/T7090499.java create mode 100644 langtools/test/tools/javac/T7090499.out create mode 100644 langtools/test/tools/javac/T7120463.java create mode 100644 langtools/test/tools/javac/T7120463.out create mode 100644 langtools/test/tools/javac/T7126754.java diff --git a/langtools/test/tools/javac/T7090499.java b/langtools/test/tools/javac/T7090499.java new file mode 100644 index 00000000000..b05cda52c4b --- /dev/null +++ b/langtools/test/tools/javac/T7090499.java @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7090499 + * @summary missing rawtypes warnings in anonymous inner class + * @compile/ref=T7090499.out -Xlint:rawtypes -XDrawDiagnostics T7090499.java + */ + +class T7090499 { + { + new Object() { + T7090499 x; + }; + } +} diff --git a/langtools/test/tools/javac/T7090499.out b/langtools/test/tools/javac/T7090499.out new file mode 100644 index 00000000000..54b68474f79 --- /dev/null +++ b/langtools/test/tools/javac/T7090499.out @@ -0,0 +1,2 @@ +T7090499.java:11:13: compiler.warn.raw.class.use: T7090499, T7090499 +1 warning diff --git a/langtools/test/tools/javac/T7120463.java b/langtools/test/tools/javac/T7120463.java new file mode 100644 index 00000000000..9f64a17178a --- /dev/null +++ b/langtools/test/tools/javac/T7120463.java @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7120463 + * @summary Fix method reference parser support in order to avoid ambiguities + * @compile/fail/ref=T7120463.out -XDrawDiagnostics T7120463.java + */ + +class T7120463 { + void test() { that(i < len, "oopmap"); } + void that(int i, String s) { }; +} diff --git a/langtools/test/tools/javac/T7120463.out b/langtools/test/tools/javac/T7120463.out new file mode 100644 index 00000000000..527bd52acf2 --- /dev/null +++ b/langtools/test/tools/javac/T7120463.out @@ -0,0 +1,3 @@ +T7120463.java:9:24: compiler.err.cant.resolve.location: kindname.variable, i, , , (compiler.misc.location: kindname.class, T7120463, null) +T7120463.java:9:28: compiler.err.cant.resolve.location: kindname.variable, len, , , (compiler.misc.location: kindname.class, T7120463, null) +2 errors diff --git a/langtools/test/tools/javac/T7126754.java b/langtools/test/tools/javac/T7126754.java new file mode 100644 index 00000000000..0b9d32409db --- /dev/null +++ b/langtools/test/tools/javac/T7126754.java @@ -0,0 +1,19 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7126754 + * @summary Generics compilation failure casting List to List + * @compile T7126754.java + */ + +import java.util.List; +import java.util.Set; + +public class T7126754 { + public static void main(String[] args) { + List> a = null; + List> b = a; + + List> c = null; + List> d = (List>)c; + } +} From e815841576eb30fe7e7b9c0582041044b8eb63e7 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Mon, 23 Sep 2013 18:29:27 +0400 Subject: [PATCH 167/293] 4881267: improve diagnostic for "instanceof T" for type parameter T Reviewed-by: vromero, jjg --- .../classes/com/sun/tools/javac/comp/Attr.java | 10 ++++++++-- .../classes/com/sun/tools/javac/comp/Check.java | 14 -------------- langtools/test/tools/javac/T4881267.java | 12 ++++++++++++ langtools/test/tools/javac/T4881267.out | 2 ++ 4 files changed, 22 insertions(+), 16 deletions(-) create mode 100644 langtools/test/tools/javac/T4881267.java create mode 100644 langtools/test/tools/javac/T4881267.out 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 3813a6acd7a..0b4db2c059f 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 @@ -3102,8 +3102,14 @@ public class Attr extends JCTree.Visitor { public void visitTypeTest(JCInstanceOf tree) { Type exprtype = chk.checkNullOrRefType( tree.expr.pos(), attribExpr(tree.expr, env)); - Type clazztype = chk.checkReifiableReferenceType( - tree.clazz.pos(), attribType(tree.clazz, env)); + Type clazztype = attribType(tree.clazz, env); + if (!clazztype.hasTag(TYPEVAR)) { + clazztype = chk.checkClassOrArrayType(tree.clazz.pos(), clazztype); + } + if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) { + log.error(tree.clazz.pos(), "illegal.generic.type.for.instof"); + clazztype = types.createErrorType(clazztype); + } chk.validate(tree.clazz, env, false); chk.checkCastable(tree.expr.pos(), exprtype, clazztype); result = check(tree, syms.booleanType, VAL, resultInfo); 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 a9ad0a68299..453bc70edda 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 @@ -706,20 +706,6 @@ public class Check { return t; } - /** Check that type is a reifiable class, interface or array type. - * @param pos Position to be used for error reporting. - * @param t The type to be checked. - */ - Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) { - t = checkClassOrArrayType(pos, t); - if (!t.isErroneous() && !types.isReifiable(t)) { - log.error(pos, "illegal.generic.type.for.instof"); - return types.createErrorType(t); - } else { - return t; - } - } - /** Check that type is a reference type, i.e. a class, interface or array type * or a type variable. * @param pos Position to be used for error reporting. diff --git a/langtools/test/tools/javac/T4881267.java b/langtools/test/tools/javac/T4881267.java new file mode 100644 index 00000000000..33690add37b --- /dev/null +++ b/langtools/test/tools/javac/T4881267.java @@ -0,0 +1,12 @@ +/* + * @test /nodynamiccopyright/ + * @bug 4881267 + * @summary improve diagnostic for "instanceof T" for type parameter T + * @compile/fail/ref=T4881267.out -XDrawDiagnostics T4881267.java + */ + +class T4881267 { + void m(Object o) { + boolean b = o instanceof T; + } +} diff --git a/langtools/test/tools/javac/T4881267.out b/langtools/test/tools/javac/T4881267.out new file mode 100644 index 00000000000..01a732a612e --- /dev/null +++ b/langtools/test/tools/javac/T4881267.out @@ -0,0 +1,2 @@ +T4881267.java:10:34: compiler.err.illegal.generic.type.for.instof +1 error From 522051490c44d11e8bb241eeefc92c0e645c0a96 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 23 Sep 2013 08:56:19 -0700 Subject: [PATCH 168/293] 8025088: Missing cases for JVM_CONSTANT_MethodHandleInError cause crash if debugger steps into error-tagged method handle Need to refetch each method from InstanceKlass after all safepoints. Removed leaky PreviousVersionInfo code. Reviewed-by: coleenp, sspitsyn --- hotspot/src/share/vm/oops/constantPool.cpp | 14 +++++---- hotspot/src/share/vm/oops/constantPool.hpp | 36 ++++++++++++++++++---- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 4f888eb9ca4..66493a879e1 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -1611,9 +1611,11 @@ jint ConstantPool::cpool_entry_size(jint idx) { case JVM_CONSTANT_UnresolvedClassInError: case JVM_CONSTANT_StringIndex: case JVM_CONSTANT_MethodType: + case JVM_CONSTANT_MethodTypeInError: return 3; case JVM_CONSTANT_MethodHandle: + case JVM_CONSTANT_MethodHandleInError: return 4; //tag, ref_kind, ref_index case JVM_CONSTANT_Integer: @@ -1794,8 +1796,8 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, case JVM_CONSTANT_MethodHandle: case JVM_CONSTANT_MethodHandleInError: { *bytes = JVM_CONSTANT_MethodHandle; - int kind = method_handle_ref_kind_at(idx); - idx1 = method_handle_index_at(idx); + int kind = method_handle_ref_kind_at_error_ok(idx); + idx1 = method_handle_index_at_error_ok(idx); *(bytes+1) = (unsigned char) kind; Bytes::put_Java_u2((address) (bytes+2), idx1); DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); @@ -1804,7 +1806,7 @@ int ConstantPool::copy_cpool_bytes(int cpool_size, case JVM_CONSTANT_MethodType: case JVM_CONSTANT_MethodTypeInError: { *bytes = JVM_CONSTANT_MethodType; - idx1 = method_type_index_at(idx); + idx1 = method_type_index_at_error_ok(idx); Bytes::put_Java_u2((address) (bytes+1), idx1); DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); break; @@ -1992,12 +1994,12 @@ void ConstantPool::print_entry_on(const int index, outputStream* st) { break; case JVM_CONSTANT_MethodHandle : case JVM_CONSTANT_MethodHandleInError : - st->print("ref_kind=%d", method_handle_ref_kind_at(index)); - st->print(" ref_index=%d", method_handle_index_at(index)); + st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index)); + st->print(" ref_index=%d", method_handle_index_at_error_ok(index)); break; case JVM_CONSTANT_MethodType : case JVM_CONSTANT_MethodTypeInError : - st->print("signature_index=%d", method_type_index_at(index)); + st->print("signature_index=%d", method_type_index_at_error_ok(index)); break; case JVM_CONSTANT_InvokeDynamic : { diff --git a/hotspot/src/share/vm/oops/constantPool.hpp b/hotspot/src/share/vm/oops/constantPool.hpp index 93c32348573..47a51a835e2 100644 --- a/hotspot/src/share/vm/oops/constantPool.hpp +++ b/hotspot/src/share/vm/oops/constantPool.hpp @@ -474,18 +474,42 @@ class ConstantPool : public Metadata { return *int_at_addr(which); } - int method_handle_ref_kind_at(int which) { - assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); + private: + int method_handle_ref_kind_at(int which, bool error_ok) { + assert(tag_at(which).is_method_handle() || + (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool"); return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits } - int method_handle_index_at(int which) { - assert(tag_at(which).is_method_handle(), "Corrupted constant pool"); + int method_handle_index_at(int which, bool error_ok) { + assert(tag_at(which).is_method_handle() || + (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool"); return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits } - int method_type_index_at(int which) { - assert(tag_at(which).is_method_type(), "Corrupted constant pool"); + int method_type_index_at(int which, bool error_ok) { + assert(tag_at(which).is_method_type() || + (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool"); return *int_at_addr(which); } + public: + int method_handle_ref_kind_at(int which) { + return method_handle_ref_kind_at(which, false); + } + int method_handle_ref_kind_at_error_ok(int which) { + return method_handle_ref_kind_at(which, true); + } + int method_handle_index_at(int which) { + return method_handle_index_at(which, false); + } + int method_handle_index_at_error_ok(int which) { + return method_handle_index_at(which, true); + } + int method_type_index_at(int which) { + return method_type_index_at(which, false); + } + int method_type_index_at_error_ok(int which) { + return method_type_index_at(which, true); + } + // Derived queries: Symbol* method_handle_name_ref_at(int which) { int member = method_handle_index_at(which); From c101eca6bb94ad082a0e961dc8e46ee076ef3b30 Mon Sep 17 00:00:00 2001 From: Eric McCorkle Date: Mon, 23 Sep 2013 15:37:59 -0400 Subject: [PATCH 169/293] 6499673: Assertion check for TypeVariable.getUpperBound() fails Fix TypeVariable.getUpperBound to return results as specified Reviewed-by: jjg --- .../com/sun/tools/javac/code/Type.java | 2 +- .../com/sun/tools/javac/code/Types.java | 23 ++ .../com/sun/tools/javac/model/JavacTypes.java | 6 +- .../cast/intersection/model/Model01.java | 4 +- .../cast/intersection/model/ModelChecker.java | 2 +- .../processing/model/type/BoundsTest.java | 200 ++++++++++++++++++ .../type/IntersectionPropertiesTest.java | 135 ++++++++++++ 7 files changed, 363 insertions(+), 9 deletions(-) create mode 100644 langtools/test/tools/javac/processing/model/type/BoundsTest.java create mode 100644 langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index a6e4642ce51..699ac7ebedc 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -977,7 +977,7 @@ public abstract class Type implements TypeMirror { } public java.util.List getBounds() { - return Collections.unmodifiableList(getComponents()); + return Collections.unmodifiableList(getExplicitComponents()); } public List getComponents() { 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 996bcd88018..84eaf4a431e 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 @@ -2414,6 +2414,29 @@ public class Types { } }; + public List directSupertypes(Type t) { + return directSupertypes.visit(t); + } + // where + private final UnaryVisitor> directSupertypes = new UnaryVisitor>() { + + public List visitType(final Type type, final Void ignored) { + if (!type.isCompound()) { + final Type sup = supertype(type); + return (sup == Type.noType || sup == type || sup == null) + ? interfaces(type) + : interfaces(type).prepend(sup); + } else { + return visitIntersectionType((IntersectionClassType) type); + } + } + + private List visitIntersectionType(final IntersectionClassType it) { + return it.getExplicitComponents(); + } + + }; + public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) { for (Type i2 : interfaces(origin.type)) { if (isym == i2.tsym) return true; diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java index 14e377fb37f..726264bb79c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java @@ -116,11 +116,7 @@ public class JavacTypes implements javax.lang.model.util.Types { public List directSupertypes(TypeMirror t) { validateTypeNotIn(t, EXEC_OR_PKG); - Type type = (Type) t; - Type sup = types.supertype(type); - return (sup == Type.noType || sup == type || sup == null) - ? types.interfaces(type) - : types.interfaces(type).prepend(sup); + return types.directSupertypes((Type) t); } public TypeMirror erasure(TypeMirror t) { diff --git a/langtools/test/tools/javac/cast/intersection/model/Model01.java b/langtools/test/tools/javac/cast/intersection/model/Model01.java index 21740179f49..782644726ca 100644 --- a/langtools/test/tools/javac/cast/intersection/model/Model01.java +++ b/langtools/test/tools/javac/cast/intersection/model/Model01.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8002099 + * @bug 8002099 6499673 * @summary Add support for intersection types in cast expression * @library /tools/javac/lib * @build JavacTestingAbstractProcessor ModelChecker @@ -46,7 +46,7 @@ class Test { } void test(){ - @IntersectionTypeInfo({"java.lang.Object", "Test.A", "Test.B"}) + @IntersectionTypeInfo({"Test.A", "Test.B"}) Object o = (A & B)null; } } diff --git a/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java b/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java index 1486d21bf1b..d2dbf697fdc 100644 --- a/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java +++ b/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java @@ -97,7 +97,7 @@ public class ModelChecker extends JavacTestingAbstractProcessor { } } - assertTrue(assertionCount == 10, "Expected 10 assertions - found " + assertionCount); + assertTrue(assertionCount == 9, "Expected 9 assertions - found " + assertionCount); return super.visitVariable(node, p); } } diff --git a/langtools/test/tools/javac/processing/model/type/BoundsTest.java b/langtools/test/tools/javac/processing/model/type/BoundsTest.java new file mode 100644 index 00000000000..59c73ef6a0c --- /dev/null +++ b/langtools/test/tools/javac/processing/model/type/BoundsTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6499673 + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor BoundsTest + * @run main BoundsTest + * @summary Assertion check for TypeVariable.getUpperBound() fails + */ + +import com.sun.source.util.*; +import com.sun.tools.javac.api.*; +import com.sun.tools.javac.file.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.type.*; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.element.*; +import javax.tools.*; +import java.util.*; +import java.io.*; + +public class BoundsTest { + + private int errors = 0; + private static final String Intersection_name = "IntersectionTest.java"; + private static final String Intersection_contents = + "import java.util.List;\n" + + "import java.io.Serializable;\t" + + "public class IntersectionTest {\n" + + " void method(S s) { }\n" + + "}"; + private static final String[] Intersection_bounds = { + "java.util.List", + "java.io.Serializable" + }; + private static final String[] Intersection_supers = { + "java.util.List", + "java.io.Serializable" + }; + + private static final String Single_name = "SingleTest.java"; + private static final String Single_contents = + "import java.util.List;\n" + + "public class SingleTest {\n" + + " void method(S s) { }\n" + + "}"; + private static final String[] Single_bounds = { + "java.util.List", + }; + private static final String[] Single_supers = { + "java.lang.Object", + "java.util.Collection" + }; + + private static final String NoBounds_name = "NoBoundsTest.java"; + private static final String NoBounds_contents = + "public class NoBoundsTest {\n" + + " void method(S s) { }\n" + + "}"; + private static final String[] NoBounds_bounds = { + "java.lang.Object", + }; + private static final String[] NoBounds_supers = {}; + + private HashSet expected_bounds; + private HashSet expected_supers; + + private static final File classesdir = new File("intersectionproperties"); + private static final JavaCompiler comp = + ToolProvider.getSystemJavaCompiler(); + private static final StandardJavaFileManager fm = + comp.getStandardFileManager(null, null, null); + + public void runOne(final String Test_name, final String Test_contents, + final String[] Test_bounds, final String[] Test_supers) + throws IOException { + System.err.println("Testing " + Test_name); + expected_bounds = new HashSet(Arrays.asList(Test_bounds)); + expected_supers = new HashSet(Arrays.asList(Test_supers)); + final Iterable files = + fm.getJavaFileObjectsFromFiles(Collections.singleton(writeFile(classesdir, Test_name, Test_contents))); + final JavacTask ct = + (JavacTask)comp.getTask(null, fm, null, null, null, files); + ct.setProcessors(Collections.singleton(new TestProcessor())); + + if (!ct.call()) { + System.err.println("Compilation unexpectedly failed"); + errors++; + } + } + + public void run() throws IOException { + runOne(Intersection_name, Intersection_contents, + Intersection_bounds, Intersection_supers); + runOne(Single_name, Single_contents, + Single_bounds, Single_supers); + runOne(NoBounds_name, NoBounds_contents, + NoBounds_bounds, NoBounds_supers); + + if (0 != errors) + throw new RuntimeException(errors + " errors occurred"); + } + + public static void main(String... args) throws IOException { + new IntersectionPropertiesTest().run(); + } + + private static File writeFile(File dir, String path, String body) + throws IOException { + File f = new File(dir, path); + f.getParentFile().mkdirs(); + try (FileWriter out = new FileWriter(f)) { + out.write(body); + } + return f; + } + + private class TestProcessor extends JavacTestingAbstractProcessor { + + private Set rootElements; + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + rootElements = roundEnv.getRootElements(); + if (!rootElements.isEmpty()) { + performCheck(); + } + return true; + } + + private void performCheck() { + TypeElement typeElement = (TypeElement) rootElements.iterator().next(); + ExecutableElement method = ElementFilter.methodsIn(typeElement.getEnclosedElements()).get(0); + TypeVariable typeVariable = (TypeVariable) method.getParameters().get(0).asType(); + + final TypeMirror upperBound = typeVariable.getUpperBound(); + + TypeParameterElement typeParameterElement = ((TypeParameterElement) typeVariable.asElement()); + final List bounds = typeParameterElement.getBounds(); + final List supers = processingEnv.getTypeUtils().directSupertypes(upperBound); + + final HashSet actual_bounds = new HashSet(); + final HashSet actual_supers = new HashSet(); + + for(TypeMirror ty : bounds) { + actual_bounds.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName()); + } + + for(TypeMirror ty : supers) { + actual_supers.add(((TypeElement)((DeclaredType)ty).asElement()).getQualifiedName()); + } + + + if (!expected_bounds.equals(actual_bounds)) { + System.err.println("Mismatched expected and actual bounds."); + System.err.println("Expected:"); + for(CharSequence tm : expected_bounds) + System.err.println(" " + tm); + System.err.println("Actual:"); + for(CharSequence tm : actual_bounds) + System.err.println(" " + tm); + errors++; + } + + if (!expected_supers.equals(actual_supers)) { + System.err.println("Mismatched expected and actual bounds."); + System.err.println("Expected:"); + for(CharSequence tm : expected_supers) + System.err.println(" " + tm); + System.err.println("Actual:"); + for(CharSequence tm : actual_supers) + System.err.println(" " + tm); + errors++; + } + } + } + +} diff --git a/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java b/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java new file mode 100644 index 00000000000..9beeb6392c8 --- /dev/null +++ b/langtools/test/tools/javac/processing/model/type/IntersectionPropertiesTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6499673 + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor IntersectionPropertiesTest + * @run main IntersectionPropertiesTest + * @summary Assertion check for TypeVariable.getUpperBound() fails + */ + +import com.sun.source.util.*; +import com.sun.tools.javac.api.*; +import com.sun.tools.javac.file.*; +import javax.annotation.processing.*; +import javax.lang.model.SourceVersion; +import javax.lang.model.type.*; +import javax.lang.model.util.ElementFilter; +import javax.lang.model.element.*; +import javax.tools.*; +import java.util.*; +import java.io.*; + +public class IntersectionPropertiesTest { + + private int errors = 0; + private static final String Intersection_name = "IntersectionTest.java"; + private static final String Intersection_contents = + "import java.util.List;\n" + + "import java.io.Serializable;\t" + + "public class IntersectionTest {\n" + + " void method(S s) { }\n" + + "}"; + + private static final File classesdir = new File("intersectionproperties"); + private static final JavaCompiler comp = + ToolProvider.getSystemJavaCompiler(); + private static final StandardJavaFileManager fm = + comp.getStandardFileManager(null, null, null); + + public void runOne(final String Test_name, final String Test_contents) + throws IOException { + System.err.println("Testing " + Test_name); + final Iterable files = + fm.getJavaFileObjectsFromFiles(Collections.singleton(writeFile(classesdir, Test_name, Test_contents))); + final JavacTask ct = + (JavacTask)comp.getTask(null, fm, null, null, null, files); + ct.setProcessors(Collections.singleton(new TestProcessor())); + + if (!ct.call()) { + System.err.println("Compilation unexpectedly failed"); + errors++; + } + } + + public void run() throws IOException { + runOne(Intersection_name, Intersection_contents); + + if (0 != errors) + throw new RuntimeException(errors + " errors occurred"); + } + + public static void main(String... args) throws IOException { + new IntersectionPropertiesTest().run(); + } + + private static File writeFile(File dir, String path, String body) + throws IOException { + File f = new File(dir, path); + f.getParentFile().mkdirs(); + try (FileWriter out = new FileWriter(f)) { + out.write(body); + } + return f; + } + + private class TestProcessor extends JavacTestingAbstractProcessor { + + private Set rootElements; + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + rootElements = roundEnv.getRootElements(); + if (!rootElements.isEmpty()) { + performCheck(); + } + return true; + } + + private void performCheck() { + TypeElement typeElement = (TypeElement) rootElements.iterator().next(); + ExecutableElement method = ElementFilter.methodsIn(typeElement.getEnclosedElements()).get(0); + TypeVariable typeVariable = (TypeVariable) method.getParameters().get(0).asType(); + + final TypeMirror upperBound = typeVariable.getUpperBound(); + + TypeParameterElement typeParameterElement = ((TypeParameterElement) typeVariable.asElement()); + final List bounds = typeParameterElement.getBounds(); + final HashSet actual = new HashSet(processingEnv.getTypeUtils().directSupertypes(upperBound)); + final HashSet expected = new HashSet(bounds); + if (!expected.equals(actual)) { + System.err.println("Mismatched expected and actual bounds."); + System.err.println("Expected:"); + for(TypeMirror tm : expected) + System.err.println(" " + tm); + System.err.println("Actual:"); + for(TypeMirror tm : actual) + System.err.println(" " + tm); + errors++; + } + } + + } + +} From bd9ffce26767c480b4b4212d414f22bb712bb4a1 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 26 Sep 2013 12:49:45 +0200 Subject: [PATCH 170/293] 8014078: G1: improve remembered set summary information by providing per region type information Add memory consumption breakdown on a per region type in the G1 remembered set summary statistics. This simplifies remembered set memory consumption analysis. Reviewed-by: brutisso --- .../gc_implementation/g1/g1CollectedHeap.cpp | 7 +- .../vm/gc_implementation/g1/g1RemSet.cpp | 4 +- .../vm/gc_implementation/g1/g1RemSet.hpp | 2 +- .../gc_implementation/g1/g1RemSetSummary.cpp | 243 +++++++++++++----- .../test/gc/g1/TestSummarizeRSetStats.java | 149 +++-------- .../g1/TestSummarizeRSetStatsPerRegion.java | 55 ++++ .../gc/g1/TestSummarizeRSetStatsTools.java | 154 +++++++++++ 7 files changed, 430 insertions(+), 184 deletions(-) create mode 100644 hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java create mode 100644 hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 0ecfd3ab3bb..eff0efc6e0f 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -3681,6 +3681,11 @@ void G1CollectedHeap::gc_prologue(bool full /* Ignored */) { assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); // Fill TLAB's and such ensure_parsability(true); + + if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) && + (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { + g1_rem_set()->print_periodic_summary_info("Before GC RS summary"); + } } void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { @@ -3689,7 +3694,7 @@ void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { (G1SummarizeRSetStatsPeriod > 0) && // we are at the end of the GC. Total collections has already been increased. ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) { - g1_rem_set()->print_periodic_summary_info(); + g1_rem_set()->print_periodic_summary_info("After GC RS summary"); } // FIXME: what is this about? diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index 5a1b92d3422..a8c580b60cd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -731,12 +731,12 @@ bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i, return has_refs_into_cset; } -void G1RemSet::print_periodic_summary_info() { +void G1RemSet::print_periodic_summary_info(const char* header) { G1RemSetSummary current; current.initialize(this, n_workers()); _prev_period_summary.subtract_from(¤t); - print_summary_info(&_prev_period_summary); + print_summary_info(&_prev_period_summary, header); _prev_period_summary.set(¤t); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp index 513945609fc..7c010f9daf6 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp @@ -145,7 +145,7 @@ public: virtual void print_summary_info(); // Print accumulated summary info from the last time called. - virtual void print_periodic_summary_info(); + virtual void print_periodic_summary_info(const char* header); // Prepare remembered set for verification. virtual void prepare_for_verify(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp index 4a6b37654d7..02e90d65103 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp @@ -125,25 +125,115 @@ void G1RemSetSummary::subtract_from(G1RemSetSummary* other) { _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime; } -class HRRSStatsIter: public HeapRegionClosure { - size_t _occupied; +static double percent_of(size_t numerator, size_t denominator) { + if (denominator != 0) { + return (double)numerator / denominator * 100.0f; + } else { + return 0.0f; + } +} + +static size_t round_to_K(size_t value) { + return value / K; +} + +class RegionTypeCounter VALUE_OBJ_CLASS_SPEC { +private: + const char* _name; + + size_t _rs_mem_size; + size_t _cards_occupied; + size_t _amount; + + size_t _code_root_mem_size; + size_t _code_root_elems; + + double rs_mem_size_percent_of(size_t total) { + return percent_of(_rs_mem_size, total); + } + + double cards_occupied_percent_of(size_t total) { + return percent_of(_cards_occupied, total); + } + + double code_root_mem_size_percent_of(size_t total) { + return percent_of(_code_root_mem_size, total); + } + + double code_root_elems_percent_of(size_t total) { + return percent_of(_code_root_elems, total); + } + + size_t amount() const { return _amount; } + +public: + + RegionTypeCounter(const char* name) : _name(name), _rs_mem_size(0), _cards_occupied(0), + _amount(0), _code_root_mem_size(0), _code_root_elems(0) { } + + void add(size_t rs_mem_size, size_t cards_occupied, size_t code_root_mem_size, + size_t code_root_elems) { + _rs_mem_size += rs_mem_size; + _cards_occupied += cards_occupied; + _code_root_mem_size += code_root_mem_size; + _code_root_elems += code_root_elems; + _amount++; + } + + size_t rs_mem_size() const { return _rs_mem_size; } + size_t cards_occupied() const { return _cards_occupied; } + + size_t code_root_mem_size() const { return _code_root_mem_size; } + size_t code_root_elems() const { return _code_root_elems; } + + void print_rs_mem_info_on(outputStream * out, size_t total) { + out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(rs_mem_size()), rs_mem_size_percent_of(total), amount(), _name); + } + + void print_cards_occupied_info_on(outputStream * out, size_t total) { + out->print_cr(" %8d (%5.1f%%) entries by %zd %s regions", cards_occupied(), cards_occupied_percent_of(total), amount(), _name); + } + + void print_code_root_mem_info_on(outputStream * out, size_t total) { + out->print_cr(" %8dK (%5.1f%%) by %zd %s regions", round_to_K(code_root_mem_size()), code_root_mem_size_percent_of(total), amount(), _name); + } + + void print_code_root_elems_info_on(outputStream * out, size_t total) { + out->print_cr(" %8d (%5.1f%%) elements by %zd %s regions", code_root_elems(), code_root_elems_percent_of(total), amount(), _name); + } +}; + + +class HRRSStatsIter: public HeapRegionClosure { +private: + RegionTypeCounter _young; + RegionTypeCounter _humonguous; + RegionTypeCounter _free; + RegionTypeCounter _old; + RegionTypeCounter _all; - size_t _total_rs_mem_sz; size_t _max_rs_mem_sz; HeapRegion* _max_rs_mem_sz_region; - size_t _total_code_root_mem_sz; + size_t total_rs_mem_sz() const { return _all.rs_mem_size(); } + size_t total_cards_occupied() const { return _all.cards_occupied(); } + + size_t max_rs_mem_sz() const { return _max_rs_mem_sz; } + HeapRegion* max_rs_mem_sz_region() const { return _max_rs_mem_sz_region; } + size_t _max_code_root_mem_sz; HeapRegion* _max_code_root_mem_sz_region; + + size_t total_code_root_mem_sz() const { return _all.code_root_mem_size(); } + size_t total_code_root_elems() const { return _all.code_root_elems(); } + + size_t max_code_root_mem_sz() const { return _max_code_root_mem_sz; } + HeapRegion* max_code_root_mem_sz_region() const { return _max_code_root_mem_sz_region; } + public: - HRRSStatsIter() : - _occupied(0), - _total_rs_mem_sz(0), - _max_rs_mem_sz(0), - _max_rs_mem_sz_region(NULL), - _total_code_root_mem_sz(0), - _max_code_root_mem_sz(0), - _max_code_root_mem_sz_region(NULL) + HRRSStatsIter() : _all("All"), _young("Young"), _humonguous("Humonguous"), + _free("Free"), _old("Old"), _max_code_root_mem_sz_region(NULL), _max_rs_mem_sz_region(NULL), + _max_rs_mem_sz(0), _max_code_root_mem_sz(0) {} bool doHeapRegion(HeapRegion* r) { @@ -156,46 +246,95 @@ public: _max_rs_mem_sz = rs_mem_sz; _max_rs_mem_sz_region = r; } - _total_rs_mem_sz += rs_mem_sz; - + size_t occupied_cards = hrrs->occupied(); size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size(); - if (code_root_mem_sz > _max_code_root_mem_sz) { - _max_code_root_mem_sz = code_root_mem_sz; + if (code_root_mem_sz > max_code_root_mem_sz()) { _max_code_root_mem_sz_region = r; } - _total_code_root_mem_sz += code_root_mem_sz; + size_t code_root_elems = hrrs->strong_code_roots_list_length(); + + RegionTypeCounter* current = NULL; + if (r->is_young()) { + current = &_young; + } else if (r->isHumongous()) { + current = &_humonguous; + } else if (r->is_empty()) { + current = &_free; + } else { + current = &_old; + } + current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); + _all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems); - size_t occ = hrrs->occupied(); - _occupied += occ; return false; } - size_t total_rs_mem_sz() { return _total_rs_mem_sz; } - size_t max_rs_mem_sz() { return _max_rs_mem_sz; } - HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; } - size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; } - size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; } - HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; } - size_t occupied() { return _occupied; } + + void print_summary_on(outputStream* out) { + RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL }; + + out->print_cr("\n Current rem set statistics"); + out->print_cr(" Total per region rem sets sizes = "SIZE_FORMAT"K." + " Max = "SIZE_FORMAT"K.", + round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz())); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_rs_mem_info_on(out, total_rs_mem_sz()); + } + + out->print_cr(" Static structures = "SIZE_FORMAT"K," + " free_lists = "SIZE_FORMAT"K.", + round_to_K(HeapRegionRemSet::static_mem_size()), + round_to_K(HeapRegionRemSet::fl_mem_size())); + + out->print_cr(" "SIZE_FORMAT" occupied cards represented.", + total_cards_occupied()); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_cards_occupied_info_on(out, total_cards_occupied()); + } + + // Largest sized rem set region statistics + HeapRegionRemSet* rem_set = max_rs_mem_sz_region()->rem_set(); + out->print_cr(" Region with largest rem set = "HR_FORMAT", " + "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", + HR_FORMAT_PARAMS(max_rs_mem_sz_region()), + round_to_K(rem_set->mem_size()), + round_to_K(rem_set->occupied())); + + // Strong code root statistics + HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set(); + out->print_cr(" Total heap region code root sets sizes = "SIZE_FORMAT"K." + " Max = "SIZE_FORMAT"K.", + round_to_K(total_code_root_mem_sz()), + round_to_K(max_code_root_rem_set->strong_code_roots_mem_size())); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz()); + } + + out->print_cr(" "SIZE_FORMAT" code roots represented.", + total_code_root_elems()); + for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { + (*current)->print_code_root_elems_info_on(out, total_code_root_elems()); + } + + out->print_cr(" Region with largest amount of code roots = "HR_FORMAT", " + "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", + HR_FORMAT_PARAMS(max_code_root_mem_sz_region()), + round_to_K(max_code_root_rem_set->strong_code_roots_mem_size()), + round_to_K(max_code_root_rem_set->strong_code_roots_list_length())); + } }; -double calc_percentage(size_t numerator, size_t denominator) { - if (denominator != 0) { - return (double)numerator / denominator * 100.0; - } else { - return 0.0f; - } -} - void G1RemSetSummary::print_on(outputStream* out) { - out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards", + out->print_cr("\n Recent concurrent refinement statistics"); + out->print_cr(" Processed "SIZE_FORMAT" cards", num_concurrent_refined_cards()); out->print_cr(" Of %d completed buffers:", num_processed_buf_total()); out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.", num_processed_buf_total(), - calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total())); + percent_of(num_processed_buf_rs_threads(), num_processed_buf_total())); out->print_cr(" %8d (%5.1f%%) by mutator threads.", num_processed_buf_mutator(), - calc_percentage(num_processed_buf_mutator(), num_processed_buf_total())); + percent_of(num_processed_buf_mutator(), num_processed_buf_total())); + out->print_cr(" Did %d coarsenings.", num_coarsenings()); out->print_cr(" Concurrent RS threads times (s)"); out->print(" "); for (uint i = 0; i < _num_vtimes; i++) { @@ -207,33 +346,5 @@ void G1RemSetSummary::print_on(outputStream* out) { HRRSStatsIter blk; G1CollectedHeap::heap()->heap_region_iterate(&blk); - // RemSet stats - out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K." - " Max = "SIZE_FORMAT"K.", - blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K); - out->print_cr(" Static structures = "SIZE_FORMAT"K," - " free_lists = "SIZE_FORMAT"K.", - HeapRegionRemSet::static_mem_size() / K, - HeapRegionRemSet::fl_mem_size() / K); - out->print_cr(" "SIZE_FORMAT" occupied cards represented.", - blk.occupied()); - HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region(); - HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set(); - out->print_cr(" Max size region = "HR_FORMAT", " - "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", - HR_FORMAT_PARAMS(max_rs_mem_sz_region), - (max_rs_rem_set->mem_size() + K - 1)/K, - (max_rs_rem_set->occupied() + K - 1)/K); - out->print_cr(" Did %d coarsenings.", num_coarsenings()); - // Strong code root stats - out->print_cr(" Total heap region code-root set sizes = "SIZE_FORMAT"K." - " Max = "SIZE_FORMAT"K.", - blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K); - HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region(); - HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set(); - out->print_cr(" Max size region = "HR_FORMAT", " - "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".", - HR_FORMAT_PARAMS(max_code_root_mem_sz_region), - (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K, - (max_code_root_rem_set->strong_code_roots_list_length())); + blk.print_summary_on(out); } diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStats.java b/hotspot/test/gc/g1/TestSummarizeRSetStats.java index 1990d4c6f39..e78e2df21a3 100644 --- a/hotspot/test/gc/g1/TestSummarizeRSetStats.java +++ b/hotspot/test/gc/g1/TestSummarizeRSetStats.java @@ -25,140 +25,61 @@ * @test TestSummarizeRSetStats.java * @bug 8013895 * @library /testlibrary - * @build TestSummarizeRSetStats + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStats * @summary Verify output of -XX:+G1SummarizeRSetStats * @run main TestSummarizeRSetStats * * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod. */ -import com.oracle.java.testlibrary.*; -import java.lang.Thread; -import java.util.ArrayList; -import java.util.Arrays; - -class RunSystemGCs { - // 4M size, both are directly allocated into the old gen - static Object[] largeObject1 = new Object[1024 * 1024]; - static Object[] largeObject2 = new Object[1024 * 1024]; - - static int[] temp; - - public static void main(String[] args) { - // create some cross-references between these objects - for (int i = 0; i < largeObject1.length; i++) { - largeObject1[i] = largeObject2; - } - - for (int i = 0; i < largeObject2.length; i++) { - largeObject2[i] = largeObject1; - } - - int numGCs = Integer.parseInt(args[0]); - - if (numGCs > 0) { - // try to force a minor collection: the young gen is 4M, the - // amount of data allocated below is roughly that (4*1024*1024 + - // some header data) - for (int i = 0; i < 1024 ; i++) { - temp = new int[1024]; - } - } - - for (int i = 0; i < numGCs - 1; i++) { - System.gc(); - } - } -} - public class TestSummarizeRSetStats { - public static String runTest(String[] additionalArgs, int numGCs) throws Exception { - ArrayList finalargs = new ArrayList(); - String[] defaultArgs = new String[] { - "-XX:+UseG1GC", - "-Xmn4m", - "-Xmx20m", - "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking - "-XX:+PrintGC", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:G1HeapRegionSize=1M", - }; - - finalargs.addAll(Arrays.asList(defaultArgs)); - - if (additionalArgs != null) { - finalargs.addAll(Arrays.asList(additionalArgs)); - } - - finalargs.add(RunSystemGCs.class.getName()); - finalargs.add(String.valueOf(numGCs)); - - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - finalargs.toArray(new String[0])); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - - output.shouldHaveExitValue(0); - - String result = output.getStdout(); - return result; - } - - private static void expectStatistics(String result, int expectedCumulative, int expectedPeriodic) throws Exception { - int actualTotal = result.split("Concurrent RS processed").length - 1; - int actualCumulative = result.split("Cumulative RS summary").length - 1; - - if (expectedCumulative != actualCumulative) { - throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative); - } - - if (expectedPeriodic != (actualTotal - actualCumulative)) { - throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative)); - } - } - public static void main(String[] args) throws Exception { String result; - // no RSet statistics output - result = runTest(null, 0); - expectStatistics(result, 0, 0); + if (!TestSummarizeRSetStatsTools.testingG1GC()) { + return; + } - // no RSet statistics output - result = runTest(null, 2); - expectStatistics(result, 0, 0); + // no remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(null, 0); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); - // no RSet statistics output - result = runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); - expectStatistics(result, 0, 0); + // no remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(null, 2); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); - // single RSet statistics output at the end - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); - expectStatistics(result, 1, 0); + // no remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 0, 0); - // single RSet statistics output at the end - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2); - expectStatistics(result, 1, 0); + // single remembered set summary output at the end + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); - // single RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0); - expectStatistics(result, 1, 0); + // single remembered set summary output at the end + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); - // two times RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); - expectStatistics(result, 1, 1); + // single remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 0); - // four times RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); - expectStatistics(result, 1, 3); + // two times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2); - // three times RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3); - expectStatistics(result, 1, 2); + // four times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 6); - // single RSet statistics output - result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3); - expectStatistics(result, 1, 1); + // three times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 4); + + // single remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3); + TestSummarizeRSetStatsTools.expectRSetSummaries(result, 1, 2); } } diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java b/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java new file mode 100644 index 00000000000..437cbc2c70e --- /dev/null +++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsPerRegion.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestSummarizeRSetStatsPerRegion.java + * @bug 8014078 + * @library /testlibrary + * @build TestSummarizeRSetStatsTools TestSummarizeRSetStatsPerRegion + * @summary Verify output of -XX:+G1SummarizeRSetStats in regards to per-region type output + * @run main TestSummarizeRSetStatsPerRegion + */ + +import com.oracle.java.testlibrary.*; +import java.lang.Thread; +import java.util.ArrayList; +import java.util.Arrays; + +public class TestSummarizeRSetStatsPerRegion { + + public static void main(String[] args) throws Exception { + String result; + + if (!TestSummarizeRSetStatsTools.testingG1GC()) { + return; + } + + // single remembered set summary output at the end + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0); + TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 0); + + // two times remembered set summary output + result = TestSummarizeRSetStatsTools.runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1); + TestSummarizeRSetStatsTools.expectPerRegionRSetSummaries(result, 1, 2); + } +} diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java b/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java new file mode 100644 index 00000000000..096a7c675b5 --- /dev/null +++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsTools.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * Common helpers for TestSummarizeRSetStats* tests + */ + +import sun.management.ManagementFactoryHelper; +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; + +import com.oracle.java.testlibrary.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.lang.Thread; +import java.util.ArrayList; +import java.util.Arrays; + +class VerifySummaryOutput { + // 4M size, both are directly allocated into the old gen + static Object[] largeObject1 = new Object[1024 * 1024]; + static Object[] largeObject2 = new Object[1024 * 1024]; + + static int[] temp; + + public static void main(String[] args) { + // create some cross-references between these objects + for (int i = 0; i < largeObject1.length; i++) { + largeObject1[i] = largeObject2; + } + + for (int i = 0; i < largeObject2.length; i++) { + largeObject2[i] = largeObject1; + } + + int numGCs = Integer.parseInt(args[0]); + + if (numGCs > 0) { + // try to force a minor collection: the young gen is 4M, the + // amount of data allocated below is roughly that (4*1024*1024 + + // some header data) + for (int i = 0; i < 1024 ; i++) { + temp = new int[1024]; + } + } + + for (int i = 0; i < numGCs - 1; i++) { + System.gc(); + } + } +} + +public class TestSummarizeRSetStatsTools { + + // the VM is currently run using G1GC, i.e. trying to test G1 functionality. + public static boolean testingG1GC() { + HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + + VMOption option = diagnostic.getVMOption("UseG1GC"); + if (option.getValue().equals("false")) { + System.out.println("Skipping this test. It is only a G1 test."); + return false; + } + return true; + } + + public static String runTest(String[] additionalArgs, int numGCs) throws Exception { + ArrayList finalargs = new ArrayList(); + String[] defaultArgs = new String[] { + "-XX:+UseG1GC", + "-XX:+UseCompressedOops", + "-Xmn4m", + "-Xmx20m", + "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking + "-XX:+PrintGC", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:G1HeapRegionSize=1M", + }; + + finalargs.addAll(Arrays.asList(defaultArgs)); + + if (additionalArgs != null) { + finalargs.addAll(Arrays.asList(additionalArgs)); + } + + finalargs.add(VerifySummaryOutput.class.getName()); + finalargs.add(String.valueOf(numGCs)); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + finalargs.toArray(new String[0])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + output.shouldHaveExitValue(0); + + String result = output.getStdout(); + return result; + } + + private static void checkCounts(int expected, int actual, String which) throws Exception { + if (expected != actual) { + throw new Exception("RSet summaries mention " + which + " regions an incorrect number of times. Expected " + expected + ", got " + actual); + } + } + + public static void expectPerRegionRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception { + expectRSetSummaries(result, expectedCumulative, expectedPeriodic); + int actualYoung = result.split("Young regions").length - 1; + int actualHumonguous = result.split("Humonguous regions").length - 1; + int actualFree = result.split("Free regions").length - 1; + int actualOther = result.split("Old regions").length - 1; + + // the strings we check for above are printed four times per summary + int expectedPerRegionTypeInfo = (expectedCumulative + expectedPeriodic) * 4; + + checkCounts(expectedPerRegionTypeInfo, actualYoung, "Young"); + checkCounts(expectedPerRegionTypeInfo, actualHumonguous, "Humonguous"); + checkCounts(expectedPerRegionTypeInfo, actualFree, "Free"); + checkCounts(expectedPerRegionTypeInfo, actualOther, "Old"); + } + + public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception { + int actualTotal = result.split("concurrent refinement").length - 1; + int actualCumulative = result.split("Cumulative RS summary").length - 1; + + if (expectedCumulative != actualCumulative) { + throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative); + } + + if (expectedPeriodic != (actualTotal - actualCumulative)) { + throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative)); + } + } +} + From 27565b7f5d9dfcb099a4c7a95c13b48607853c7a Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Fri, 27 Sep 2013 10:23:12 +0200 Subject: [PATCH 171/293] 8025279: metaspace/flags/maxMetaspaceSize throws OOM: out of Compressed Klass space Only put "Compressed class space" as OOM cause if actually using Compressed class space Reviewed-by: jwilhelm, stefank, ehelin, coleenp --- hotspot/src/share/vm/memory/metaspace.cpp | 8 ++++---- hotspot/src/share/vm/memory/metaspace.hpp | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 06f3d09378a..7b9144942d9 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -3104,7 +3104,7 @@ size_t Metaspace::align_word_size_up(size_t word_size) { MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) { // DumpSharedSpaces doesn't use class metadata area (yet) // Also, don't use class_vsm() unless UseCompressedClassPointers is true. - if (mdtype == ClassType && using_class_space()) { + if (is_class_space_allocation(mdtype)) { return class_vsm()->allocate(word_size); } else { return vsm()->allocate(word_size); @@ -3252,8 +3252,8 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, MetaspaceAux::dump(gclog_or_tty); } // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support - const char* space_string = (mdtype == ClassType) ? "Compressed class space" : - "Metadata space"; + const char* space_string = is_class_space_allocation(mdtype) ? "Compressed class space" : + "Metadata space"; report_java_out_of_memory(space_string); if (JvmtiExport::should_post_resource_exhausted()) { @@ -3261,7 +3261,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, space_string); } - if (mdtype == ClassType) { + if (is_class_space_allocation(mdtype)) { THROW_OOP_0(Universe::out_of_memory_error_class_metaspace()); } else { THROW_OOP_0(Universe::out_of_memory_error_metaspace()); diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp index 29c07e15179..925d9c140d6 100644 --- a/hotspot/src/share/vm/memory/metaspace.hpp +++ b/hotspot/src/share/vm/memory/metaspace.hpp @@ -235,6 +235,9 @@ class Metaspace : public CHeapObj { return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces); } + static bool is_class_space_allocation(MetadataType mdType) { + return mdType == ClassType && using_class_space(); + } }; class MetaspaceAux : AllStatic { From b8363e6615bcc65a4aa3c1fe4799dcebb18dedbb Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Tue, 24 Sep 2013 14:46:29 +0200 Subject: [PATCH 172/293] 8025305: Cleanup CardTableModRefBS usage in G1 Move some G1 specific code from CardTableModRefBS to G1SATBCardTableModRefBS. Reviewed-by: brutisso, tschatzl, ehelin --- .../g1/concurrentMark.inline.hpp | 2 +- .../vm/gc_implementation/g1/g1CardCounts.cpp | 4 +- .../gc_implementation/g1/g1CollectedHeap.cpp | 46 ++++++---------- .../gc_implementation/g1/g1CollectedHeap.hpp | 12 +++-- .../g1/g1CollectedHeap.inline.hpp | 2 +- .../vm/gc_implementation/g1/g1EvacFailure.hpp | 4 +- .../vm/gc_implementation/g1/g1MarkSweep.cpp | 2 +- .../vm/gc_implementation/g1/g1RemSet.cpp | 11 ++-- .../g1/g1SATBCardTableModRefBS.cpp | 21 ++++++++ .../g1/g1SATBCardTableModRefBS.hpp | 36 +++++++++++++ .../src/share/vm/memory/cardTableModRefBS.cpp | 54 ------------------- .../src/share/vm/memory/cardTableModRefBS.hpp | 24 --------- 12 files changed, 90 insertions(+), 128 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp index d962842b39a..ea45f2d6466 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp @@ -81,7 +81,7 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr, size_t* marked_bytes_array, BitMap* task_card_bm) { G1CollectedHeap* g1h = _g1h; - CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set()); + CardTableModRefBS* ct_bs = g1h->g1_barrier_set(); HeapWord* start = mr.start(); HeapWord* end = mr.end(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp index 31972bf3c4e..59041d34ae2 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @@ -65,9 +65,7 @@ void G1CardCounts::initialize() { // threshold limit is no more than this. guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity"); - ModRefBarrierSet* bs = _g1h->mr_bs(); - guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); - _ct_bs = (CardTableModRefBS*)bs; + _ct_bs = _g1h->g1_barrier_set(); _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start()); // Allocate/Reserve the counts table diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index eff0efc6e0f..b5ea461690c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -125,10 +125,8 @@ class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { int _histo[256]; public: ClearLoggedCardTableEntryClosure() : - _calls(0) + _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) { - _g1h = G1CollectedHeap::heap(); - _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); for (int i = 0; i < 256; i++) _histo[i] = 0; } bool do_card_ptr(jbyte* card_ptr, int worker_i) { @@ -158,11 +156,8 @@ class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { CardTableModRefBS* _ctbs; public: RedirtyLoggedCardTableEntryClosure() : - _calls(0) - { - _g1h = G1CollectedHeap::heap(); - _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); - } + _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {} + bool do_card_ptr(jbyte* card_ptr, int worker_i) { if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { _calls++; @@ -478,7 +473,7 @@ bool G1CollectedHeap::is_scavengable(const void* p) { void G1CollectedHeap::check_ct_logs_at_safepoint() { DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); + CardTableModRefBS* ct_bs = g1_barrier_set(); // Count the dirty cards at the start. CountNonCleanMemRegionClosure count1(this); @@ -1205,7 +1200,7 @@ public: }; void G1CollectedHeap::clear_rsets_post_compaction() { - PostMCRemSetClearClosure rs_clear(this, mr_bs()); + PostMCRemSetClearClosure rs_clear(this, g1_barrier_set()); heap_region_iterate(&rs_clear); } @@ -2045,20 +2040,13 @@ jint G1CollectedHeap::initialize() { // Create the gen rem set (and barrier set) for the entire reserved region. _rem_set = collector_policy()->create_rem_set(_reserved, 2); set_barrier_set(rem_set()->bs()); - if (barrier_set()->is_a(BarrierSet::ModRef)) { - _mr_bs = (ModRefBarrierSet*)_barrier_set; - } else { - vm_exit_during_initialization("G1 requires a mod ref bs."); + if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) { + vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS"); return JNI_ENOMEM; } // Also create a G1 rem set. - if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { - _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); - } else { - vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); - return JNI_ENOMEM; - } + _g1_rem_set = new G1RemSet(this, g1_barrier_set()); // Carve out the G1 part of the heap. @@ -4555,7 +4543,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num) : _g1h(g1h), _refs(g1h->task_queue(queue_num)), _dcq(&g1h->dirty_card_queue_set()), - _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), + _ct_bs(g1h->g1_barrier_set()), _g1_rem(g1h->g1_rem_set()), _hash_seed(17), _queue_num(queue_num), _term_attempts(0), @@ -5984,11 +5972,11 @@ void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used, } class G1ParCleanupCTTask : public AbstractGangTask { - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; G1CollectedHeap* _g1h; HeapRegion* volatile _su_head; public: - G1ParCleanupCTTask(CardTableModRefBS* ct_bs, + G1ParCleanupCTTask(G1SATBCardTableModRefBS* ct_bs, G1CollectedHeap* g1h) : AbstractGangTask("G1 Par Cleanup CT Task"), _ct_bs(ct_bs), _g1h(g1h) { } @@ -6011,9 +5999,9 @@ public: #ifndef PRODUCT class G1VerifyCardTableCleanup: public HeapRegionClosure { G1CollectedHeap* _g1h; - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; public: - G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs) + G1VerifyCardTableCleanup(G1CollectedHeap* g1h, G1SATBCardTableModRefBS* ct_bs) : _g1h(g1h), _ct_bs(ct_bs) { } virtual bool doHeapRegion(HeapRegion* r) { if (r->is_survivor()) { @@ -6027,7 +6015,7 @@ public: void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) { // All of the region should be clean. - CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); MemRegion mr(hr->bottom(), hr->end()); ct_bs->verify_not_dirty_region(mr); } @@ -6040,13 +6028,13 @@ void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) { // not dirty that area (one less thing to have to do while holding // a lock). So we can only verify that [bottom(),pre_dummy_top()] // is dirty. - CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); MemRegion mr(hr->bottom(), hr->pre_dummy_top()); ct_bs->verify_dirty_region(mr); } void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) { - CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) { verify_dirty_region(hr); } @@ -6058,7 +6046,7 @@ void G1CollectedHeap::verify_dirty_young_regions() { #endif void G1CollectedHeap::cleanUpCardTable() { - CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); + G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); double start = os::elapsedTime(); { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 747b2326236..3a6a0c5f37e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -31,6 +31,7 @@ #include "gc_implementation/g1/g1HRPrinter.hpp" #include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/g1RemSet.hpp" +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/g1YCTypes.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionSets.hpp" @@ -791,8 +792,6 @@ protected: // The g1 remembered set of the heap. G1RemSet* _g1_rem_set; - // And it's mod ref barrier set, used to track updates for the above. - ModRefBarrierSet* _mr_bs; // A set of cards that cover the objects for which the Rsets should be updated // concurrently after the collection. @@ -1127,7 +1126,6 @@ public: // The rem set and barrier set. G1RemSet* g1_rem_set() const { return _g1_rem_set; } - ModRefBarrierSet* mr_bs() const { return _mr_bs; } unsigned get_gc_time_stamp() { return _gc_time_stamp; @@ -1346,6 +1344,10 @@ public: virtual bool is_in_closed_subset(const void* p) const; + G1SATBCardTableModRefBS* g1_barrier_set() { + return (G1SATBCardTableModRefBS*) barrier_set(); + } + // This resets the card table to all zeros. It is used after // a collection pause which used the card table to claim cards. void cleanUpCardTable(); @@ -1875,7 +1877,7 @@ protected: G1CollectedHeap* _g1h; RefToScanQueue* _refs; DirtyCardQueue _dcq; - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; G1RemSet* _g1_rem; G1ParGCAllocBufferContainer _surviving_alloc_buffer; @@ -1914,7 +1916,7 @@ protected: void add_to_undo_waste(size_t waste) { _undo_waste += waste; } DirtyCardQueue& dirty_card_queue() { return _dcq; } - CardTableModRefBS* ctbs() { return _ct_bs; } + G1SATBCardTableModRefBS* ctbs() { return _ct_bs; } template void immediate_rs_update(HeapRegion* from, T* p, int tid) { if (!from->is_survivor()) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp index 20eb1693c43..5cd3f7f21cd 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp @@ -134,7 +134,7 @@ G1CollectedHeap::dirty_young_block(HeapWord* start, size_t word_size) { assert(containing_hr->is_in(end - 1), "it should also contain end - 1"); MemRegion mr(start, end); - ((CardTableModRefBS*)_g1h->barrier_set())->dirty(mr); + g1_barrier_set()->dirty(mr); } inline RefToScanQueue* G1CollectedHeap::task_queue(int i) const { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp index 84d998265a9..1333f287047 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1EvacFailure.hpp @@ -41,11 +41,11 @@ class UpdateRSetDeferred : public OopsInHeapRegionClosure { private: G1CollectedHeap* _g1; DirtyCardQueue *_dcq; - CardTableModRefBS* _ct_bs; + G1SATBCardTableModRefBS* _ct_bs; public: UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : - _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {} + _g1(g1), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {} virtual void do_oop(narrowOop* p) { do_oop_work(p); } virtual void do_oop( oop* p) { do_oop_work(p); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp index 74aabc1298d..87650103d60 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @@ -220,7 +220,7 @@ class G1PrepareCompactClosure: public HeapRegionClosure { public: G1PrepareCompactClosure(CompactibleSpace* cs) : _g1h(G1CollectedHeap::heap()), - _mrbs(G1CollectedHeap::heap()->mr_bs()), + _mrbs(_g1h->g1_barrier_set()), _cp(NULL, cs, cs->initialize_threshold()), _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index a8c580b60cd..0e06c472ffa 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -109,7 +109,7 @@ class ScanRSClosure : public HeapRegionClosure { CodeBlobToOopClosure* _code_root_cl; G1BlockOffsetSharedArray* _bot_shared; - CardTableModRefBS *_ct_bs; + G1SATBCardTableModRefBS *_ct_bs; double _strong_code_root_scan_time_sec; int _worker_i; @@ -130,7 +130,7 @@ public: { _g1h = G1CollectedHeap::heap(); _bot_shared = _g1h->bot_shared(); - _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); + _ct_bs = _g1h->g1_barrier_set(); _block_size = MAX2(G1RSetScanBlockSize, 1); } @@ -505,12 +505,7 @@ public: ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) : _g1h(G1CollectedHeap::heap()), _region_bm(region_bm), _card_bm(card_bm), - _ctbs(NULL) - { - ModRefBarrierSet* bs = _g1h->mr_bs(); - guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition"); - _ctbs = (CardTableModRefBS*)bs; - } + _ctbs(_g1h->g1_barrier_set()) {} bool doHeapRegion(HeapRegion* r) { if (!r->continuesHumongous()) { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp index 218be0c0e40..48c737e74ab 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -64,6 +64,27 @@ G1SATBCardTableModRefBS::write_ref_array_pre_work(T* dst, int count) { } } +bool G1SATBCardTableModRefBS::mark_card_deferred(size_t card_index) { + jbyte val = _byte_map[card_index]; + // It's already processed + if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { + return false; + } + // Cached bit can be installed either on a clean card or on a claimed card. + jbyte new_val = val; + if (val == clean_card_val()) { + new_val = (jbyte)deferred_card_val(); + } else { + if (val & claimed_card_val()) { + new_val = val | (jbyte)deferred_card_val(); + } + } + if (new_val != val) { + Atomic::cmpxchg(new_val, &_byte_map[card_index], val); + } + return true; +} + G1SATBCardTableLoggingModRefBS:: G1SATBCardTableLoggingModRefBS(MemRegion whole_heap, int max_covered_regions) : diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp index 6f887583cab..4e807348102 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp @@ -89,6 +89,42 @@ public: write_ref_array_pre_work(dst, count); } } + +/* + Claimed and deferred bits are used together in G1 during the evacuation + pause. These bits can have the following state transitions: + 1. The claimed bit can be put over any other card state. Except that + the "dirty -> dirty and claimed" transition is checked for in + G1 code and is not used. + 2. Deferred bit can be set only if the previous state of the card + was either clean or claimed. mark_card_deferred() is wait-free. + We do not care if the operation is be successful because if + it does not it will only result in duplicate entry in the update + buffer because of the "cache-miss". So it's not worth spinning. + */ + + bool is_card_claimed(size_t card_index) { + jbyte val = _byte_map[card_index]; + return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val(); + } + + void set_card_claimed(size_t card_index) { + jbyte val = _byte_map[card_index]; + if (val == clean_card_val()) { + val = (jbyte)claimed_card_val(); + } else { + val |= (jbyte)claimed_card_val(); + } + _byte_map[card_index] = val; + } + + bool mark_card_deferred(size_t card_index); + + bool is_card_deferred(size_t card_index) { + jbyte val = _byte_map[card_index]; + return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); + } + }; // Adds card-table logging to the post-barrier. diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index 82336503eb4..5e9d843ff52 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -423,60 +423,6 @@ void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) { inline_write_ref_field(field, newVal); } -/* - Claimed and deferred bits are used together in G1 during the evacuation - pause. These bits can have the following state transitions: - 1. The claimed bit can be put over any other card state. Except that - the "dirty -> dirty and claimed" transition is checked for in - G1 code and is not used. - 2. Deferred bit can be set only if the previous state of the card - was either clean or claimed. mark_card_deferred() is wait-free. - We do not care if the operation is be successful because if - it does not it will only result in duplicate entry in the update - buffer because of the "cache-miss". So it's not worth spinning. - */ - - -bool CardTableModRefBS::claim_card(size_t card_index) { - jbyte val = _byte_map[card_index]; - assert(val != dirty_card_val(), "Shouldn't claim a dirty card"); - while (val == clean_card_val() || - (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) { - jbyte new_val = val; - if (val == clean_card_val()) { - new_val = (jbyte)claimed_card_val(); - } else { - new_val = val | (jbyte)claimed_card_val(); - } - jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val); - if (res == val) { - return true; - } - val = res; - } - return false; -} - -bool CardTableModRefBS::mark_card_deferred(size_t card_index) { - jbyte val = _byte_map[card_index]; - // It's already processed - if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { - return false; - } - // Cached bit can be installed either on a clean card or on a claimed card. - jbyte new_val = val; - if (val == clean_card_val()) { - new_val = (jbyte)deferred_card_val(); - } else { - if (val & claimed_card_val()) { - new_val = val | (jbyte)deferred_card_val(); - } - } - if (new_val != val) { - Atomic::cmpxchg(new_val, &_byte_map[card_index], val); - } - return true; -} void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp, MemRegion mr, diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp index 6b5de2a4460..cadb4cb88aa 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp @@ -339,34 +339,10 @@ public: _byte_map[card_index] = dirty_card_val(); } - bool is_card_claimed(size_t card_index) { - jbyte val = _byte_map[card_index]; - return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val(); - } - - void set_card_claimed(size_t card_index) { - jbyte val = _byte_map[card_index]; - if (val == clean_card_val()) { - val = (jbyte)claimed_card_val(); - } else { - val |= (jbyte)claimed_card_val(); - } - _byte_map[card_index] = val; - } - - bool claim_card(size_t card_index); - bool is_card_clean(size_t card_index) { return _byte_map[card_index] == clean_card_val(); } - bool is_card_deferred(size_t card_index) { - jbyte val = _byte_map[card_index]; - return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); - } - - bool mark_card_deferred(size_t card_index); - // Card marking array base (adjusted for heap low boundary) // This would be the 0th element of _byte_map, if the heap started at 0x0. // But since the heap starts at some higher address, this points to somewhere From a2889becd991625fb922b1916a6adcb4129d3fd7 Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Tue, 24 Sep 2013 15:56:25 +0200 Subject: [PATCH 173/293] 7009641: Don't fail VM when CodeCache is full Allocation in the code cache returns NULL instead of failing the entire VM Reviewed-by: kvn, iveresov --- hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp | 10 ++++++++++ hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp | 10 ++++++++++ hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp | 10 ++++++++++ hotspot/src/share/vm/code/compiledIC.cpp | 10 ++++++++-- hotspot/src/share/vm/code/compiledIC.hpp | 5 ++++- hotspot/src/share/vm/code/vtableStubs.cpp | 11 +++++++---- hotspot/src/share/vm/runtime/sharedRuntime.cpp | 7 +++++-- 7 files changed, 54 insertions(+), 9 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp index ce19d4d7e7b..cdbb57fbecd 100644 --- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp @@ -52,6 +52,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oopDesc* receiver, VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const int sparc_code_length = VtableStub::pd_code_size_limit(true); VtableStub* s = new(sparc_code_length) VtableStub(true, vtable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), sparc_code_length); MacroAssembler* masm = new MacroAssembler(&cb); @@ -125,6 +130,11 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { VtableStub* VtableStubs::create_itable_stub(int itable_index) { const int sparc_code_length = VtableStub::pd_code_size_limit(false); VtableStub* s = new(sparc_code_length) VtableStub(false, itable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), sparc_code_length); MacroAssembler* masm = new MacroAssembler(&cb); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp index c470004ebc8..7c49d737fa5 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp @@ -58,6 +58,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const int i486_code_length = VtableStub::pd_code_size_limit(true); VtableStub* s = new(i486_code_length) VtableStub(true, vtable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), i486_code_length); MacroAssembler* masm = new MacroAssembler(&cb); @@ -132,6 +137,11 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { // add code here, bump the code stub size returned by pd_code_size_limit! const int i486_code_length = VtableStub::pd_code_size_limit(false); VtableStub* s = new(i486_code_length) VtableStub(false, itable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), i486_code_length); MacroAssembler* masm = new MacroAssembler(&cb); diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp index 5f5f94f41a5..911341736d8 100644 --- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp @@ -49,6 +49,11 @@ extern "C" void bad_compiled_vtable_index(JavaThread* thread, VtableStub* VtableStubs::create_vtable_stub(int vtable_index) { const int amd64_code_length = VtableStub::pd_code_size_limit(true); VtableStub* s = new(amd64_code_length) VtableStub(true, vtable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), amd64_code_length); MacroAssembler* masm = new MacroAssembler(&cb); @@ -126,6 +131,11 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) { // returned by pd_code_size_limit! const int amd64_code_length = VtableStub::pd_code_size_limit(false); VtableStub* s = new(amd64_code_length) VtableStub(false, itable_index); + // Can be NULL if there is no free space in the code cache. + if (s == NULL) { + return NULL; + } + ResourceMark rm; CodeBuffer cb(s->entry_point(), amd64_code_length); MacroAssembler* masm = new MacroAssembler(&cb); diff --git a/hotspot/src/share/vm/code/compiledIC.cpp b/hotspot/src/share/vm/code/compiledIC.cpp index b9db323e5b2..489e649fadc 100644 --- a/hotspot/src/share/vm/code/compiledIC.cpp +++ b/hotspot/src/share/vm/code/compiledIC.cpp @@ -160,7 +160,7 @@ address CompiledIC::stub_address() const { // High-level access to an inline cache. Guaranteed to be MT-safe. -void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { +bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), ""); assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); @@ -170,8 +170,10 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod assert(bytecode == Bytecodes::_invokeinterface, ""); int itable_index = call_info->itable_index(); entry = VtableStubs::find_itable_stub(itable_index); + if (entry == false) { + return false; + } #ifdef ASSERT - assert(entry != NULL, "entry not computed"); int index = call_info->resolved_method()->itable_index(); assert(index == itable_index, "CallInfo pre-computes this"); #endif //ASSERT @@ -184,6 +186,9 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod int vtable_index = call_info->vtable_index(); assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check"); entry = VtableStubs::find_vtable_stub(vtable_index); + if (entry == NULL) { + return false; + } InlineCacheBuffer::create_transition_stub(this, NULL, entry); } @@ -200,6 +205,7 @@ void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod // race because the IC entry was complete when we safepointed so // cleaning it immediately is harmless. // assert(is_megamorphic(), "sanity check"); + return true; } diff --git a/hotspot/src/share/vm/code/compiledIC.hpp b/hotspot/src/share/vm/code/compiledIC.hpp index 96cb0a582bb..598cbe949e2 100644 --- a/hotspot/src/share/vm/code/compiledIC.hpp +++ b/hotspot/src/share/vm/code/compiledIC.hpp @@ -226,7 +226,10 @@ class CompiledIC: public ResourceObj { // void set_to_clean(); // Can only be called during a safepoint operation void set_to_monomorphic(CompiledICInfo& info); - void set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS); + + // Returns true if successful and false otherwise. The call can fail if memory + // allocation in the code cache fails. + bool set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS); static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass, bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS); diff --git a/hotspot/src/share/vm/code/vtableStubs.cpp b/hotspot/src/share/vm/code/vtableStubs.cpp index 7d9d7efaf67..5af91a3a6ee 100644 --- a/hotspot/src/share/vm/code/vtableStubs.cpp +++ b/hotspot/src/share/vm/code/vtableStubs.cpp @@ -46,12 +46,9 @@ address VtableStub::_chunk = NULL; address VtableStub::_chunk_end = NULL; VMReg VtableStub::_receiver_location = VMRegImpl::Bad(); -static int num_vtable_chunks = 0; - void* VtableStub::operator new(size_t size, int code_size) throw() { assert(size == sizeof(VtableStub), "mismatched size"); - num_vtable_chunks++; // compute real VtableStub size (rounded to nearest word) const int real_size = round_to(code_size + sizeof(VtableStub), wordSize); // malloc them in chunks to minimize header overhead @@ -60,7 +57,7 @@ void* VtableStub::operator new(size_t size, int code_size) throw() { const int bytes = chunk_factor * real_size + pd_code_alignment(); BufferBlob* blob = BufferBlob::create("vtable chunks", bytes); if (blob == NULL) { - vm_exit_out_of_memory(bytes, OOM_MALLOC_ERROR, "CodeCache: no room for vtable chunks"); + return NULL; } _chunk = blob->content_begin(); _chunk_end = _chunk + bytes; @@ -121,6 +118,12 @@ address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) { } else { s = create_itable_stub(vtable_index); } + + // Creation of vtable or itable can fail if there is not enough free space in the code cache. + if (s == NULL) { + return NULL; + } + enter(is_vtable_stub, vtable_index, s); if (PrintAdapterHandlers) { tty->print_cr("Decoding VtableStub %s[%d]@%d", diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index d014eda2f80..17ea65ae716 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1506,8 +1506,11 @@ methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) { info, CHECK_(methodHandle())); inline_cache->set_to_monomorphic(info); } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) { - // Change to megamorphic - inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle())); + // Potential change to megamorphic + bool successful = inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle())); + if (!successful) { + inline_cache->set_to_clean(); + } } else { // Either clean or megamorphic } From 93c8cbec9c0d600ea74c4ad3adf6e0d5edc85b53 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 24 Sep 2013 20:43:42 +0530 Subject: [PATCH 174/293] 8025312: parseInt should convert 'radix' argument to ToInt32 even if empty string is parsed Reviewed-by: jlaskey, hannesw --- .../internal/runtime/GlobalFunctions.java | 2 +- nashorn/test/script/basic/JDK-8025312.js | 35 +++++++++++++++++++ .../test/script/basic/JDK-8025312.js.EXPECTED | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8025312.js create mode 100644 nashorn/test/script/basic/JDK-8025312.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java index c504276f41c..9ddc7090b2b 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java @@ -90,6 +90,7 @@ public final class GlobalFunctions { public static double parseInt(final Object self, final Object string, final Object rad) { final String str = JSType.trimLeft(JSType.toString(string)); final int length = str.length(); + int radix = JSType.toInt32(rad); // empty string is not valid if (length == 0) { @@ -113,7 +114,6 @@ public final class GlobalFunctions { } boolean stripPrefix = true; - int radix = JSType.toInt32(rad); if (radix != 0) { if (radix < 2 || radix > 36) { diff --git a/nashorn/test/script/basic/JDK-8025312.js b/nashorn/test/script/basic/JDK-8025312.js new file mode 100644 index 00000000000..6f2b42f38af --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025312.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025312: parseInt should convert 'radix' argument to ToInt32 even if empty string is parsed + * + * @test + * @run + */ + +parseInt("", { + valueOf: function() { + print("inside valueOf of 'radix'"); + } +}); diff --git a/nashorn/test/script/basic/JDK-8025312.js.EXPECTED b/nashorn/test/script/basic/JDK-8025312.js.EXPECTED new file mode 100644 index 00000000000..31ffef83890 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025312.js.EXPECTED @@ -0,0 +1 @@ +inside valueOf of 'radix' From 14ceb05e0ea4914bffb6db708b8dd8e6992137c9 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 10:48:11 -0700 Subject: [PATCH 175/293] 8025050: Doclint doesn't recognize tag Reviewed-by: bpatel --- langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java | 3 +++ langtools/test/tools/doclint/html/InlineTagsTest.java | 1 + 2 files changed, 4 insertions(+) diff --git a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java index 3b8f8599e09..2ea92af9ac0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java @@ -86,6 +86,9 @@ public enum HtmlTag { DD(BlockType.LIST_ITEM, EndKind.OPTIONAL, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)), + DFN(BlockType.INLINE, EndKind.REQUIRED, + EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)), + DIV(BlockType.BLOCK, EndKind.REQUIRED, EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)), diff --git a/langtools/test/tools/doclint/html/InlineTagsTest.java b/langtools/test/tools/doclint/html/InlineTagsTest.java index 4835b36a9a0..5dda7c27c55 100644 --- a/langtools/test/tools/doclint/html/InlineTagsTest.java +++ b/langtools/test/tools/doclint/html/InlineTagsTest.java @@ -39,6 +39,7 @@ public class InlineTagsTest { *
    * abc * abc + * abc * abc * abc * abc From 026c5d762097591e6e60244ed4fd40cb80a5cd53 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 10:51:28 -0700 Subject: [PATCH 176/293] 8025246: [doclint] doclint is showing error on anchor already defined when it's not Reviewed-by: bpatel --- .../com/sun/tools/doclint/Checker.java | 25 +++++++-- .../tools/doclint/anchorTests/p/Test.java | 53 +++++++++++++++++++ .../doclint/anchorTests/p/Test.javac.out | 7 +++ .../test/tools/doclint/anchorTests/p/Test.out | 19 +++++++ .../doclint/anchorTests/p/package-info.java | 15 ++++++ .../anchorTests/p/package-info.javac.out | 2 + .../doclint/anchorTests/p/package-info.out | 4 ++ 7 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/doclint/anchorTests/p/Test.java create mode 100644 langtools/test/tools/doclint/anchorTests/p/Test.javac.out create mode 100644 langtools/test/tools/doclint/anchorTests/p/Test.out create mode 100644 langtools/test/tools/doclint/anchorTests/p/package-info.java create mode 100644 langtools/test/tools/doclint/anchorTests/p/package-info.javac.out create mode 100644 langtools/test/tools/doclint/anchorTests/p/package-info.out diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index d7d8ada40f0..fad2e9f46d4 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -93,7 +93,7 @@ public class Checker extends DocTreePathScanner { Set foundParams = new HashSet<>(); Set foundThrows = new HashSet<>(); - Map> foundAnchors = new HashMap<>(); + Map> foundAnchors = new HashMap<>(); boolean foundInheritDoc = false; boolean foundReturn = false; @@ -576,13 +576,30 @@ public class Checker extends DocTreePathScanner { } private boolean checkAnchor(String name) { - JavaFileObject fo = env.currPath.getCompilationUnit().getSourceFile(); - Set set = foundAnchors.get(fo); + Element e = getEnclosingPackageOrClass(env.currElement); + if (e == null) + return true; + Set set = foundAnchors.get(e); if (set == null) - foundAnchors.put(fo, set = new HashSet<>()); + foundAnchors.put(e, set = new HashSet<>()); return set.add(name); } + private Element getEnclosingPackageOrClass(Element e) { + while (e != null) { + switch (e.getKind()) { + case CLASS: + case ENUM: + case INTERFACE: + case PACKAGE: + return e; + default: + e = e.getEnclosingElement(); + } + } + return e; + } + // http://www.w3.org/TR/html401/types.html#type-name private static final Pattern validName = Pattern.compile("[A-Za-z][A-Za-z0-9-_:.]*"); diff --git a/langtools/test/tools/doclint/anchorTests/p/Test.java b/langtools/test/tools/doclint/anchorTests/p/Test.java new file mode 100644 index 00000000000..131629d7ac6 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/Test.java @@ -0,0 +1,53 @@ +/* @test /nodynamiccopyright/ + * @bug 8025246 + * @summary doclint is showing error on anchor already defined when it's not + * @library ../.. + * @build DocLintTester + * @run main DocLintTester -ref Test.out Test.java + * @compile/fail/ref=Test.javac.out -XDrawDiagnostics -Werror -Xdoclint:all Test.java + */ + +package p; + +/** + *
    dupTest + * dupTest again + * + * dupTestField + * dupTestMethod + + * okClass + * okField + * okMethod + */ +public class Test { + /** dupTestField again */ + public int f; + + /** dupTestMethod again */ + public void m() { } + + /** + * dupNested + * dupNested again + * dupNestedField + * dupNestedMethod + * + * okClass again + */ + public class Nested { + /** + * dupNestedField + * + * okField again + */ + public int f; + + /** + * dupNestedMethod + * + * okMethod again + */ + public void m() { } + } +} diff --git a/langtools/test/tools/doclint/anchorTests/p/Test.javac.out b/langtools/test/tools/doclint/anchorTests/p/Test.javac.out new file mode 100644 index 00000000000..44a723969eb --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/Test.javac.out @@ -0,0 +1,7 @@ +Test.java:14:7: compiler.err.proc.messager: anchor already defined: dupTest +Test.java:24:12: compiler.err.proc.messager: anchor already defined: dupTestField +Test.java:27:12: compiler.err.proc.messager: anchor already defined: dupTestMethod +Test.java:32:11: compiler.err.proc.messager: anchor already defined: dupNested +Test.java:40:15: compiler.err.proc.messager: anchor already defined: dupNestedField +Test.java:47:15: compiler.err.proc.messager: anchor already defined: dupNestedMethod +6 errors diff --git a/langtools/test/tools/doclint/anchorTests/p/Test.out b/langtools/test/tools/doclint/anchorTests/p/Test.out new file mode 100644 index 00000000000..6f39fcf1e28 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/Test.out @@ -0,0 +1,19 @@ +Test.java:14: error: anchor already defined: dupTest + * dupTest again + ^ +Test.java:24: error: anchor already defined: dupTestField + /** dupTestField again */ + ^ +Test.java:27: error: anchor already defined: dupTestMethod + /** dupTestMethod again */ + ^ +Test.java:32: error: anchor already defined: dupNested + * dupNested again + ^ +Test.java:40: error: anchor already defined: dupNestedField + * dupNestedField + ^ +Test.java:47: error: anchor already defined: dupNestedMethod + * dupNestedMethod + ^ +6 errors diff --git a/langtools/test/tools/doclint/anchorTests/p/package-info.java b/langtools/test/tools/doclint/anchorTests/p/package-info.java new file mode 100644 index 00000000000..af7682a3676 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.java @@ -0,0 +1,15 @@ +/* @test /nodynamiccopyright/ + * @bug 8025246 + * @summary doclint is showing error on anchor already defined when it's not + * @library ../.. + * @build DocLintTester + * @run main DocLintTester -ref package-info.out package-info.java + * @compile/fail/ref=package-info.javac.out -XDrawDiagnostics -Werror -Xdoclint:all package-info.java + */ + +/** + * here + * here again + */ +package p; + diff --git a/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out b/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out new file mode 100644 index 00000000000..0a859df5894 --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out @@ -0,0 +1,2 @@ +package-info.java:12:7: compiler.err.proc.messager: anchor already defined: here +1 error diff --git a/langtools/test/tools/doclint/anchorTests/p/package-info.out b/langtools/test/tools/doclint/anchorTests/p/package-info.out new file mode 100644 index 00000000000..dda1b19f0dd --- /dev/null +++ b/langtools/test/tools/doclint/anchorTests/p/package-info.out @@ -0,0 +1,4 @@ +package-info.java:12: error: anchor already defined: here + * here again + ^ +1 error From e762b2997d71aae9de597d0c74a8748a0187aed0 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 11:46:25 -0700 Subject: [PATCH 177/293] 8025272: doclint needs to check for valid usage of @value tag Reviewed-by: bpatel --- .../com/sun/tools/doclint/Checker.java | 24 +++++++ .../doclint/resources/doclint.properties | 2 + langtools/test/tools/doclint/ValueTest.java | 67 +++++++++++++++++++ langtools/test/tools/doclint/ValueTest.out | 22 ++++++ 4 files changed, 115 insertions(+) create mode 100644 langtools/test/tools/doclint/ValueTest.java create mode 100644 langtools/test/tools/doclint/ValueTest.out diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index fad2e9f46d4..c8d331a43c0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -44,6 +44,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic.Kind; @@ -822,10 +823,33 @@ public class Checker extends DocTreePathScanner { @Override public Void visitValue(ValueTree tree, Void ignore) { + ReferenceTree ref = tree.getReference(); + if (ref == null || ref.getSignature().isEmpty()) { + if (!isConstant(env.currElement)) + env.messages.error(REFERENCE, tree, "dc.value.not.allowed.here"); + } else { + Element e = env.trees.getElement(new DocTreePath(getCurrentPath(), ref)); + if (!isConstant(e)) + env.messages.error(REFERENCE, tree, "dc.value.not.a.constant"); + } + markEnclosingTag(Flag.HAS_INLINE_TAG); return super.visitValue(tree, ignore); } + private boolean isConstant(Element e) { + if (e == null) + return false; + + switch (e.getKind()) { + case FIELD: + Object value = ((VariableElement) e).getConstantValue(); + return (value != null); // can't distinguish "not a constant" from "constant is null" + default: + return false; + } + } + @Override public Void visitVersion(VersionTree tree, Void ignore) { warnIfEmpty(tree, tree.getBody()); diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties index 37470976141..24c3aac76e6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -68,6 +68,8 @@ dc.tag.start.unmatched = end tag missing: dc.tag.unknown = unknown tag: {0} dc.text.not.allowed = text not allowed in <{0}> element dc.unexpected.comment=documentation comment not expected here +dc.value.not.allowed.here='{@value}' not allowed here +dc.value.not.a.constant=value does not refer to a constant dc.main.ioerror=IO error: {0} dc.main.no.files.given=No files given diff --git a/langtools/test/tools/doclint/ValueTest.java b/langtools/test/tools/doclint/ValueTest.java new file mode 100644 index 00000000000..f9de36daf15 --- /dev/null +++ b/langtools/test/tools/doclint/ValueTest.java @@ -0,0 +1,67 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8025272 + * @summary doclint needs to check for valid usage of at-value tag + * @build DocLintTester + * @run main DocLintTester -ref ValueTest.out ValueTest.java + */ + +/** */ +public class ValueTest { + /* + * Tests for {@value} without a reference + */ + + /** valid: {@value} */ + public static final boolean cBoolean = false; + + /** valid: {@value} */ + public static final byte cByte = 0; + + /** valid: {@value} */ + public static final short cShort = 0; + + /** valid: {@value} */ + public static final int cInt = 0; + + /** valid: {@value} */ + public static final long cLong = 0L; + + /** valid: {@value} */ + public static final float cFloat = 0.0f; + + /** valid: {@value} */ + public static final double cDouble = 0.0; + + /** valid: {@value} */ + public static final String cString = ""; + + /** invalid class C: {@value} */ + public class C { } + + /** invalid enum E: {@value} */ + public enum E { + /** invalid enum constant E1: {@value} */ + E1 + } + + /** invalid field 1: {@value} */ + public int f1; + + /** invalid field 2: {@value} */ + public int f2 = 3; + + + /* + * Tests for {@value} with a reference + */ + + /** valid: {@value Integer#SIZE} */ + public int intRef; + + /** invalid method: {@value Object#toString} */ + public int badMethod; + + /** invalid enum constant: {@value Thread.State#NEW} */ + public int badEnum; +} diff --git a/langtools/test/tools/doclint/ValueTest.out b/langtools/test/tools/doclint/ValueTest.out new file mode 100644 index 00000000000..3b2977f9f72 --- /dev/null +++ b/langtools/test/tools/doclint/ValueTest.out @@ -0,0 +1,22 @@ +ValueTest.java:39: error: {@value} not allowed here + /** invalid class C: {@value} */ + ^ +ValueTest.java:42: error: {@value} not allowed here + /** invalid enum E: {@value} */ + ^ +ValueTest.java:44: error: {@value} not allowed here + /** invalid enum constant E1: {@value} */ + ^ +ValueTest.java:48: error: {@value} not allowed here + /** invalid field 1: {@value} */ + ^ +ValueTest.java:51: error: {@value} not allowed here + /** invalid field 2: {@value} */ + ^ +ValueTest.java:62: error: value does not refer to a constant + /** invalid method: {@value Object#toString} */ + ^ +ValueTest.java:65: error: value does not refer to a constant + /** invalid enum constant: {@value Thread.State#NEW} */ + ^ +7 errors From 48d1808d53cb8b4a4b841fc70081e4fcb2cb47c5 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 24 Sep 2013 13:48:12 -0700 Subject: [PATCH 178/293] 8002154: [doclint] doclint should check for issues which are errors in javadoc Reviewed-by: bpatel --- .../classes/com/sun/tools/doclint/Checker.java | 4 ++++ .../sun/tools/doclint/resources/doclint.properties | 1 + langtools/test/tools/doclint/ReferenceTest.java | 10 +++++++++- langtools/test/tools/doclint/ReferenceTest.out | 14 +++++++++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java index c8d331a43c0..bc4b86b0a09 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/Checker.java +++ b/langtools/src/share/classes/com/sun/tools/doclint/Checker.java @@ -730,6 +730,10 @@ public class Checker extends DocTreePathScanner { @Override public Void visitReference(ReferenceTree tree, Void ignore) { + String sig = tree.getSignature(); + if (sig.contains("<") || sig.contains(">")) + env.messages.error(REFERENCE, tree, "dc.type.arg.not.allowed"); + Element e = env.trees.getElement(getCurrentPath()); if (e == null) env.messages.error(REFERENCE, tree, "dc.ref.not.found"); diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties index 24c3aac76e6..b51af2a7358 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -67,6 +67,7 @@ dc.tag.self.closing = self-closing element not allowed dc.tag.start.unmatched = end tag missing: dc.tag.unknown = unknown tag: {0} dc.text.not.allowed = text not allowed in <{0}> element +dc.type.arg.not.allowed = type arguments not allowed here dc.unexpected.comment=documentation comment not expected here dc.value.not.allowed.here='{@value}' not allowed here dc.value.not.a.constant=value does not refer to a constant diff --git a/langtools/test/tools/doclint/ReferenceTest.java b/langtools/test/tools/doclint/ReferenceTest.java index 57b26aeff24..1ffd633e866 100644 --- a/langtools/test/tools/doclint/ReferenceTest.java +++ b/langtools/test/tools/doclint/ReferenceTest.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8004832 8020556 + * @bug 8004832 8020556 8002154 * @summary Add new doclint package * @build DocLintTester * @run main DocLintTester -Xmsgs:-reference ReferenceTest.java @@ -54,5 +54,13 @@ public class ReferenceTest { * @throws T description */ public void valid_throws_generic() throws T { } + + /** + * {@link java.util.List} + * {@link java.util.List#equals} + * @see java.util.List + * @see java.util.List#equals + */ + public void invalid_type_args() { } } diff --git a/langtools/test/tools/doclint/ReferenceTest.out b/langtools/test/tools/doclint/ReferenceTest.out index df21e5ef990..ab288a34b00 100644 --- a/langtools/test/tools/doclint/ReferenceTest.out +++ b/langtools/test/tools/doclint/ReferenceTest.out @@ -25,6 +25,18 @@ ReferenceTest.java:43: error: invalid use of @return ReferenceTest.java:48: error: exception not thrown: java.lang.Exception * @throws Exception description ^ -8 errors +ReferenceTest.java:59: error: type arguments not allowed here + * {@link java.util.List} + ^ +ReferenceTest.java:60: error: type arguments not allowed here + * {@link java.util.List#equals} + ^ +ReferenceTest.java:61: error: type arguments not allowed here + * @see java.util.List + ^ +ReferenceTest.java:62: error: type arguments not allowed here + * @see java.util.List#equals + ^ +12 errors 1 warning From c5bb090fff3b984b956bd42ed2663982db626400 Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Tue, 24 Sep 2013 14:17:42 -0700 Subject: [PATCH 179/293] 8025215: jdk8 l10n resource file translation update 4 Reviewed-by: naoto, yhuang --- .../apple/laf/resources/aqua_ko.properties | 2 +- .../resources/accessibility_de.properties | 2 +- .../resources/accessibility_es.properties | 2 +- .../resources/accessibility_fr.properties | 2 +- .../resources/accessibility_it.properties | 2 +- .../resources/accessibility_pt_BR.properties | 2 +- .../resources/accessibility_sv.properties | 2 +- .../plaf/motif/resources/motif_de.properties | 2 +- .../plaf/motif/resources/motif_ko.properties | 4 +- .../java/util/jar/pack/DriverResource_ja.java | 131 ++++++++++++++++++ .../util/jar/pack/DriverResource_zh_CN.java | 131 ++++++++++++++++++ .../rowset/RowSetResourceBundle_ko.properties | 6 +- .../plaf/basic/resources/basic_ko.properties | 4 +- .../plaf/metal/resources/metal_sv.properties | 4 +- .../applet/resources/MsgAppletViewer_de.java | 2 +- .../launcher/resources/launcher_de.properties | 4 +- .../launcher/resources/launcher_es.properties | 2 - .../launcher/resources/launcher_fr.properties | 4 +- .../launcher/resources/launcher_it.properties | 2 - .../launcher/resources/launcher_ja.properties | 8 +- .../launcher/resources/launcher_ko.properties | 7 +- .../resources/launcher_pt_BR.properties | 4 +- .../launcher/resources/launcher_sv.properties | 2 - .../resources/launcher_zh_CN.properties | 2 - .../resources/launcher_zh_TW.properties | 2 - .../print/resources/serviceui_de.properties | 18 +-- .../print/resources/serviceui_es.properties | 12 +- .../print/resources/serviceui_fr.properties | 16 +-- .../print/resources/serviceui_it.properties | 6 +- .../resources/serviceui_pt_BR.properties | 22 +-- .../print/resources/serviceui_sv.properties | 12 +- .../resources/rmiregistry_de.properties | 2 +- .../rmi/server/resources/rmid_ko.properties | 2 +- .../tools/jarsigner/Resources_ja.java | 40 +++--- .../tools/jarsigner/Resources_zh_CN.java | 8 +- .../security/tools/keytool/Resources_de.java | 20 +-- .../security/tools/keytool/Resources_es.java | 20 +-- .../security/tools/keytool/Resources_fr.java | 20 +-- .../security/tools/keytool/Resources_it.java | 18 ++- .../security/tools/keytool/Resources_ja.java | 16 ++- .../security/tools/keytool/Resources_ko.java | 18 ++- .../tools/keytool/Resources_pt_BR.java | 26 ++-- .../security/tools/keytool/Resources_sv.java | 22 +-- .../tools/keytool/Resources_zh_CN.java | 44 +++--- .../tools/keytool/Resources_zh_TW.java | 18 ++- .../tools/policytool/Resources_de.java | 5 +- .../tools/policytool/Resources_es.java | 3 + .../tools/policytool/Resources_fr.java | 3 + .../tools/policytool/Resources_it.java | 5 +- .../tools/policytool/Resources_ja.java | 3 + .../tools/policytool/Resources_ko.java | 3 + .../tools/policytool/Resources_pt_BR.java | 3 + .../tools/policytool/Resources_sv.java | 3 + .../tools/policytool/Resources_zh_CN.java | 21 +-- .../tools/policytool/Resources_zh_TW.java | 3 + .../sun/security/util/Resources_fr.java | 8 +- .../sun/tools/jar/resources/jar_de.properties | 5 +- .../sun/tools/jar/resources/jar_es.properties | 5 +- .../sun/tools/jar/resources/jar_fr.properties | 5 +- .../sun/tools/jar/resources/jar_it.properties | 5 +- .../sun/tools/jar/resources/jar_ja.properties | 5 +- .../sun/tools/jar/resources/jar_ko.properties | 7 +- .../tools/jar/resources/jar_pt_BR.properties | 9 +- .../sun/tools/jar/resources/jar_sv.properties | 3 +- .../tools/jar/resources/jar_zh_CN.properties | 3 +- .../tools/jar/resources/jar_zh_TW.properties | 5 +- .../jconsole/resources/messages_ja.properties | 17 ++- .../resources/messages_zh_CN.properties | 17 ++- 68 files changed, 583 insertions(+), 258 deletions(-) create mode 100644 jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java create mode 100644 jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java diff --git a/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties b/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties index 3fbfbe7e76e..82c4ce2f2dc 100644 --- a/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties +++ b/jdk/src/macosx/classes/com/apple/laf/resources/aqua_ko.properties @@ -46,7 +46,7 @@ FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5 FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30 FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30 -FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0 +FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0 FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties index fe0f918d9bf..45148664672 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_de.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=ein-/ausblenden +toggleexpand=einblenden umschalten # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties index c3f90416a30..ce185a10dd1 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_es.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=activar/desactivar ampliaci\u00F3n +toggleexpand=conmutar ampliaci\u00F3n # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties index c399d9a0b32..88e8ae304b4 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_fr.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=basculer le d\u00E9veloppement +toggleexpand=activer/d\u00E9sactiver d\u00E9veloppement # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties index 94eefb0a2a3..a8af9705d19 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_it.properties @@ -102,7 +102,7 @@ horizontal=orizzontale # # accessible actions # -toggleexpand=abilita/disabilita espansione +toggleexpand=attiva/disattiva espansione # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties index f8aaf355040..638b46a7219 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_pt_BR.properties @@ -102,7 +102,7 @@ horizontal=horizontal # # accessible actions # -toggleexpand=alternar expans\u00E3o +toggleexpand=alternar expandir # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties index 962b9d35dc5..3261b2c9be3 100644 --- a/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties +++ b/jdk/src/share/classes/com/sun/accessibility/internal/resources/accessibility_sv.properties @@ -102,7 +102,7 @@ horizontal=horisontell # # accessible actions # -toggleexpand=v\u00E4xla ut\u00F6ka +toggleexpand=v\u00E4xla expandering # new relations, roles and states for J2SE 1.5.0 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties index 43ba5b6d32b..0c177f8b122 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties @@ -30,7 +30,7 @@ FileChooser.pathLabel.textAndMnemonic=&Pfad- oder Ordnername eingeben: FileChooser.filterLabel.textAndMnemonic=Filte&r FileChooser.foldersLabel.textAndMnemonic=Ord&ner FileChooser.filesLabel.textAndMnemonic=Date&ien -FileChooser.enterFileNameLabel.textAndMnemonic=Dateiname ei&ngeben: +FileChooser.enterFileNameLabel.textAndMnemonic=Dateina&me eingeben: FileChooser.enterFolderNameLabel.textAndMnemonic=Ordnernamen eingeben: FileChooser.cancelButtonToolTip.textAndMnemonic=Dialogfeld f\u00FCr Dateiauswahl schlie\u00DFen. diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties index f7e2625e9c9..7090ef5a7c4 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties @@ -24,7 +24,7 @@ FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5 FileChooser.openButton.textAndMnemonic=\uD655\uC778 FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30 -FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0 +FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0 FileChooser.pathLabel.textAndMnemonic=\uACBD\uB85C \uB610\uB294 \uD3F4\uB354 \uC774\uB984 \uC785\uB825(&P): FileChooser.filterLabel.textAndMnemonic=\uD544\uD130(&R) @@ -36,5 +36,5 @@ FileChooser.enterFolderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984 \uC78 FileChooser.cancelButtonToolTip.textAndMnemonic=\uD30C\uC77C \uC120\uD0DD\uAE30 \uB300\uD654\uC0C1\uC790\uB97C \uC911\uB2E8\uD569\uB2C8\uB2E4. FileChooser.saveButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4. FileChooser.openButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C\uC744 \uC5FD\uB2C8\uB2E4. -FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC744 \uAC31\uC2E0\uD569\uB2C8\uB2E4. +FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D\uC744 \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4. FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser \uB3C4\uC6C0\uB9D0\uC785\uB2C8\uB2E4. diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java new file mode 100644 index 00000000000..de35d5ac0eb --- /dev/null +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.util.jar.pack; + +import java.util.ListResourceBundle; + +public class DriverResource_ja extends ListResourceBundle { + public static final String VERSION ="VERSION"; + public static final String BAD_ARGUMENT ="BAD_ARGUMENT"; + public static final String BAD_OPTION ="BAD_OPTION"; + public static final String BAD_REPACK_OUTPUT="BAD_REPACK_OUTPUT"; + public static final String DETECTED_ZIP_COMMENT="DETECTED_ZIP_COMMENT"; + public static final String SKIP_FOR_REPACKED ="SKIP_FOR_REPACKED"; + public static final String WRITE_PACK_FILE ="WRITE_PACK_FILE"; + public static final String WIRTE_PACKGZ_FILE="WIRTE_PACKGZ_FILE"; + public static final String SKIP_FOR_MOVE_FAILED="SKIP_FOR_MOVE_FAILED"; + public static final String PACK_HELP="PACK_HELP"; + public static final String UNPACK_HELP ="UNPACK_HELP"; + public static final String MORE_INFO = "MORE_INFO"; + public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; + public static final String BAD_SPEC = "BAD_SPEC"; + + //The following string is duplicate in PACK and UNPACK comment,which was draw out to ruduce translation work. + private static final String PARAMETER_V = " -v, --verbose increase program verbosity"; + private static final String PARAMETER_Q = " -q, --quiet set verbosity to lowest level"; + private static final String PARAMETER_LF = " -l{F}, --log-file={F} output to the given log file, or '-' for System.out"; + private static final String PARAMETER_H = " -?, -h, --help print this message"; + private static final String PARAMETER_VER = " -V, --version print program version"; + private static final String PARAMETER_J = " -J{X} pass option X to underlying Java VM"; + + + //The following are outputs of command 'pack200' and 'unpack200'. + //Don't translate command arguments ,words with a prefix of '-' or '--'. + // + private static final Object[][] resource= { + {VERSION,"{0}\u30D0\u30FC\u30B8\u30E7\u30F3{1}"},//parameter 0:class name;parameter 1: version value + {BAD_ARGUMENT,"\u7121\u52B9\u306A\u5F15\u6570: {0}"}, + {BAD_OPTION,"\u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}={1}"},//parameter 0:option name;parameter 1:option value + {BAD_REPACK_OUTPUT,"\u7121\u52B9\u306A--repack\u51FA\u529B: {0}"},//parameter 0:filename + {DETECTED_ZIP_COMMENT,"\u691C\u51FA\u3055\u308C\u305FZIP\u30B3\u30E1\u30F3\u30C8: {0}"},//parameter 0:comment + {SKIP_FOR_REPACKED,"\u3059\u3067\u306B\u518D\u5727\u7E2E\u3055\u308C\u3066\u3044\u308B\u305F\u3081\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059: {0}"},//parameter 0:filename + {WRITE_PACK_FILE,"*.pack\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\u306B\u306F\u3001--no-gzip\u3092\u6307\u5B9A\u3057\u307E\u3059: {0}"},//parameter 0:filename + {WIRTE_PACKGZ_FILE,"*.pack.gz\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\u306B\u306F\u3001--gzip\u3092\u6307\u5B9A\u3057\u307E\u3059: {0}"},//parameter 0:filename + {SKIP_FOR_MOVE_FAILED,"\u79FB\u52D5\u304C\u5931\u6557\u3057\u305F\u305F\u3081\u89E3\u51CD\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u3044\u307E\u3059: {0}"},//parameter 0:filename + {PACK_HELP,new String[]{ + "\u4F7F\u7528\u65B9\u6CD5: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", + "", + "\u5727\u7E2E\u30AA\u30D7\u30B7\u30E7\u30F3", + " -g\u3001--no-gzip \u30D7\u30EC\u30FC\u30F3\u306A*.pack\u30D5\u30A1\u30A4\u30EB\u3092\u5727\u7E2E\u305B\u305A\u306B\u51FA\u529B\u3057\u307E\u3059", + " --gzip (\u30C7\u30D5\u30A9\u30EB\u30C8)\u5727\u7E2E\u51FA\u529B\u3092gzip\u3067\u5F8C\u51E6\u7406\u3057\u307E\u3059", + " -G\u3001--strip-debug \u5727\u7E2E\u4E2D\u306B\u30C7\u30D0\u30C3\u30B0\u5C5E\u6027\u3092\u524A\u9664\u3057\u307E\u3059", + " -O\u3001--no-keep-file-order \u30D5\u30A1\u30A4\u30EB\u306E\u9806\u5E8F\u4ED8\u3051\u60C5\u5831\u3092\u8EE2\u9001\u3057\u307E\u305B\u3093", + " --keep-file-order (\u30C7\u30D5\u30A9\u30EB\u30C8)\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u9806\u5E8F\u4ED8\u3051\u3092\u4FDD\u6301\u3057\u307E\u3059", + " -S{N}\u3001--segment-limit={N} \u30BB\u30B0\u30E1\u30F3\u30C8\u5236\u9650\u3092\u51FA\u529B\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8N=1Mb)", + " -E{N}\u3001--effort={N} \u5727\u7E2E\u306E\u8A66\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8N=5)", + " -H{h}\u3001--deflate-hint={h} \u30C7\u30D5\u30EC\u30FC\u30C8\u30FB\u30D2\u30F3\u30C8\u3092\u8EE2\u9001\u3057\u307E\u3059: true\u3001false\u307E\u305F\u306Fkeep(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -m{V}\u3001--modification-time={V} \u5909\u66F4\u6642\u9593\u3092\u8EE2\u9001\u3057\u307E\u3059: latest\u307E\u305F\u306Fkeep(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -P{F}\u3001--pass-file={F} \u6307\u5B9A\u3055\u308C\u305F\u5727\u7E2E\u3055\u308C\u3066\u3044\u306A\u3044\u5165\u529B\u8981\u7D20\u3092\u8EE2\u9001\u3057\u307E\u3059", + " -U{a}\u3001--unknown-attribute={a} \u4E0D\u660E\u306E\u5C5E\u6027\u30A2\u30AF\u30B7\u30E7\u30F3: error\u3001strip\u307E\u305F\u306Fpass(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -C{N}={L}\u3001--class-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -F{N}={L}\u3001--field-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -M{N}={L}\u3001--method-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -D{N}={L}\u3001--code-attribute={N}={L} (\u30E6\u30FC\u30B6\u30FC\u5B9A\u7FA9\u5C5E\u6027)", + " -f{F}\u3001--config-file={F} Pack200.Packer\u30D7\u30ED\u30D1\u30C6\u30A3\u306B\u30D5\u30A1\u30A4\u30EBF\u3092\u8AAD\u307F\u8FBC\u307F\u307E\u3059", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + "", + "\u6CE8\u610F:", + " -P\u3001-C\u3001-F\u3001-M\u304A\u3088\u3073-D\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u7D2F\u7A4D\u3055\u308C\u307E\u3059\u3002", + " \u5C5E\u6027\u5B9A\u7FA9\u306E\u4F8B: -C SourceFile=RUH .", + " Config.\u30D5\u30A1\u30A4\u30EB\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u306F\u3001Pack200 API\u306B\u3088\u3063\u3066\u5B9A\u7FA9\u3055\u308C\u307E\u3059\u3002", + " -S\u3001-E\u3001-H\u3001-m\u3001-U\u306E\u5024\u306E\u610F\u5473\u306F\u3001Pack200 API\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002", + " \u30EC\u30A4\u30A2\u30A6\u30C8\u5B9A\u7FA9(RUH\u306A\u3069)\u306FJSR 200\u306B\u3088\u3063\u3066\u5B9A\u7FA9\u3055\u308C\u307E\u3059\u3002", + "", + "\u518D\u5727\u7E2E\u30E2\u30FC\u30C9\u3067\u306F\u3001JAR\u30D5\u30A1\u30A4\u30EB\u304C\u5727\u7E2E/\u89E3\u51CD\u30B5\u30A4\u30AF\u30EB\u3067\u66F4\u65B0\u3055\u308C\u307E\u3059:", + " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" + } + }, + {UNPACK_HELP,new String[]{ + "\u4F7F\u7528\u65B9\u6CD5: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", + "", + "\u89E3\u51CD\u30AA\u30D7\u30B7\u30E7\u30F3", + " -H{h}\u3001--deflate-hint={h} \u8EE2\u9001\u3055\u308C\u305F\u30C7\u30D5\u30EC\u30FC\u30C8\u30FB\u30D2\u30F3\u30C8\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u3059: true\u3001false\u307E\u305F\u306Fkeep(\u30C7\u30D5\u30A9\u30EB\u30C8)", + " -r\u3001--remove-pack-file \u89E3\u51CD\u5F8C\u306B\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664\u3057\u307E\u3059", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + } + }, + + {MORE_INFO,"(\u8A73\u7D30\u306F\u3001{0} --help\u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002)"},//parameter 0:command name + {DUPLICATE_OPTION,"\u91CD\u8907\u30AA\u30D7\u30B7\u30E7\u30F3: {0}"},//parameter 0:option + {BAD_SPEC,"{0}\u306E\u7121\u52B9\u306A\u4ED5\u69D8: {1}"},//parameter 0:option;parameter 1:specifier + }; + + protected Object[][] getContents() { + return resource; + } + + +} diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java new file mode 100644 index 00000000000..25cc710e61f --- /dev/null +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_zh_CN.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java.util.jar.pack; + +import java.util.ListResourceBundle; + +public class DriverResource_zh_CN extends ListResourceBundle { + public static final String VERSION ="VERSION"; + public static final String BAD_ARGUMENT ="BAD_ARGUMENT"; + public static final String BAD_OPTION ="BAD_OPTION"; + public static final String BAD_REPACK_OUTPUT="BAD_REPACK_OUTPUT"; + public static final String DETECTED_ZIP_COMMENT="DETECTED_ZIP_COMMENT"; + public static final String SKIP_FOR_REPACKED ="SKIP_FOR_REPACKED"; + public static final String WRITE_PACK_FILE ="WRITE_PACK_FILE"; + public static final String WIRTE_PACKGZ_FILE="WIRTE_PACKGZ_FILE"; + public static final String SKIP_FOR_MOVE_FAILED="SKIP_FOR_MOVE_FAILED"; + public static final String PACK_HELP="PACK_HELP"; + public static final String UNPACK_HELP ="UNPACK_HELP"; + public static final String MORE_INFO = "MORE_INFO"; + public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; + public static final String BAD_SPEC = "BAD_SPEC"; + + //The following string is duplicate in PACK and UNPACK comment,which was draw out to ruduce translation work. + private static final String PARAMETER_V = " -v, --verbose increase program verbosity"; + private static final String PARAMETER_Q = " -q, --quiet set verbosity to lowest level"; + private static final String PARAMETER_LF = " -l{F}, --log-file={F} output to the given log file, or '-' for System.out"; + private static final String PARAMETER_H = " -?, -h, --help print this message"; + private static final String PARAMETER_VER = " -V, --version print program version"; + private static final String PARAMETER_J = " -J{X} pass option X to underlying Java VM"; + + + //The following are outputs of command 'pack200' and 'unpack200'. + //Don't translate command arguments ,words with a prefix of '-' or '--'. + // + private static final Object[][] resource= { + {VERSION,"{0}\u7248\u672C{1}"},//parameter 0:class name;parameter 1: version value + {BAD_ARGUMENT,"\u9519\u8BEF\u53C2\u6570: {0}"}, + {BAD_OPTION,"\u9519\u8BEF\u9009\u9879: {0}={1}"},//parameter 0:option name;parameter 1:option value + {BAD_REPACK_OUTPUT,"--repack \u8F93\u51FA\u9519\u8BEF: {0}"},//parameter 0:filename + {DETECTED_ZIP_COMMENT,"\u68C0\u6D4B\u5230 ZIP \u6CE8\u91CA: {0}"},//parameter 0:comment + {SKIP_FOR_REPACKED,"\u7531\u4E8E\u5DF2\u91CD\u65B0\u6253\u5305\u800C\u8DF3\u8FC7: {0}"},//parameter 0:filename + {WRITE_PACK_FILE,"\u8981\u5199\u5165 *.pack \u6587\u4EF6, \u8BF7\u6307\u5B9A --no-gzip: {0}"},//parameter 0:filename + {WIRTE_PACKGZ_FILE,"\u8981\u5199\u5165 *.pack.gz \u6587\u4EF6, \u8BF7\u6307\u5B9A --gzip: {0}"},//parameter 0:filename + {SKIP_FOR_MOVE_FAILED,"\u7531\u4E8E\u79FB\u52A8\u5931\u8D25\u800C\u8DF3\u8FC7\u91CD\u65B0\u6253\u5305: {0}"},//parameter 0:filename + {PACK_HELP,new String[]{ + "\u7528\u6CD5: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", + "", + "\u6253\u5305\u9009\u9879", + " -g, --no-gzip \u8F93\u51FA\u65E0\u683C\u5F0F\u7684 *.pack \u6587\u4EF6, \u4E0D\u538B\u7F29", + " --gzip (\u9ED8\u8BA4\u503C) \u4F7F\u7528 gzip \u5BF9\u6253\u5305\u8FDB\u884C\u540E\u5904\u7406", + " -G, --strip-debug \u6253\u5305\u65F6\u5220\u9664\u8C03\u8BD5\u5C5E\u6027", + " -O, --no-keep-file-order \u4E0D\u4F20\u8F93\u6587\u4EF6\u6392\u5E8F\u4FE1\u606F", + " --keep-file-order (\u9ED8\u8BA4\u503C) \u4FDD\u7559\u8F93\u5165\u6587\u4EF6\u6392\u5E8F", + " -S{N}, --segment-limit={N} \u8F93\u51FA\u6BB5\u9650\u5236 (\u9ED8\u8BA4\u503C N=1Mb)", + " -E{N}, --effort={N} \u6253\u5305\u6548\u679C (\u9ED8\u8BA4\u503C N=5)", + " -H{h}, --deflate-hint={h} \u4F20\u8F93\u538B\u7F29\u63D0\u793A: true, false \u6216 keep (\u9ED8\u8BA4\u503C)", + " -m{V}, --modification-time={V} \u4F20\u8F93 modtimes: latest \u6216 keep (\u9ED8\u8BA4\u503C)", + " -P{F}, --pass-file={F} \u4F20\u8F93\u672A\u89E3\u538B\u7F29\u7684\u7ED9\u5B9A\u8F93\u5165\u5143\u7D20", + " -U{a}, --unknown-attribute={a} \u672A\u77E5\u5C5E\u6027\u64CD\u4F5C: error, strip \u6216 pass (\u9ED8\u8BA4\u503C)", + " -C{N}={L}, --class-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -F{N}={L}, --field-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -M{N}={L}, --method-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -D{N}={L}, --code-attribute={N}={L} (\u7528\u6237\u5B9A\u4E49\u7684\u5C5E\u6027)", + " -f{F}, --config-file={F} \u8BFB\u53D6\u6587\u4EF6 F \u7684 Pack200.Packer \u5C5E\u6027", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + "", + "\u6CE8:", + " -P, -C, -F, -M \u548C -D \u9009\u9879\u7D2F\u8BA1\u3002", + " \u793A\u4F8B\u5C5E\u6027\u5B9A\u4E49: -C SourceFile=RUH\u3002", + " Config. \u6587\u4EF6\u5C5E\u6027\u7531 Pack200 API \u5B9A\u4E49\u3002", + " \u6709\u5173 -S, -E, -H-, -m, -U \u503C\u7684\u542B\u4E49, \u8BF7\u53C2\u9605 Pack200 API\u3002", + " \u5E03\u5C40\u5B9A\u4E49 (\u4F8B\u5982 RUH) \u7531 JSR 200 \u5B9A\u4E49\u3002", + "", + "\u91CD\u65B0\u6253\u5305\u6A21\u5F0F\u901A\u8FC7\u6253\u5305/\u89E3\u5305\u5468\u671F\u66F4\u65B0 JAR \u6587\u4EF6:", + " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" + } + }, + {UNPACK_HELP,new String[]{ + "\u7528\u6CD5: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", + "", + "\u89E3\u5305\u9009\u9879", + " -H{h}, --deflate-hint={h} \u8986\u76D6\u5DF2\u4F20\u8F93\u7684\u538B\u7F29\u63D0\u793A: true, false \u6216 keep (\u9ED8\u8BA4\u503C)", + " -r, --remove-pack-file \u89E3\u5305\u4E4B\u540E\u5220\u9664\u8F93\u5165\u6587\u4EF6", + PARAMETER_V , + PARAMETER_Q , + PARAMETER_LF , + PARAMETER_H , + PARAMETER_VER , + PARAMETER_J, + } + }, + + {MORE_INFO,"(\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u8FD0\u884C {0} --help\u3002)"},//parameter 0:command name + {DUPLICATE_OPTION,"\u91CD\u590D\u7684\u9009\u9879: {0}"},//parameter 0:option + {BAD_SPEC,"{0}\u7684\u89C4\u8303\u9519\u8BEF: {1}"},//parameter 0:option;parameter 1:specifier + }; + + protected Object[][] getContents() { + return resource; + } + + +} diff --git a/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties b/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties index 3dd9ee0d1b9..89bbf67ec53 100644 --- a/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties +++ b/jdk/src/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties @@ -44,7 +44,7 @@ cachedrowsetimpl.doublefail = {1} \uC5F4\uC758 \uAC12({0})\uC5D0\uC11C getDouble cachedrowsetimpl.dtypemismt = \uB370\uC774\uD130 \uC720\uD615\uC774 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.datefail = {1} \uC5F4\uC758 \uAC12({0})\uC5D0\uC11C getDate\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uBCC0\uD658\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.timefail = {1} \uC5F4\uC758 \uAC12({0})\uC5D0\uC11C getTime\uC744 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uBCC0\uD658\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. -cachedrowsetimpl.posupdate = \uC704\uCE58\uAC00 \uC9C0\uC815\uB41C \uAC31\uC2E0\uC774 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. +cachedrowsetimpl.posupdate = \uC704\uCE58\uAC00 \uC9C0\uC815\uB41C \uC5C5\uB370\uC774\uD2B8\uAC00 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.unableins = \uC778\uC2A4\uD134\uC2A4\uD654\uD560 \uC218 \uC5C6\uC74C: {0} cachedrowsetimpl.beforefirst = beforeFirst: \uCEE4\uC11C \uC791\uC5C5\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. cachedrowsetimpl.first = \uCC98\uC74C: \uCEE4\uC11C \uC791\uC5C5\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. @@ -110,7 +110,7 @@ jdbcrowsetimpl.matchcols2 = \uC77C\uCE58 \uC5F4\uC740 \uB110 \uB610\uB294 \uBE48 jdbcrowsetimpl.unsetmatch = \uC124\uC815\uC744 \uD574\uC81C\uD558\uB824\uB294 \uC5F4\uC774 \uC124\uC815\uB41C \uC5F4\uACFC \uB2E4\uB985\uB2C8\uB2E4. jdbcrowsetimpl.usecolname = \uC5F4 \uC774\uB984\uC744 unsetMatchColumn\uC758 \uC778\uC218\uB85C \uC0AC\uC6A9\uD558\uC2ED\uC2DC\uC624. jdbcrowsetimpl.usecolid = \uC5F4 ID\uB97C unsetMatchColumn\uC758 \uC778\uC218\uB85C \uC0AC\uC6A9\uD558\uC2ED\uC2DC\uC624. -jdbcrowsetimpl.resnotupd = ResultSet\uB97C \uAC31\uC2E0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. +jdbcrowsetimpl.resnotupd = ResultSet\uB97C \uC5C5\uB370\uC774\uD2B8\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. jdbcrowsetimpl.opnotysupp = \uC791\uC5C5\uC774 \uC544\uC9C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. jdbcrowsetimpl.featnotsupp = \uAE30\uB2A5\uC774 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. @@ -157,7 +157,7 @@ xmlrch.errdel = \uD589\uC744 \uC0AD\uC81C\uD558\uB294 \uC911 \uC624\uB958 \uBC1C xmlrch.errinsert = insert \uD589\uC744 \uC0DD\uC131\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} xmlrch.errinsdel = insdel \uD589\uC744 \uC0DD\uC131\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} xmlrch.errupdate = update \uD589\uC744 \uC0DD\uC131\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} -xmlrch.errupdrow = \uD589\uC744 \uAC31\uC2E0\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} +xmlrch.errupdrow = \uD589\uC744 \uC5C5\uB370\uC774\uD2B8\uD558\uB294 \uC911 \uC624\uB958 \uBC1C\uC0DD: {0} xmlrch.chars = \uBB38\uC790: xmlrch.badvalue = \uC798\uBABB\uB41C \uAC12: \uB110\uC77C \uC218 \uC5C6\uB294 \uC18D\uC131\uC785\uB2C8\uB2E4. xmlrch.badvalue1 = \uC798\uBABB\uB41C \uAC12: \uB110\uC77C \uC218 \uC5C6\uB294 \uBA54\uD0C0 \uB370\uC774\uD130\uC785\uB2C8\uB2E4. diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties index 86f010204dc..a8504f7872c 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties @@ -46,7 +46,7 @@ FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5(&S) FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30(&O) FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30 -FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0(&U) +FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8(&U) FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0(&H) FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30(&O) @@ -66,7 +66,7 @@ FileChooser.other.newFolder.subsequent=NewFolder.{0} FileChooser.cancelButtonToolTip.textAndMnemonic=\uD30C\uC77C \uC120\uD0DD\uAE30 \uB300\uD654\uC0C1\uC790 \uC911\uB2E8 FileChooser.saveButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C \uC800\uC7A5 FileChooser.openButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uD30C\uC77C \uC5F4\uAE30 -FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D \uAC31\uC2E0 +FileChooser.updateButtonToolTip.textAndMnemonic=\uB514\uB809\uD1A0\uB9AC \uBAA9\uB85D \uC5C5\uB370\uC774\uD2B8 FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser \uB3C4\uC6C0\uB9D0 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uB514\uB809\uD1A0\uB9AC \uC5F4\uAE30 diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties index 3d799b58a80..1b9b7e217c7 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties @@ -20,8 +20,8 @@ FileChooser.lookInLabel.textAndMnemonic=Leta &i: FileChooser.saveInLabel.textAndMnemonic=Spara i: -FileChooser.fileNameLabel.textAndMnemonic=Fil&namn: -FileChooser.folderNameLabel.textAndMnemonic=Mapp&namn: +FileChooser.fileNameLabel.textAndMnemonic=&Fil: +FileChooser.folderNameLabel.textAndMnemonic=&Mapp: FileChooser.filesOfTypeLabel.textAndMnemonic=Mapp&namn: FileChooser.upFolderToolTip.textAndMnemonic=Upp en niv\u00E5 FileChooser.upFolderAccessibleName=Upp diff --git a/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java b/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java index 7163bb5b1a1..b99d3bbd75d 100644 --- a/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java +++ b/jdk/src/share/classes/sun/applet/resources/MsgAppletViewer_de.java @@ -73,7 +73,7 @@ public class MsgAppletViewer_de extends ListResourceBundle { {"appletviewer.parse.warning.embed.requiresheight", "Warnung: F\u00FCr -Tag ist ein \"height\"-Attribut erforderlich."}, {"appletviewer.parse.warning.embed.requireswidth", "Warnung: F\u00FCr -Tag ist ein \"width\"-Attribut erforderlich."}, {"appletviewer.parse.warning.appnotLongersupported", "Warnung: -Tag wird nicht mehr unterst\u00FCtzt. Verwenden Sie stattdessen :"}, - {"appletviewer.usage", "Verwendung: appletviewer url(s)\n\nwobei die Folgendes umfassen:\n -debug Applet Viewer im Java-Debugger starten\n -encoding Zeichencodierung f\u00FCr HTML-Dateien angeben\n -J Argument an den Java-Interpreter \u00FCbergeben\n\nDie Option \"-J\" ist nicht standardm\u00E4\u00DFig und kann ohne vorherige Ank\u00FCndigung ge\u00E4ndert werden."}, + {"appletviewer.usage", "Verwendung: appletviewer url(s)\n\nwobei die Folgendes umfassen:\n -debug Applet Viewer im Java-Debugger starten\n -encoding Zeichencodierung f\u00FCr HTML-Dateien angeben\n -J Argument an den Java-Interpreter \u00FCbergeben\n\nDie Option \"-J\" ist nicht standardm\u00E4\u00DFig und kann ohne vorherige Ank\u00FCndigung ge\u00E4ndert werden."}, {"appletviewer.main.err.unsupportedopt", "Nicht unterst\u00FCtzte Option: {0}"}, {"appletviewer.main.err.unrecognizedarg", "Unbekanntes Argument: {0}"}, {"appletviewer.main.err.dupoption", "Doppelte Verwendung von Option: {0}"}, diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties index 4d5ef284277..9720e4626bc 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_de.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ Die Standard-VM ist {0} java.launcher.ergo.message2 =\ weil die Ausf\u00FChrung auf einem Server-Class-Rechner erfolgt.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n und ZIP-Archiven zur Suche nach Klassendateien.\n -D=\n Legt eine Systemeigenschaft fest\n -verbose[:class|gc|jni]\n Aktiviert die Verbose-Ausgabe\n -version Druckt Produktversion und beendet das Programm\n -version:\n Erfordert die angegebene Version zur Ausf\u00FChrung\n -showversion Druckt Produktversion und f\u00E4hrt fort\n -jre-restrict-search | -no-jre-restrict-search\n Bezieht private JREs des Benutzers in Versionssuche ein bzw. schlie\u00DFt sie aus\n -? -help Druckt diese Hilfemeldung\n -X Druckt Hilfe zu Nicht-Standardoptionen\n -ea[:...|:]\n -enableassertions[:...|:]\n Aktiviert Assertionen mit angegebener Granularit\u00E4t\n -da[:...|:]\n -disableassertions[:...|:]\n Deaktiviert Assertionen mit angegebener Granularit\u00E4t\n -esa | -enablesystemassertions\n Aktiviert Systemassertionen\n -dsa | -disablesystemassertions\n Deaktiviert Systemassertionen\n -agentlib:[=]\n L\u00E4dt native Agent Library , z.B. -agentlib:hprof\n siehe auch -agentlib:jdwp=help und -agentlib:hprof=help\n -agentpath:[=]\n L\u00E4dt native Agent Library nach vollem Pfadnamen\n -javaagent:[=]\n L\u00E4dt Java-Programmiersprachen-Agent, siehe java.lang.instrument\n -splash:\n Zeigt Startbildschirm mit angegebenem Bild\nWeitere Einzelheiten finden Sie unter http://www.oracle.com/technetwork/java/javase/documentation/index.html +java.launcher.opt.footer =\ -cp \n -classpath \n Eine durch {0} getrennte Liste mit Verzeichnissen, JAR-Archiven\n und ZIP-Archiven zur Suche nach Klassendateien.\n -D=\n Legt eine Systemeigenschaft fest\n -verbose:[class|gc|jni]\n Aktiviert die Verbose-Ausgabe\n -version Druckt Produktversion und beendet das Programm\n -version:\n Erfordert die angegebene Version zur Ausf\u00FChrung\n -showversion Druckt Produktversion und f\u00E4hrt fort\n -jre-restrict-search | -no-jre-restrict-search\n Bezieht private JREs des Benutzers in Versionssuche ein bzw. schlie\u00DFt sie aus\n -? -help Druckt diese Hilfemeldung\n -X Druckt Hilfe zu Nicht-Standardoptionen\n -ea[:...|:]\n -enableassertions[:...|:]\n Aktiviert Assertionen mit angegebener Granularit\u00E4t\n -da[:...|:]\n -disableassertions[:...|:]\n Deaktiviert Assertionen mit angegebener Granularit\u00E4t\n -esa | -enablesystemassertions\n Aktiviert Systemassertionen\n -dsa | -disablesystemassertions\n Deaktiviert Systemassertionen\n -agentlib:[=]\n L\u00E4dt native Agent Library , z.B. -agentlib:hprof\n siehe auch -agentlib:jdwp=help und -agentlib:hprof=help\n -agentpath:[=]\n L\u00E4dt native Agent Library nach vollem Pfadnamen\n -javaagent:[=]\n L\u00E4dt Java-Programmiersprachen-Agent, siehe java.lang.instrument\n -splash:\n Zeigt Startbildschirm mit angegebenem Bild\nWeitere Einzelheiten finden Sie unter http://www.oracle.com/technetwork/java/javase/documentation/index.html # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed Ausf\u00FChrung im gemischten Modus (Standard)\n -Xint Nur Ausf\u00FChrung im interpretierten Modus\n -Xbootclasspath:\n Legt Suchpfad f\u00FCr Bootstrap-Klassen und Ressourcen fest\n -Xbootclasspath/a:\n H\u00E4ngt an das Ende des Bootstrap Classpath an\n -Xbootclasspath/p:\n Stellt Bootstrap Classpath voran\n -Xdiag Zeigt zus\u00E4tzliche Diagnosemeldungen an\n -Xnoclassgc Deaktiviert Klassen-Garbage Collection\n -Xincgc Aktiviert inkrementelle Garbage Collection\n -Xloggc: Loggt GC-Status in einer Datei mit Zeitstempeln\n -Xbatch Deaktiviert Hintergrundkompilierung\n -Xms Legt anf\u00E4ngliche Java Heap-Gr\u00F6\u00DFe fest\n -Xmx Legt maximale Java Heap-Gr\u00F6\u00DFe fest\n -Xss Legt Java-Thread-Stackgr\u00F6\u00DFe fest\n -Xprof Gibt CPU-Profiling-Daten aus\n -Xfuture Aktiviert strengste Pr\u00FCfungen, antizipiert zuk\u00FCnftigen Standardwert\n -Xrs Reduziert Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n -Xcheck:jni F\u00FChrt zus\u00E4tzliche Pr\u00FCfungen f\u00FCr JNI-Funktionen durch\n -Xshare:off Kein Versuch, gemeinsame Klassendaten zu verwenden\n -Xshare:auto Verwendet gemeinsame Klassendaten, wenn m\u00F6glich (Standard)\n -Xshare:on Erfordert die Verwendung gemeinsamer Klassendaten, sonst verl\u00E4uft der Vorgang nicht erfolgreich.\n -XshowSettings Zeigt alle Einstellungen und f\u00E4hrt fort\n -XshowSettings:all\n Zeigt alle Einstellungen und f\u00E4hrt fort\n -XshowSettings:vm Zeigt alle VM-bezogenen Einstellungen und f\u00E4hrt fort\n -XshowSettings:properties\n Zeigt alle Eigenschaftseinstellungen und f\u00E4hrt fort\n -XshowSettings:locale\n Zeigt alle gebietsschemabezogenen Einstellungen und f\u00E4hrt fort\n\nDie -X-Optionen sind keine Standardoptionen und k\u00F6nnen ohne Vorank\u00FCndigung ge\u00E4ndert werden.\n @@ -50,7 +50,5 @@ java.launcher.cls.error5=Fehler: Zum Ausf\u00FChren dieser Anwendung ben\u00F6ti java.launcher.jar.error1=Fehler: Beim Versuch, Datei {0} zu \u00F6ffnen, ist ein unerwarteter Fehler aufgetreten java.launcher.jar.error2=Manifest in {0} nicht gefunden java.launcher.jar.error3=kein Hauptmanifestattribut, in {0} -java.launcher.jar.error4=kein Profilmanifestattribut in {0} -java.launcher.jar.error5=Das f\u00FCr {1} erforderliche Profil {0} wird von dieser Runtime-Anwendung nicht unterst\u00FCtzt java.launcher.init.error=Initialisierungsfehler java.launcher.javafx.error1=Fehler: Die JavaFX-Methode launchApplication hat die falsche Signatur, sie\nmuss als statisch deklariert werden und einen Wert vom Typ VOID zur\u00FCckgeben diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties index 1aefa5f0194..b2bdab3f63d 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_es.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=Error: faltan los componentes de JavaFX runtime y son n java.launcher.jar.error1=Error: se ha producido un error inesperado al intentar abrir el archivo {0} java.launcher.jar.error2=no se ha encontrado el manifiesto en {0} java.launcher.jar.error3=no hay ning\u00FAn atributo de manifiesto principal en {0} -java.launcher.jar.error4=no hay ning\u00FAn atributo de manifiesto de perfil en {0} -java.launcher.jar.error5=El perfil {0} que necesita {1} no est\u00E1 soportado por este tiempo de ejecuci\u00F3n java.launcher.init.error=error de inicializaci\u00F3n java.launcher.javafx.error1=Error: el m\u00E9todo launchApplication de JavaFX tiene una firma que no es correcta.\\nSe debe declarar est\u00E1tico y devolver un valor de tipo nulo diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties index 6e5d9891828..11f64e009fa 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_fr.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ La machine virtuelle par d\u00E java.launcher.ergo.message2 =\ car vous ex\u00E9cutez une machine de classe de serveur.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n Liste de r\u00E9pertoires, d''archives JAR et\n d''archives ZIP s\u00E9par\u00E9s par des {0}, dans laquelle rechercher les fichiers de classe.\n -D=\n d\u00E9finition d''une propri\u00E9t\u00E9 syst\u00E8me\n -verbose[:class|gc|jni]\n activation de la sortie en mode verbose\n -version impression de la version du produit et fin de l''op\u00E9ration\n -version:\n ex\u00E9cution de la version sp\u00E9cifi\u00E9e obligatoire\n -showversion impression de la version du produit et poursuite de l''op\u00E9ration\n -jre-restrict-search | -no-jre-restrict-search\n inclusion/exclusion des environnements JRE priv\u00E9s de l''utilisateur dans la recherche de version\n -? -help impression du message d''aide\n -X impression de l''aide sur les options non standard\n -ea[:...|:]\n -enableassertions[:...|:]\n activation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -da[:...|:]\n -disableassertions[:...|:]\n d\u00E9sactivation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -esa | -enablesystemassertions\n activation des assertions syst\u00E8me\n -dsa | -disablesystemassertions\n d\u00E9sactivation des assertions syst\u00E8me\n -agentlib:[=]\n chargement de la biblioth\u00E8que d''agent natif , par exemple -agentlib:hprof\n voir \u00E9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n -agentpath:[=]\n chargement de la biblioth\u00E8que d''agent natif via le chemin d''acc\u00E8s complet\n -javaagent:[=]\n chargement de l''agent du langage de programmation Java, voir java.lang.instrument\n -splash:\n affichage de l''\u00E9cran d''accueil avec l''image sp\u00E9cifi\u00E9e\nVoir http://www.oracle.com/technetwork/java/javase/documentation/index.html pour plus de d\u00E9tails. +java.launcher.opt.footer =\ -cp \n -classpath \n Liste de r\u00E9pertoires, d''archives JAR et\n d''archives ZIP s\u00E9par\u00E9s par des {0}, dans laquelle rechercher les fichiers de classe.\n -D=\n d\u00E9finition d''une propri\u00E9t\u00E9 syst\u00E8me\n -verbose:[class|gc|jni]\n activation de la sortie en mode verbose\n -version impression de la version du produit et fin de l''op\u00E9ration\n -version:\n ex\u00E9cution de la version sp\u00E9cifi\u00E9e obligatoire\n -showversion impression de la version du produit et poursuite de l''op\u00E9ration\n -jre-restrict-search | -no-jre-restrict-search\n inclusion/exclusion des environnements JRE priv\u00E9s de l''utilisateur dans la recherche de version\n -? -help impression du message d''aide\n -X impression de l''aide sur les options non standard\n -ea[:...|:]\n -enableassertions[:...|:]\n activation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -da[:...|:]\n -disableassertions[:...|:]\n d\u00E9sactivation des assertions avec la granularit\u00E9 sp\u00E9cifi\u00E9e\n -esa | -enablesystemassertions\n activation des assertions syst\u00E8me\n -dsa | -disablesystemassertions\n d\u00E9sactivation des assertions syst\u00E8me\n -agentlib:[=]\n chargement de la biblioth\u00E8que d''agent natif , par exemple -agentlib:hprof\n voir \u00E9galement, -agentlib:jdwp=help et -agentlib:hprof=help\n -agentpath:[=]\n chargement de la biblioth\u00E8que d''agent natif via le chemin d''acc\u00E8s complet\n -javaagent:[=]\n chargement de l''agent du langage de programmation Java, voir java.lang.instrument\n -splash:\n affichage de l''\u00E9cran d''accueil avec l''image sp\u00E9cifi\u00E9e\nVoir http://www.oracle.com/technetwork/java/javase/documentation/index.html pour plus de d\u00E9tails. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed ex\u00E9cution en mode mixte (valeur par d\u00E9faut)\n -Xint ex\u00E9cution en mode interpr\u00E9t\u00E9 uniquement\n -Xbootclasspath:\n d\u00E9finition du chemin de recherche pour les ressources et classes bootstrap\n -Xbootclasspath/a:\n ajout \u00E0 la fin du chemin de classe bootstrap\n -Xbootclasspath/p:\n ajout au d\u00E9but du chemin de classe bootstrap\n -Xdiag affichage de messages de diagnostic suppl\u00E9mentaires\n -Xnoclassgc d\u00E9sactivation de l''op\u00E9ration de ramasse-miette (garbage collection) de la classe\n -Xincgc activation de l''op\u00E9ration de ramasse-miette (garbage collection) incr\u00E9mentielle\n -Xloggc: journalisation du statut de l''op\u00E9ration de ramasse-miette (garbage collection) dans un fichier avec horodatages\n -Xbatch d\u00E9sactivation de la compilation en arri\u00E8re-plan\n -Xms d\u00E9finition de la taille initiale des portions de m\u00E9moire Java\n -Xmx d\u00E9finition de la taille maximale des portions de m\u00E9moire Java\n -Xss d\u00E9finition de la taille de pile de thread Java\n -Xprof sortie des donn\u00E9es de profilage de l''unit\u00E9 centrale\n -Xfuture activation des contr\u00F4les les plus stricts en vue d''anticiper la future valeur par d\u00E9faut\n -Xrs r\u00E9duction de l''utilisation des signaux OS par Java/la machine virtuelle (voir documentation)\n -Xcheck:jni ex\u00E9cution de contr\u00F4les suppl\u00E9mentaires pour les fonctions JNI\n -Xshare:off aucune tentative d''utilisation des donn\u00E9es de classe partag\u00E9es\n -Xshare:auto utilisation des donn\u00E9es de classe partag\u00E9es si possible (valeur par d\u00E9faut)\n -Xshare:on utilisation des donn\u00E9es de classe partag\u00E9es obligatoire ou \u00E9chec de l''op\u00E9ration\n -XshowSettings affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n -XshowSettings:all\n affichage de tous les param\u00E8tres et poursuite de l''op\u00E9ration\n -XshowSettings:vm affichage de tous les param\u00E8tres de machine virtuelle et poursuite de l''op\u00E9ration\n -XshowSettings:properties\n affichage de tous les param\u00E8tres de propri\u00E9t\u00E9 et poursuite de l''op\u00E9ration\n -XshowSettings:locale\n affichage de tous les param\u00E8tres d''environnement local et poursuite de l''op\u00E9ration\n\nLes options -X ne sont pas des options standard et peuvent faire l''objet de modifications sans pr\u00E9avis.\n @@ -50,7 +50,5 @@ java.launcher.cls.error5=Erreur : des composants d'ex\u00E9cution JavaFX obligat java.launcher.jar.error1=Erreur : une erreur inattendue est survenue lors de la tentative d''ouverture du fichier {0} java.launcher.jar.error2=fichier manifeste introuvable dans {0} java.launcher.jar.error3=aucun attribut manifest principal dans {0} -java.launcher.jar.error4=aucun attribut manifest ''Profile'' dans {0} -java.launcher.jar.error5=Profil {0} requis par {1} non pris en charge par cette ex\u00E9cution java.launcher.init.error=erreur d'initialisation java.launcher.javafx.error1=Erreur : la signature de la m\u00E9thode launchApplication JavaFX est incorrecte, la\nm\u00E9thode doit \u00EAtre d\u00E9clar\u00E9e statique et renvoyer une valeur de type void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties index 7ca3cf357c8..492b6755111 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_it.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=Errore: non sono presenti i componenti runtime di JavaF java.launcher.jar.error1=Errore: si \u00E8 verificato un errore imprevisto durante il tentativo di aprire il file {0} java.launcher.jar.error2=manifest non trovato in {0} java.launcher.jar.error3=nessun attributo manifest principale in {0} -java.launcher.jar.error4=nessun attributo manifest di profilo in {0} -java.launcher.jar.error5=Il profilo {0} richiesto da {1} non \u00E8 supportato da questo runtime java.launcher.init.error=errore di inizializzazione java.launcher.javafx.error1=Errore: il metodo JavaFX launchApplication dispone di una firma errata, \nla firma deve essere dichiarata static e restituire un valore di tipo void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties index 52c220a6926..d1f2f699f2e 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_ja.properties @@ -34,11 +34,11 @@ java.launcher.ergo.message1 =\ \u30C7\u30D5\u30A9\u30EB\u30C8V java.launcher.ergo.message2 =\ \u3053\u308C\u306F\u30B5\u30FC\u30D0\u30FC\u30AF\u30E9\u30B9\u306E\u30DE\u30B7\u30F3\u3067\u5B9F\u884C\u3057\u3066\u3044\u308B\u305F\u3081\u3067\u3059\u3002\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\n JAR\u30A2\u30FC\u30AB\u30A4\u30D6\u304A\u3088\u3073ZIP\u30A2\u30FC\u30AB\u30A4\u30D6\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3067\u3059\u3002\n -D=\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8A2D\u5B9A\u3059\u308B\n -verbose:[class|gc|jni]\n \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n -version \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D42\u4E86\u3059\u308B\n -version:\n \u6307\u5B9A\u3057\u305F\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u5B9F\u884C\u306B\u5FC5\u9808\u306B\u3059\u308B\n -showversion \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D9A\u884C\u3059\u308B\n -jre-restrict-search | -no-jre-restrict-search\n \u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8JRE\u3092\u30D0\u30FC\u30B8\u30E7\u30F3\u691C\u7D22\u306B\u542B\u3081\u308B/\u9664\u5916\u3059\u308B\n -? -help \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n -X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u95A2\u3059\u308B\u30D8\u30EB\u30D7\u3092\u51FA\u529B\u3059\u308B\n -ea[:...|:]\n -enableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -da[:...|:]\n -disableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -esa | -enablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -dsa | -disablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -agentlib:[=]\n \u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002\u4F8B: -agentlib:hprof\n -agentlib:jdwp=help\u3068-agentlib:hprof=help\u3082\u53C2\u7167\n -agentpath:[=]\n \u30D5\u30EB\u30D1\u30B9\u540D\u3067\u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\n -javaagent:[=]\n Java\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002java.lang.instrument\u3092\u53C2\u7167\n -splash:\n \u6307\u5B9A\u3057\u305F\u30A4\u30E1\u30FC\u30B8\u3067\u30B9\u30D7\u30E9\u30C3\u30B7\u30E5\u753B\u9762\u3092\u8868\u793A\u3059\u308B\n\u8A73\u7D30\u306Fhttp://www.oracle.com/technetwork/java/javase/documentation/index.html\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 +java.launcher.opt.footer =\ -cp <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n -classpath <\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB\u306E\u30AF\u30E9\u30B9\u691C\u7D22\u30D1\u30B9>\n \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001\n JAR\u30A2\u30FC\u30AB\u30A4\u30D6\u304A\u3088\u3073ZIP\u30A2\u30FC\u30AB\u30A4\u30D6\u306E{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30EA\u30B9\u30C8\u3067\u3059\u3002\n -D=\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u8A2D\u5B9A\u3059\u308B\n -verbose:[class|gc|jni]\n \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n -version \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D42\u4E86\u3059\u308B\n -version:\n \u6307\u5B9A\u3057\u305F\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u5B9F\u884C\u306B\u5FC5\u9808\u306B\u3059\u308B\n -showversion \u88FD\u54C1\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u3066\u7D9A\u884C\u3059\u308B\n -jre-restrict-search | -no-jre-restrict-search\n \u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30E9\u30A4\u30D9\u30FC\u30C8JRE\u3092\u30D0\u30FC\u30B8\u30E7\u30F3\u691C\u7D22\u306B\u542B\u3081\u308B/\u9664\u5916\u3059\u308B\n -? -help \u3053\u306E\u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n -X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u95A2\u3059\u308B\u30D8\u30EB\u30D7\u3092\u51FA\u529B\u3059\u308B\n -ea[:...|:]\n -enableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -da[:...|:]\n -disableassertions[:...|:]\n \u6307\u5B9A\u3057\u305F\u7C92\u5EA6\u3067\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -esa | -enablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -dsa | -disablesystemassertions\n \u30B7\u30B9\u30C6\u30E0\u30FB\u30A2\u30B5\u30FC\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -agentlib:[=]\n \u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002\u4F8B: -agentlib:hprof\n -agentlib:jdwp=help\u3068-agentlib:hprof=help\u3082\u53C2\u7167\n -agentpath:[=]\n \u30D5\u30EB\u30D1\u30B9\u540D\u3067\u30CD\u30A4\u30C6\u30A3\u30D6\u30FB\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30E9\u30A4\u30D6\u30E9\u30EA\u3092\u30ED\u30FC\u30C9\u3059\u308B\n -javaagent:[=]\n Java\u30D7\u30ED\u30B0\u30E9\u30DF\u30F3\u30B0\u8A00\u8A9E\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u30ED\u30FC\u30C9\u3059\u308B\u3002java.lang.instrument\u3092\u53C2\u7167\n -splash:\n \u6307\u5B9A\u3057\u305F\u30A4\u30E1\u30FC\u30B8\u3067\u30B9\u30D7\u30E9\u30C3\u30B7\u30E5\u753B\u9762\u3092\u8868\u793A\u3059\u308B\n\u8A73\u7D30\u306Fhttp://www.oracle.com/technetwork/java/javase/documentation/index.html\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002 # Translators please note do not translate the options themselves -java.launcher.X.usage=\ -Xmixed \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xint \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n -Xbootclasspath:\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u306E\u30AF\u30E9\u30B9\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u691C\u7D22\u30D1\u30B9\u3092\u8A2D\u5B9A\u3059\u308B\n -Xbootclasspath/a:\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3059\u308B\n -Xbootclasspath/p:\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u524D\u306B\u4ED8\u52A0\u3059\u308B\n -Xdiag \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n -Xnoclassgc \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xincgc \u5897\u5206\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xloggc: \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3059\u308B\n -Xbatch \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xms Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xmx Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xss Java\u306E\u30B9\u30EC\u30C3\u30C9\u30FB\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xprof CPU\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30C7\u30FC\u30BF\u3092\u51FA\u529B\u3059\u308B\n -Xfuture \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xrs Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3059\u308B(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n -Xcheck:jni JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3059\u308B\n -Xshare:off \u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u306A\u3044\n -Xshare:auto \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xshare:on \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3059\u308B\u3002\n -XshowSettings \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:all\n \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:vm \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:properties\n \u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:locale\n \ -\u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n\n-X\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u6A19\u6E96\u306A\u306E\u3067\u3001\u4E88\u544A\u306A\u304F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\n +java.launcher.X.usage=\ -Xmixed \u6DF7\u5408\u30E2\u30FC\u30C9\u306E\u5B9F\u884C(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xint \u30A4\u30F3\u30BF\u30D7\u30EA\u30BF\u30FB\u30E2\u30FC\u30C9\u306E\u5B9F\u884C\u306E\u307F\n -Xbootclasspath:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u306E\u30AF\u30E9\u30B9\u3068\u30EA\u30BD\u30FC\u30B9\u306E\u691C\u7D22\u30D1\u30B9\u3092\u8A2D\u5B9A\u3059\u308B\n -Xbootclasspath/a:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u6700\u5F8C\u306B\u8FFD\u52A0\u3059\u308B\n -Xbootclasspath/p:<{0}\u3067\u533A\u5207\u3089\u308C\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304A\u3088\u3073zip/jar\u30D5\u30A1\u30A4\u30EB>\n \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306E\u524D\u306B\u4ED8\u52A0\u3059\u308B\n -Xdiag \u8FFD\u52A0\u306E\u8A3A\u65AD\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3059\u308B\n -Xnoclassgc \u30AF\u30E9\u30B9\u306E\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xincgc \u5897\u5206\u30AC\u30D9\u30FC\u30B8\u30FB\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xloggc: \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u304C\u4ED8\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u306BGC\u30B9\u30C6\u30FC\u30BF\u30B9\u306E\u30ED\u30B0\u3092\u8A18\u9332\u3059\u308B\n -Xbatch \u30D0\u30C3\u30AF\u30B0\u30E9\u30A6\u30F3\u30C9\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3092\u7121\u52B9\u306B\u3059\u308B\n -Xms Java\u306E\u521D\u671F\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xmx Java\u306E\u6700\u5927\u30D2\u30FC\u30D7\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xss Java\u306E\u30B9\u30EC\u30C3\u30C9\u30FB\u30B9\u30BF\u30C3\u30AF\u30FB\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A\u3059\u308B\n -Xprof CPU\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30C7\u30FC\u30BF\u3092\u51FA\u529B\u3059\u308B\n -Xfuture \u5C06\u6765\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u3092\u898B\u8D8A\u3057\u3066\u3001\u6700\u3082\u53B3\u5BC6\u306A\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B\n -Xrs Java/VM\u306B\u3088\u308BOS\u30B7\u30B0\u30CA\u30EB\u306E\u4F7F\u7528\u3092\u524A\u6E1B\u3059\u308B(\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u53C2\u7167)\n -Xcheck:jni JNI\u95A2\u6570\u306B\u5BFE\u3059\u308B\u8FFD\u52A0\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u5B9F\u884C\u3059\u308B\n -Xshare:off \u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3057\u3088\u3046\u3068\u3057\u306A\u3044\n -Xshare:auto \u53EF\u80FD\u3067\u3042\u308C\u3070\u5171\u6709\u30AF\u30E9\u30B9\u306E\u30C7\u30FC\u30BF\u3092\u4F7F\u7528\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -Xshare:on \u5171\u6709\u30AF\u30E9\u30B9\u30FB\u30C7\u30FC\u30BF\u306E\u4F7F\u7528\u3092\u5FC5\u9808\u306B\u3057\u3001\u3067\u304D\u306A\u3051\u308C\u3070\u5931\u6557\u3059\u308B\u3002\n -XshowSettings \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:all\n \u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:vm \u3059\u3079\u3066\u306EVM\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:properties\n \ +\u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n -XshowSettings:locale\n \u3059\u3079\u3066\u306E\u30ED\u30B1\u30FC\u30EB\u95A2\u9023\u306E\u8A2D\u5B9A\u3092\u8868\u793A\u3057\u3066\u7D9A\u884C\u3059\u308B\n\n-X\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u975E\u6A19\u6E96\u306A\u306E\u3067\u3001\u4E88\u544A\u306A\u304F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\n # Translators please note do not translate the options themselves java.launcher.X.macosx.usage=\n\u6B21\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306FMac OS X\u56FA\u6709\u3067\u3059\u3002\n -XstartOnFirstThread\n main()\u30E1\u30BD\u30C3\u30C9\u3092\u6700\u521D(AppKit)\u306E\u30B9\u30EC\u30C3\u30C9\u3067\u5B9F\u884C\u3059\u308B\n -Xdock:name="\n Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u540D\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n -Xdock:icon=\n Dock\u306B\u8868\u793A\u3055\u308C\u308B\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30A2\u30A4\u30B3\u30F3\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n\n @@ -51,7 +51,5 @@ java.launcher.cls.error5=\u30A8\u30E9\u30FC: JavaFX\u30E9\u30F3\u30BF\u30A4\u30E java.launcher.jar.error1=\u30A8\u30E9\u30FC: \u30D5\u30A1\u30A4\u30EB{0}\u3092\u958B\u3053\u3046\u3068\u3057\u3066\u3044\u308B\u3068\u304D\u306B\u3001\u4E88\u671F\u3057\u306A\u3044\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F java.launcher.jar.error2={0}\u306B\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 java.launcher.jar.error3={0}\u306B\u30E1\u30A4\u30F3\u30FB\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093 -java.launcher.jar.error4={0}\u306B\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u30FB\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093 -java.launcher.jar.error5={1}\u306B\u5FC5\u8981\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB{0}\u306F\u3053\u306E\u30E9\u30F3\u30BF\u30A4\u30E0\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093 java.launcher.init.error=\u521D\u671F\u5316\u30A8\u30E9\u30FC java.launcher.javafx.error1=\u30A8\u30E9\u30FC: JavaFX launchApplication\u30E1\u30BD\u30C3\u30C9\u306B\u8AA4\u3063\u305F\u30B7\u30B0\u30CD\u30C1\u30E3\u304C\u3042\u308A\u3001\nstatic\u3092\u5BA3\u8A00\u3057\u3066void\u578B\u306E\u5024\u3092\u8FD4\u3059\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059 diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties index a4c3d800c2d..d9d471eec9f 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_ko.properties @@ -34,10 +34,11 @@ java.launcher.ergo.message1 =\ \uAE30\uBCF8 VM\uC740 {0}\uC785 java.launcher.ergo.message2 =\ \uC11C\uBC84\uAE09 \uC2DC\uC2A4\uD15C\uC5D0\uC11C \uC2E4\uD589 \uC911\uC774\uAE30 \uB54C\uBB38\uC785\uB2C8\uB2E4.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \\n -classpath \\n \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uAC80\uC0C9\uD560 {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC,\\n JAR \uC544\uCE74\uC774\uBE0C \uBC0F ZIP \uC544\uCE74\uC774\uBE0C \uBAA9\uB85D\uC785\uB2C8\uB2E4.\\n -D=\\n \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 \uC124\uC815\uD569\uB2C8\uB2E4.\\n -verbose:[class|gc|jni]\\n \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -version \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\\n -version:\\n \uC2E4\uD589\uD560 \uBC84\uC804\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.\\n -showversion \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\\n -jre-restrict-search | -no-jre-restrict-search\\n \uBC84\uC804 \uAC80\uC0C9\uC5D0\uC11C \uC0AC\uC6A9\uC790 \uC804\uC6A9 JRE\uB97C \uD3EC\uD568/\uC81C\uC678\uD569\uB2C8\uB2E4.\\n -? -help \uC774 \uB3C4\uC6C0\uB9D0 \uBA54\uC2DC\uC9C0\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.\\n -X \uBE44\uD45C\uC900 \uC635\uC158\uC5D0 \uB300\uD55C \uB3C4\uC6C0\uB9D0\uC744 \uC778\uC1C4\uD569\uB2C8\uB2E4.\\n -ea[:...|:]\\n -enableassertions[:...|:]\\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -da[:...|:]\\n -disableassertions[:...|:]\\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -esa | -enablesystemassertions\\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -dsa | -disablesystemassertions\\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\\n -agentlib:[=]\\n \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4(\uC608: -agentlib:hprof).\\n -agentlib:jdwp=help \uBC0F -agentlib:hprof=help\uB3C4 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\\n -agentpath:[=]\\n \uC804\uCCB4 \uACBD\uB85C\uBA85\uC744 \uC0AC\uC6A9\uD558\uC5EC \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4.\\n -javaagent:[=]\\n Java \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4 \uC5D0\uC774\uC804\uD2B8\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4. java.lang.instrument\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\\n -splash:\\n \uC774\uBBF8\uC9C0\uAC00 \uC9C0\uC815\uB41C \uC2A4\uD50C\uB798\uC2DC \uD654\uBA74\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4.\\n\uC790\uC138\uD55C \uB0B4\uC6A9\uC740 http://www.oracle.com/technetwork/java/javase/documentation/index.html\uC744 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624. +java.launcher.opt.footer =\ -cp <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n -classpath <\uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C\uC758 \uD074\uB798\uC2A4 \uAC80\uC0C9 \uACBD\uB85C>\n \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uAC80\uC0C9\uD560 {0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC,\n JAR \uC544\uCE74\uC774\uBE0C \uBC0F ZIP \uC544\uCE74\uC774\uBE0C \uBAA9\uB85D\uC785\uB2C8\uB2E4.\n -D=\n \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 \uC124\uC815\uD569\uB2C8\uB2E4.\n -verbose:[class|gc|jni]\n \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -version \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uC885\uB8CC\uD569\uB2C8\uB2E4.\n -version:\n \uC2E4\uD589\uD560 \uBC84\uC804\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.\n -showversion \uC81C\uD488 \uBC84\uC804\uC744 \uC778\uC1C4\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -jre-restrict-search | -no-jre-restrict-search\n \uBC84\uC804 \uAC80\uC0C9\uC5D0\uC11C \uC0AC\uC6A9\uC790 \uC804\uC6A9 JRE\uB97C \uD3EC\uD568/\uC81C\uC678\uD569\uB2C8\uB2E4.\n -? -help \uC774 \uB3C4\uC6C0\uB9D0 \uBA54\uC2DC\uC9C0\uB97C \uC778\uC1C4\uD569\uB2C8\uB2E4.\n -X \uBE44\uD45C\uC900 \uC635\uC158\uC5D0 \uB300\uD55C \uB3C4\uC6C0\uB9D0\uC744 \uC778\uC1C4\uD569\uB2C8\uB2E4.\n -ea[:...|:]\n -enableassertions[:...|:]\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -da[:...|:]\n -disableassertions[:...|:]\n \uC138\uBD84\uC131\uC774 \uC9C0\uC815\uB41C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -esa | -enablesystemassertions\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -dsa | -disablesystemassertions\n \uC2DC\uC2A4\uD15C \uAC80\uC99D\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -agentlib:[=]\n \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4(\uC608: -agentlib:hprof).\n -agentlib:jdwp=help \uBC0F -agentlib:hprof=help\uB3C4 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n -agentpath:[=]\n \uC804\uCCB4 \uACBD\uB85C\uBA85\uC744 \uC0AC\uC6A9\uD558\uC5EC \uACE0\uC720 \uC5D0\uC774\uC804\uD2B8 \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4.\n -javaagent:[=]\n Java \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4 \uC5D0\uC774\uC804\uD2B8\uB97C \uB85C\uB4DC\uD569\uB2C8\uB2E4. java.lang.instrument\uB97C \uCC38\uC870\uD558\uC2ED\uC2DC\uC624.\n -splash:\n \uC774\uBBF8\uC9C0\uAC00 \uC9C0\uC815\uB41C \uC2A4\uD50C\uB798\uC2DC \uD654\uBA74\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n\uC790\uC138\uD55C \uB0B4\uC6A9\uC740 http://www.oracle.com/technetwork/java/javase/documentation/index.html\uC744 \uCC38\uC870\uD558\uC2ED\uC2DC\uC624. # Translators please note do not translate the options themselves -java.launcher.X.usage=\ -Xmixed \uD63C\uD569 \uBAA8\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xint \uD574\uC11D\uB41C \uBAA8\uB4DC\uB9CC \uC2E4\uD589\uD569\uB2C8\uB2E4.\n -Xbootclasspath:\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uBC0F \uB9AC\uC18C\uC2A4\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACBD\uB85C\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xbootclasspath/a:\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uB05D\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xbootclasspath/p:\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uC55E\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xdiag \uCD94\uAC00 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n -Xnoclassgc \uD074\uB798\uC2A4\uC758 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xincgc \uC99D\uBD84\uC801\uC778 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xloggc: \uC2DC\uAC04 \uAE30\uB85D\uACFC \uD568\uAED8 \uD30C\uC77C\uC5D0 GC \uC0C1\uD0DC\uB97C \uAE30\uB85D\uD569\uB2C8\uB2E4.\n -Xbatch \uBC31\uADF8\uB77C\uC6B4\uB4DC \uCEF4\uD30C\uC77C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xms \uCD08\uAE30 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xmx \uCD5C\uB300 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xss Java \uC2A4\uB808\uB4DC \uC2A4\uD0DD \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xprof CPU \uD504\uB85C\uD30C\uC77C \uC791\uC131 \uB370\uC774\uD130\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4.\n -Xfuture \uBBF8\uB798 \uAE30\uBCF8\uAC12\uC744 \uC608\uCE21\uD558\uC5EC \uAC00\uC7A5 \uC5C4\uACA9\uD55C \uAC80\uC0AC\uB97C \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xrs Java/VM\uC5D0 \uC758\uD55C OS \uC2E0\uD638 \uC0AC\uC6A9\uC744 \uC904\uC785\uB2C8\uB2E4(\uC124\uBA85\uC11C \uCC38\uC870).\n -Xcheck:jni JNI \uD568\uC218\uC5D0 \uB300\uD55C \uCD94\uAC00 \uAC80\uC0AC\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n -Xshare:off \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130 \uC0AC\uC6A9\uC744 \uC2DC\uB3C4\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -Xshare:auto \uAC00\uB2A5\uD55C \uACBD\uC6B0 \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xshare:on \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. \uADF8\uB807\uC9C0 \uC54A\uC744 \uACBD\uC6B0 \uC2E4\uD328\uD569\uB2C8\uB2E4.\n -XshowSettings \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:all\n \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:vm \uBAA8\uB4E0 VM \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:properties\n \uBAA8\uB4E0 \uC18D\uC131 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:locale\n \uBAA8\uB4E0 \uB85C\uCF00\uC77C \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n\n-X \uC635\uC158\uC740 \uBE44\uD45C\uC900 \uC635\uC158\uC774\uBBC0\uB85C \uD1B5\uC9C0 \uC5C6\uC774 \uBCC0\uACBD\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n +java.launcher.X.usage=\ -Xmixed \uD63C\uD569 \uBAA8\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xint \uD574\uC11D\uB41C \uBAA8\uB4DC\uB9CC \uC2E4\uD589\uD569\uB2C8\uB2E4.\n -Xbootclasspath:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uBC0F \uB9AC\uC18C\uC2A4\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACBD\uB85C\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xbootclasspath/a:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uB05D\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xbootclasspath/p:<{0}(\uC73C)\uB85C \uAD6C\uBD84\uB41C \uB514\uB809\uD1A0\uB9AC \uBC0F zip/jar \uD30C\uC77C>\n \uBD80\uD2B8\uC2A4\uD2B8\uB7A9 \uD074\uB798\uC2A4 \uACBD\uB85C \uC55E\uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.\n -Xdiag \uCD94\uAC00 \uC9C4\uB2E8 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n -Xnoclassgc \uD074\uB798\uC2A4\uC758 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xincgc \uC99D\uBD84\uC801\uC778 \uBD88\uD544\uC694\uD55C \uC815\uBCF4 \uBAA8\uC74C\uC744 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xloggc: \uC2DC\uAC04 \uAE30\uB85D\uACFC \uD568\uAED8 \uD30C\uC77C\uC5D0 GC \uC0C1\uD0DC\uB97C \uAE30\uB85D\uD569\uB2C8\uB2E4.\n -Xbatch \uBC31\uADF8\uB77C\uC6B4\uB4DC \uCEF4\uD30C\uC77C\uC744 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xms \uCD08\uAE30 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xmx \uCD5C\uB300 Java \uD799 \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xss Java \uC2A4\uB808\uB4DC \uC2A4\uD0DD \uD06C\uAE30\uB97C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xprof CPU \uD504\uB85C\uD30C\uC77C \uC791\uC131 \uB370\uC774\uD130\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4.\n -Xfuture \uBBF8\uB798 \uAE30\uBCF8\uAC12\uC744 \uC608\uCE21\uD558\uC5EC \uAC00\uC7A5 \uC5C4\uACA9\uD55C \uAC80\uC0AC\uB97C \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uD569\uB2C8\uB2E4.\n -Xrs Java/VM\uC5D0 \uC758\uD55C OS \uC2E0\uD638 \uC0AC\uC6A9\uC744 \uC904\uC785\uB2C8\uB2E4(\uC124\uBA85\uC11C \uCC38\uC870).\n -Xcheck:jni JNI \uD568\uC218\uC5D0 \uB300\uD55C \uCD94\uAC00 \uAC80\uC0AC\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n -Xshare:off \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130 \uC0AC\uC6A9\uC744 \uC2DC\uB3C4\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -Xshare:auto \uAC00\uB2A5\uD55C \uACBD\uC6B0 \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4(\uAE30\uBCF8\uAC12).\n -Xshare:on \uACF5\uC720 \uD074\uB798\uC2A4 \uB370\uC774\uD130\uB97C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4. \uADF8\uB807\uC9C0 \uC54A\uC744 \uACBD\uC6B0 \uC2E4\uD328\uD569\uB2C8\uB2E4.\n -XshowSettings \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:all\n \uBAA8\uB4E0 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:vm \uBAA8\uB4E0 VM \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:properties\n \uBAA8\uB4E0 \uC18D\uC131 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n -XshowSettings:locale\n \uBAA8\uB4E0 \uB85C\uCF00\uC77C \uAD00\uB828 \uC124\uC815\uC744 \uD45C\uC2DC\uD55C \uD6C4 \uACC4\uC18D\uD569\uB2C8\uB2E4.\n\n-X \uC635\uC158\uC740 \uBE44\uD45C\uC900 \uC635\uC158\uC774\uBBC0\uB85C \uD1B5\uC9C0 \uC5C6\uC774 \uBCC0\uACBD\uB420 \uC218 \ +\uC788\uC2B5\uB2C8\uB2E4.\n # Translators please note do not translate the options themselves java.launcher.X.macosx.usage=\n\uB2E4\uC74C\uC740 Mac OS X\uC5D0 \uD2B9\uC815\uB41C \uC635\uC158\uC785\uB2C8\uB2E4.\n -XstartOnFirstThread\n \uCCAB\uBC88\uC9F8 (AppKit) \uC2A4\uB808\uB4DC\uC5D0 main() \uBA54\uC18C\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.\n -Xdock:name="\n \uACE0\uC815\uC73C\uB85C \uD45C\uC2DC\uB41C \uAE30\uBCF8 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8 \uC774\uB984\uC744 \uBB34\uD6A8\uD654\uD569\uB2C8\uB2E4.\n -Xdock:icon=\n \uACE0\uC815\uC73C\uB85C \uD45C\uC2DC\uB41C \uAE30\uBCF8 \uC544\uC774\uCF58\uC744 \uBB34\uD6A8\uD654\uD569\uB2C8\uB2E4.\n\n @@ -50,7 +51,5 @@ java.launcher.cls.error5=\uC624\uB958: \uC774 \uC751\uC6A9 \uD504\uB85C\uADF8\uB java.launcher.jar.error1=\uC624\uB958: {0} \uD30C\uC77C\uC744 \uC5F4\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911 \uC608\uC0C1\uCE58 \uC54A\uC740 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. java.launcher.jar.error2={0}\uC5D0\uC11C Manifest\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. java.launcher.jar.error3={0}\uC5D0 \uAE30\uBCF8 Manifest \uC18D\uC131\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. -java.launcher.jar.error4={0}\uC5D0 Profile manifest \uC18D\uC131\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. -java.launcher.jar.error5={1}\uC5D0 \uD544\uC694\uD55C {0} \uD504\uB85C\uD30C\uC77C\uC740 \uC774 \uB7F0\uD0C0\uC784\uC5D0\uC11C \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. java.launcher.init.error=\uCD08\uAE30\uD654 \uC624\uB958 java.launcher.javafx.error1=\uC624\uB958: JavaFX launchApplication \uBA54\uC18C\uB4DC\uC5D0 \uC798\uBABB\uB41C \uC11C\uBA85\uC774 \uC788\uC2B5\uB2C8\uB2E4.\\n\uB530\uB77C\uC11C static\uC73C\uB85C \uC120\uC5B8\uD558\uACE0 void \uC720\uD615\uC758 \uAC12\uC744 \uBC18\uD658\uD574\uC57C \uD569\uB2C8\uB2E4. diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties index 00425f64412..17d88fef80d 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_pt_BR.properties @@ -34,7 +34,7 @@ java.launcher.ergo.message1 =\ A VM default \u00E9 {0} java.launcher.ergo.message2 =\ porque a execu\u00E7\u00E3o est\u00E1 sendo feita em uma m\u00E1quina de classe de servidor.\n # Translators please note do not translate the options themselves -java.launcher.opt.footer =\ -cp \n -classpath \n Uma lista separada por {0} de diret\u00F3rios, archives JAR\n e archives ZIP nos quais ser\u00E3o procurados os arquivos de classe.\n -D=\n define uma propriedade do sistema\n -verbose[:classe|gc|jni]\n ativa a sa\u00EDda detalhada\n -version imprime a vers\u00E3o do produto e sai do programa\n -version:\n requer a execu\u00E7\u00E3o da vers\u00E3o especificada\n -showversion imprime a vers\u00E3o do produto e continua\n -jre-restrict-search | -no-jre-restrict-search\n inclui/exclui JREs privados do usu\u00E1rio na pesquisa de vers\u00E3o\n -? -help imprime esta mensagem de ajuda\n -X imprime a ajuda sobre op\u00E7\u00F5es n\u00E3o padronizadas\n -ea[:...|:]\n -enableassertions[:...|:]\n ativa asser\u00E7\u00F5es com granularidade especificada\n -da[:...|:]\n -disableassertions[:...|:]\n desativa asser\u00E7\u00F5es com granularidade especificada\n -esa | -enablesystemassertions\n ativa asser\u00E7\u00F5es do sistema\n -dsa | -disablesystemassertions\n desativa asser\u00E7\u00F5es do sistema\n -agentlib:[=]\n carrega a biblioteca de agentes nativa , por exemplo: -agentlib:hprof\n consulte tamb\u00E9m: -agentlib:jdwp=help e -agentlib:hprof=help\n -agentpath:[=]\n carrega a biblioteca de agentes nativa com base no nome do caminho completo\n -javaagent:[=]\n carrega o agente da linguagem de programa\u00E7\u00E3o Java; consulte java.lang.instrument\n -splash:\n mostra a tela de abertura com a imagem especificada\nConsulte http://www.oracle.com/technetwork/java/javase/documentation/index.html para obter mais detalhes. +java.launcher.opt.footer =\ -cp \n -classpath \n Uma lista separada por {0} de diret\u00F3rios, archives JAR\n e archives ZIP nos quais ser\u00E3o procurados os arquivos de classe.\n -D=\n define uma propriedade do sistema\n -verbose:[classe|gc|jni]\n ativa a sa\u00EDda detalhada\n -version imprime a vers\u00E3o do produto e sai do programa\n -version:\n requer a execu\u00E7\u00E3o da vers\u00E3o especificada\n -showversion imprime a vers\u00E3o do produto e continua\n -jre-restrict-search | -no-jre-restrict-search\n inclui/exclui JREs privados do usu\u00E1rio na pesquisa de vers\u00E3o\n -? -help imprime esta mensagem de ajuda\n -X imprime a ajuda sobre op\u00E7\u00F5es n\u00E3o padronizadas\n -ea[:...|:]\n -enableassertions[:...|:]\n ativa asser\u00E7\u00F5es com granularidade especificada\n -da[:...|:]\n -disableassertions[:...|:]\n desativa asser\u00E7\u00F5es com granularidade especificada\n -esa | -enablesystemassertions\n ativa asser\u00E7\u00F5es do sistema\n -dsa | -disablesystemassertions\n desativa asser\u00E7\u00F5es do sistema\n -agentlib:[=]\n carrega a biblioteca de agentes nativa , por exemplo: -agentlib:hprof\n consulte tamb\u00E9m: -agentlib:jdwp=help e -agentlib:hprof=help\n -agentpath:[=]\n carrega a biblioteca de agentes nativa com base no nome do caminho completo\n -javaagent:[=]\n carrega o agente da linguagem de programa\u00E7\u00E3o Java; consulte java.lang.instrument\n -splash:\n mostra a tela de abertura com a imagem especificada\nConsulte http://www.oracle.com/technetwork/java/javase/documentation/index.html para obter mais detalhes. # Translators please note do not translate the options themselves java.launcher.X.usage=\ -Xmixed execu\u00E7\u00E3o no modo misto (default)\n -Xint execu\u00E7\u00E3o somente no modo interpretado\n -Xbootclasspath:\n define o caminho de pesquisa para classes e recursos de inicializa\u00E7\u00E3o\n -Xbootclasspath/a:\n anexa no final do caminho da classe de inicializa\u00E7\u00E3o\n -Xbootclasspath/p:\n anexa no in\u00EDcio do caminho da classe de inicializa\u00E7\u00E3o\n -Xdiag mostra mensagens de diagn\u00F3stico adicionais\n -Xnoclassgc desativa a coleta de lixo da classe\n -Xincgc ativa a coleta de lixo incremental\n -Xloggc: registra o status do GC status em um arquivo com marca\u00E7\u00F5es de data e hor\u00E1rio\n -Xbatch desativa a compila\u00E7\u00E3o em segundo plano\n -Xms define o tamanho inicial do heap Java\n -Xmx define o tamanho m\u00E1ximo do heap Java\n -Xss define o tamanho da pilha de threads java\n -Xprof produz dados de perfil da cpu\n -Xfuture ativa verifica\u00E7\u00F5es de n\u00EDvel m\u00E1ximo de exig\u00EAncia, prevendo o valor default futuro\n -Xrs reduz o uso de sinais do SO pelo(a) Java/VM (consulte a documenta\u00E7\u00E3o)\n -Xcheck:jni executa verifica\u00E7\u00F5es adicionais de fun\u00E7\u00F5es da JNI\n -Xshare:off n\u00E3o tenta usar dados da classe compartilhada\n -Xshare:auto se poss\u00EDvel, usa dados da classe compartilhada (default)\n -Xshare:on requer o uso de dados da classe compartilhada, caso contr\u00E1rio haver\u00E1 falha.\n -XshowSettings mostra todas as defini\u00E7\u00F5es e continua\n -XshowSettings:all\n mostra todas as defini\u00E7\u00F5es e continua\n -XshowSettings:vm mostra todas as defini\u00E7\u00F5es relacionadas \u00E0 vm e continua\n -XshowSettings:properties\n mostra todas as defini\u00E7\u00F5es da propriedade e continua\n -XshowSettings:locale\n mostra todas as defini\u00E7\u00F5es relativas \u00E0s configura\u00E7\u00F5es regionais e continua\n\nAs -X options n\u00E3o s\u00E3o padronizadas e est\u00E3o sujeitas a altera\u00E7\u00F5es sem aviso.\n @@ -50,7 +50,5 @@ java.launcher.cls.error5=Erro: os componentes de runtime do JavaFX n\u00E3o fora java.launcher.jar.error1=Erro: ocorreu um erro inesperado ao tentar abrir o arquivo {0} java.launcher.jar.error2=manifesto n\u00E3o encontrado em {0} java.launcher.jar.error3=nenhum atributo de manifesto principal em {0} -java.launcher.jar.error4=nenhum atributo de manifesto de Perfil em {0} -java.launcher.jar.error5=O perfil {0} exigido por {1} n\u00E3o \u00E9 suportado por este runtime java.launcher.init.error=erro de inicializa\u00E7\u00E3o java.launcher.javafx.error1=Erro: O m\u00E9todo launchApplication do JavaFX tem a assinatura errada. Ele\\ndeve ser declarado como est\u00E1tico e retornar um valor do tipo void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties index 9577f39477a..d64c3f6f347 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_sv.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=Fel: JavaFX-k\u00F6rningskomponenter saknas, och de kr\ java.launcher.jar.error1=Fel: Ett ov\u00E4ntat fel intr\u00E4ffade n\u00E4r filen {0} skulle \u00F6ppnas java.launcher.jar.error2=manifest finns inte i {0} java.launcher.jar.error3=inget huvudmanifestattribut i {0} -java.launcher.jar.error4=inget profilmanifestattribut i {0} -java.launcher.jar.error5=Profil {0} som kr\u00E4vs av {1} kan inte anv\u00E4ndas av den h\u00E4r k\u00F6rningen java.launcher.init.error=initieringsfel java.launcher.javafx.error1=Fel: JavaFX launchApplication-metoden har fel signatur, den \nm\u00E5ste ha deklarerats som statisk och returnera ett v\u00E4rde av typen void diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties index a536e68bfbc..1e352765d39 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_CN.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=\u9519\u8BEF: \u7F3A\u5C11 JavaFX \u8FD0\u884C\u65F6\u7 java.launcher.jar.error1=\u9519\u8BEF: \u5C1D\u8BD5\u6253\u5F00\u6587\u4EF6{0}\u65F6\u51FA\u73B0\u610F\u5916\u9519\u8BEF java.launcher.jar.error2=\u5728{0}\u4E2D\u627E\u4E0D\u5230\u6E05\u5355 java.launcher.jar.error3={0}\u4E2D\u6CA1\u6709\u4E3B\u6E05\u5355\u5C5E\u6027 -java.launcher.jar.error4={0}\u4E2D\u6CA1\u6709\u914D\u7F6E\u6587\u4EF6\u6E05\u5355\u5C5E\u6027 -java.launcher.jar.error5=\u6B64\u8FD0\u884C\u65F6\u4E0D\u652F\u6301{1}\u6240\u9700\u7684\u914D\u7F6E\u6587\u4EF6{0} java.launcher.init.error=\u521D\u59CB\u5316\u9519\u8BEF java.launcher.javafx.error1=\u9519\u8BEF: JavaFX launchApplication \u65B9\u6CD5\u5177\u6709\u9519\u8BEF\u7684\u7B7E\u540D, \u5FC5\u987B\n\u5C06\u65B9\u6CD5\u58F0\u660E\u4E3A\u9759\u6001\u65B9\u6CD5\u5E76\u8FD4\u56DE\u7A7A\u7C7B\u578B\u7684\u503C diff --git a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties index 9fd5ff272a7..57e301d7558 100644 --- a/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties +++ b/jdk/src/share/classes/sun/launcher/resources/launcher_zh_TW.properties @@ -50,7 +50,5 @@ java.launcher.cls.error5=\u932F\u8AA4: \u907A\u6F0F\u57F7\u884C\u6B64\u61C9\u752 java.launcher.jar.error1=\u932F\u8AA4: \u5617\u8A66\u958B\u555F\u6A94\u6848 {0} \u6642\u767C\u751F\u672A\u9810\u671F\u7684\u932F\u8AA4 java.launcher.jar.error2=\u5728 {0} \u4E2D\u627E\u4E0D\u5230\u8CC7\u8A0A\u6E05\u55AE java.launcher.jar.error3={0} \u4E2D\u6C92\u6709\u4E3B\u8981\u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027 -java.launcher.jar.error4={0} \u4E2D\u6C92\u6709 Profile \u8CC7\u8A0A\u6E05\u55AE\u5C6C\u6027 -java.launcher.jar.error5=\u6B64\u7A0B\u5F0F\u5BE6\u969B\u57F7\u884C\u4E0D\u652F\u63F4 {1} \u6240\u9700\u7684\u8A2D\u5B9A\u6A94 {0} java.launcher.init.error=\u521D\u59CB\u5316\u932F\u8AA4 java.launcher.javafx.error1=\u932F\u8AA4: JavaFX launchApplication \u65B9\u6CD5\u7684\u7C3D\u7AE0\u932F\u8AA4\uFF0C\u5B83\n\u5FC5\u9808\u5BA3\u544A\u70BA\u975C\u614B\u4E26\u50B3\u56DE void \u985E\u578B\u7684\u503C diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_de.properties b/jdk/src/share/classes/sun/print/resources/serviceui_de.properties index c7a48fcab41..51dac99f71c 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_de.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_de.properties @@ -17,8 +17,8 @@ button.print=Drucken button.properties=E&igenschaften... # checkbox.collate=&Sortieren -checkbox.jobsheets=&Bannerseite -checkbox.printtofile=Ausgabe in &Datei +checkbox.jobsheets=Banner&seite +checkbox.printtofile=Aus&gabe in Datei # dialog.printtitle=Drucken dialog.pstitle=Seite einrichten @@ -29,7 +29,7 @@ dialog.noprintermsg=Kein Druckservice gefunden. dialog.writeerror=Schreiben in Datei nicht m\u00F6glich: # label.info=Info: -label.jobname=&Job-Name: +label.jobname=&Jobname: label.numcopies=Anzahl &Kopien: label.priority=P&riorit\u00E4t: label.psname=&Name: @@ -42,21 +42,21 @@ label.username=&Benutzername: label.millimetres=(mm) label.inches=(Zoll) label.topmargin=&oben -label.bottommargin=&unten +label.bottommargin=u&nten label.leftmargin=&links -label.rightmargin=&rechts +label.rightmargin=re&chts # radiobutton.color=&Farbe radiobutton.draftq=Ent&wurf -radiobutton.duplex=&Duplex +radiobutton.duplex=Du&plex radiobutton.highq=&Hoch -radiobutton.landscape=&Querformat +radiobutton.landscape=Querforma&t radiobutton.monochrome=&Monochrom radiobutton.normalq=&Normal -radiobutton.oneside=&Einseitig +radiobutton.oneside=E&inseitig radiobutton.portrait=Hochfor&mat radiobutton.rangeall=A&lle -radiobutton.rangepages=S&eiten +radiobutton.rangepages=Sei&ten radiobutton.revlandscape=Umgekehrtes Q&uerformat radiobutton.revportrait=Umgekehrtes &Hochformat radiobutton.tumble=&Kalenderdruck diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_es.properties b/jdk/src/share/classes/sun/print/resources/serviceui_es.properties index 70c31fe9506..a0af46041a7 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_es.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_es.properties @@ -36,29 +36,29 @@ label.psname=&Nombre: label.pstype=Tipo: label.rangeto=A label.size=Tama&\u00F1o: -label.source=Ori&gen: +label.source=Orig&en: label.status=Estado: label.username=&Usuario: label.millimetres=(mm) label.inches=(pulg.) -label.topmargin=&superior +label.topmargin=s&uperior label.bottommargin=in&ferior label.leftmargin=iz&quierdo label.rightmargin=d&erecho # radiobutton.color=&Color -radiobutton.draftq=Bo&rrador +radiobutton.draftq=B&orrador radiobutton.duplex=&D\u00FAplex -radiobutton.highq=&Alta +radiobutton.highq=Al&ta radiobutton.landscape=Hori&zontal radiobutton.monochrome=&Monocromo radiobutton.normalq=&Normal radiobutton.oneside=Una Ca&ra radiobutton.portrait=&Vertical radiobutton.rangeall=&Todo -radiobutton.rangepages=P\u00E1&ginas +radiobutton.rangepages=P\u00E1gina&s radiobutton.revlandscape=&Horizontal Inverso -radiobutton.revportrait=Vertical Inver&so +radiobutton.revportrait=Vertical I&nverso radiobutton.tumble=Cam&bio de Cara # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties index a09df3e5846..366aa3ba3e3 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties @@ -29,7 +29,7 @@ dialog.noprintermsg=Service d'impression introuvable. dialog.writeerror=Impossible d'\u00E9crire dans le fichier : # label.info=Infos : -label.jobname=Nom du &travail : +label.jobname=Nom du tra&vail : label.numcopies=Nombre de c&opies : label.priority=P&riorit\u00E9 : label.psname=&Nom : @@ -38,22 +38,22 @@ label.rangeto=A label.size=Tai&lle : label.source=Sour&ce : label.status=Statut : -label.username=Nom &utilisateur : +label.username=Nom ut&ilisateur : label.millimetres=(mm) label.inches=(po) label.topmargin=&haut label.bottommargin=&bas -label.leftmargin=&gauche +label.leftmargin=gauc&he label.rightmargin=&droite # -radiobutton.color=Coule&ur +radiobutton.color=Coul&eur radiobutton.draftq=Broui&llon radiobutton.duplex=&Duplex radiobutton.highq=Ma&x. -radiobutton.landscape=Pay&sage -radiobutton.monochrome=&Monochrome +radiobutton.landscape=Pa&ysage +radiobutton.monochrome=Monoc&hrome radiobutton.normalq=&Normal -radiobutton.oneside=&Un c\u00F4t\u00E9 +radiobutton.oneside=Un &c\u00F4t\u00E9 radiobutton.portrait=&Portrait radiobutton.rangeall=&Tout radiobutton.rangepages=Pag&es @@ -64,7 +64,7 @@ radiobutton.tumble=&T\u00EAte-b\u00EAche # 65 = KeyEvent.VK_A tab.appearance=&Apparence tab.general=&G\u00E9n\u00E9ral -tab.pagesetup=Mi&se en page +tab.pagesetup=&Mise en page # error.pagerange=Plage de pages non valide. Sp\u00E9cifiez les valeurs de nouveau (ex. : 1-3,5,7-10) error.destination=Nom de fichier non valide ; recommencez diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_it.properties b/jdk/src/share/classes/sun/print/resources/serviceui_it.properties index b5f5382216c..e87efcd27bd 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_it.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_it.properties @@ -47,8 +47,8 @@ label.leftmargin=sinis&tro label.rightmargin=&destro # radiobutton.color=&Colore -radiobutton.draftq=&Bozza -radiobutton.duplex=F&ronte retro +radiobutton.draftq=Bo&zza +radiobutton.duplex=&Fronte retro radiobutton.highq=A<a radiobutton.landscape=Orizzonta&le radiobutton.monochrome=Monocrom&atico @@ -62,7 +62,7 @@ radiobutton.revportrait=Vert&icale capovolto radiobutton.tumble=La&to corto # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=&Aspetto +tab.appearance=As&petto tab.general=&Generale tab.pagesetup=Impo&sta pagina # diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties index 437b432f78e..13d4d72d0ab 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties @@ -31,7 +31,7 @@ dialog.writeerror=N\u00E3o \u00E9 poss\u00EDvel gravar no arquivo: label.info=Informa\u00E7\u00F5es: label.jobname=Nome do &Job: label.numcopies=N\u00FAmer&o de c\u00F3pias: -label.priority=P&rioridade: +label.priority=Pri&oridade: label.psname=&Nome: label.pstype=Tipo: label.rangeto=At\u00E9 @@ -44,27 +44,27 @@ label.inches=(pol) label.topmargin=&superior label.bottommargin=&inferior label.leftmargin=es&querda: -label.rightmargin=di&reita +label.rightmargin=&direita # -radiobutton.color=C&or -radiobutton.draftq=&Rascunho -radiobutton.duplex=&Duplex -radiobutton.highq=&Alta +radiobutton.color=&Cor +radiobutton.draftq=Rascun&ho +radiobutton.duplex=Duple&x +radiobutton.highq=A<a radiobutton.landscape=&Paisagem radiobutton.monochrome=&Monocrom\u00E1tico radiobutton.normalq=&Normal -radiobutton.oneside=Um Lad&o -radiobutton.portrait=&Retrato +radiobutton.oneside=Um La&do +radiobutton.portrait=Re&trato radiobutton.rangeall=T&udo radiobutton.rangepages=&P\u00E1ginas radiobutton.revlandscape=Paisagem I&nvertida -radiobutton.revportrait=Retrato &Invertido +radiobutton.revportrait=Retrato In&vertido radiobutton.tumble=&Virar # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=&Apar\u00EAncia +tab.appearance=Apa&r\u00EAncia tab.general=&Geral -tab.pagesetup=Configura\u00E7\u00E3o de &P\u00E1gina +tab.pagesetup=Con&figura\u00E7\u00E3o da P\u00E1gina # error.pagerange=Faixa de p\u00E1ginas inv\u00E1lida; insira novamente os valores (por exemplo, 1-3,5,7-10) error.destination=Nome de arquivo inv\u00E1lido; tente novamente diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties b/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties index 16f04f634b3..f6475df9f59 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_sv.properties @@ -17,7 +17,7 @@ button.print=Skriv ut button.properties=&Egenskaper... # checkbox.collate=&Sortera -checkbox.jobsheets=&F\u00F6rs\u00E4ttsblad +checkbox.jobsheets=F&\u00F6rs\u00E4ttsblad checkbox.printtofile=Skriv ut till &fil # dialog.printtitle=Skriv ut @@ -30,13 +30,13 @@ dialog.writeerror=Kan inte skriva till filen: # label.info=Information: label.jobname=&Utskrift: -label.numcopies=Antal &exemplar: +label.numcopies=Antal e&xemplar: label.priority=P&rioritet: label.psname=&Namn: label.pstype=Typ: label.rangeto=Till label.size=Stor&lek: -label.source=K\u00E4l&la: +label.source=&K\u00E4lla: label.status=Status: label.username=A&nv\u00E4ndarnamn: label.millimetres=(mm) @@ -50,7 +50,7 @@ radiobutton.color=&F\u00E4rg radiobutton.draftq=Utka&st radiobutton.duplex=&Dubbelsidig radiobutton.highq=&H\u00F6g -radiobutton.landscape=&Liggande +radiobutton.landscape=Liggan&de radiobutton.monochrome=&Monokrom radiobutton.normalq=&Normal radiobutton.oneside=&Ensidig @@ -62,9 +62,9 @@ radiobutton.revportrait=Omv\u00E4nt st\u00E5en&de radiobutton.tumble=&V\u00E4nd # The vkMnemonics correspond with the constants defined in KeyEvent, eg # 65 = KeyEvent.VK_A -tab.appearance=&Format +tab.appearance=Fo&rmat tab.general=&Allm\u00E4nt -tab.pagesetup=Utskrifts&format +tab.pagesetup=&Utskriftsformat # error.pagerange=Ogiltigt sidintervall. Skriv in v\u00E4rdena igen (t ex 1-3,5,7-10) error.destination=Ogiltigt filnamn. F\u00F6rs\u00F6k igen. diff --git a/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties b/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties index 51068bff8de..ae2c6bf5cd1 100644 --- a/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties +++ b/jdk/src/share/classes/sun/rmi/registry/resources/rmiregistry_de.properties @@ -24,5 +24,5 @@ # questions. # -rmiregistry.usage=Verwendung: {0} \n\nwobei die Folgendes beinhalten:\n -J Argument an den Java-Interpreter \u00FCbergeben +rmiregistry.usage=Verwendung: {0} \n\nwobei die Folgendes beinhalten:\n -J Argument an den Java-Interpreter \u00FCbergeben rmiregistry.port.badnumber=Portargument {0} ist keine Zahl. diff --git a/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties b/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties index e744d9cc433..ea728a6dedb 100644 --- a/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties +++ b/jdk/src/share/classes/sun/rmi/server/resources/rmid_ko.properties @@ -87,7 +87,7 @@ rmid.restart.group.warning=\nrmid: (\uACBD\uACE0) \uADF8\uB8F9 \uC7AC\uC2DC\uC79 rmid.restart.service.warning=\nrmid: (\uACBD\uACE0) \uC11C\uBE44\uC2A4 \uC7AC\uC2DC\uC791\uC73C\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: # "rmid" should not be translated -rmid.log.update.warning=\nrmid: (\uACBD\uACE0) \uB85C\uADF8 \uAC31\uC2E0\uC73C\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: +rmid.log.update.warning=\nrmid: (\uACBD\uACE0) \uB85C\uADF8 \uC5C5\uB370\uC774\uD2B8\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: # "rmid" should not be translated rmid.log.snapshot.warning=\nrmid: (\uC2EC\uAC01) \uB85C\uADF8 \uC2A4\uB0C5\uC0F7\uC73C\uB85C \uC778\uD574 \uBC1C\uC0DD\uD55C \uC624\uB958: diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java index d5048af0bf9..397a859bcbe 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_ja.java @@ -57,49 +57,51 @@ public class Resources_ja extends java.util.ListResourceBundle { {".jarsigner.verify.options.jar.file.alias.", " jarsigner -verify [options] jar-file [alias...]"}, {".keystore.url.keystore.location", - "[-keystore ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u4F4D\u7F6E"}, + "[-keystore ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u4F4D\u7F6E"}, {".storepass.password.password.for.keystore.integrity", - "[-storepass ] \u30AD\u30FC\u30B9\u30C8\u30A2\u6574\u5408\u6027\u306E\u305F\u3081\u306E\u30D1\u30B9\u30EF\u30FC\u30C9"}, + "[-storepass ] \u30AD\u30FC\u30B9\u30C8\u30A2\u6574\u5408\u6027\u306E\u305F\u3081\u306E\u30D1\u30B9\u30EF\u30FC\u30C9"}, {".storetype.type.keystore.type", - "[-storetype ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u578B"}, + "[-storetype ] \u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u578B"}, {".keypass.password.password.for.private.key.if.different.", - "[-keypass ] \u79D8\u5BC6\u9375\u306E\u30D1\u30B9\u30EF\u30FC\u30C9(\u7570\u306A\u308B\u5834\u5408)"}, + "[-keypass ] \u79D8\u5BC6\u9375\u306E\u30D1\u30B9\u30EF\u30FC\u30C9(\u7570\u306A\u308B\u5834\u5408)"}, {".certchain.file.name.of.alternative.certchain.file", "[-certchain ] \u4EE3\u66FF\u8A3C\u660E\u66F8\u30C1\u30A7\u30FC\u30F3\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, {".sigfile.file.name.of.SF.DSA.file", - "[-sigfile ] .SF/.DSA\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, + "[-sigfile ] .SF/.DSA\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, {".signedjar.file.name.of.signed.JAR.file", - "[-signedjar ] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, + "[-signedjar ] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D"}, {".digestalg.algorithm.name.of.digest.algorithm", - "[-digestalg ] \u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, + "[-digestalg ] \u30C0\u30A4\u30B8\u30A7\u30B9\u30C8\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, {".sigalg.algorithm.name.of.signature.algorithm", - "[-sigalg ] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, + "[-sigalg ] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u540D\u524D"}, {".verify.verify.a.signed.JAR.file", - "[-verify] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u691C\u8A3C"}, + "[-verify] \u7F72\u540D\u4ED8\u304DJAR\u30D5\u30A1\u30A4\u30EB\u306E\u691C\u8A3C"}, {".verbose.suboptions.verbose.output.when.signing.verifying.", "[-verbose[:suboptions]] \u7F72\u540D/\u691C\u8A3C\u6642\u306E\u8A73\u7D30\u51FA\u529B\u3002"}, {".suboptions.can.be.all.grouped.or.summary", " \u30B5\u30D6\u30AA\u30D7\u30B7\u30E7\u30F3\u3068\u3057\u3066\u3001\u3059\u3079\u3066\u3001\u30B0\u30EB\u30FC\u30D7\u307E\u305F\u306F\u30B5\u30DE\u30EA\u30FC\u3092\u4F7F\u7528\u3067\u304D\u307E\u3059"}, {".certs.display.certificates.when.verbose.and.verifying", - "[-certs] \u8A73\u7D30\u51FA\u529B\u304A\u3088\u3073\u691C\u8A3C\u6642\u306B\u8A3C\u660E\u66F8\u3092\u8868\u793A"}, + "[-certs] \u8A73\u7D30\u51FA\u529B\u304A\u3088\u3073\u691C\u8A3C\u6642\u306B\u8A3C\u660E\u66F8\u3092\u8868\u793A"}, {".tsa.url.location.of.the.Timestamping.Authority", - "[-tsa ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u5834\u6240"}, + "[-tsa ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u5834\u6240"}, {".tsacert.alias.public.key.certificate.for.Timestamping.Authority", - "[-tsacert ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u516C\u958B\u9375\u8A3C\u660E\u66F8"}, + "[-tsacert ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306E\u516C\u958B\u9375\u8A3C\u660E\u66F8"}, + {".tsapolicyid.tsapolicyid.for.Timestamping.Authority", + "[-tsapolicyid ] \u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u5C40\u306ETSAPolicyID"}, {".altsigner.class.class.name.of.an.alternative.signing.mechanism", - "[-altsigner ] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u30AF\u30E9\u30B9\u540D"}, + "[-altsigner ] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u30AF\u30E9\u30B9\u540D"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", - "[-altsignerpath ]\u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u4F4D\u7F6E"}, + "[-altsignerpath ] \u4EE3\u66FF\u7F72\u540D\u30E1\u30AB\u30CB\u30BA\u30E0\u306E\u5834\u6240"}, {".internalsf.include.the.SF.file.inside.the.signature.block", - "[-internalsf] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30D6\u30ED\u30C3\u30AF\u306B.SF\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B"}, + "[-internalsf] \u30B7\u30B0\u30CD\u30C1\u30E3\u30FB\u30D6\u30ED\u30C3\u30AF\u306B.SF\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B"}, {".sectionsonly.don.t.compute.hash.of.entire.manifest", - "[-sectionsonly] \u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5168\u4F53\u306E\u30CF\u30C3\u30B7\u30E5\u306F\u8A08\u7B97\u3057\u306A\u3044"}, + "[-sectionsonly] \u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u5168\u4F53\u306E\u30CF\u30C3\u30B7\u30E5\u306F\u8A08\u7B97\u3057\u306A\u3044"}, {".protected.keystore.has.protected.authentication.path", - "[-protected] \u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u306F\u4FDD\u8B77\u3055\u308C\u305F\u8A8D\u8A3C\u30D1\u30B9\u304C\u3042\u308B"}, + "[-protected] \u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u306F\u4FDD\u8B77\u3055\u308C\u305F\u8A8D\u8A3C\u30D1\u30B9\u304C\u3042\u308B"}, {".providerName.name.provider.name", - "[-providerName ] \u30D7\u30ED\u30D0\u30A4\u30C0\u540D"}, + "[-providerName ] \u30D7\u30ED\u30D0\u30A4\u30C0\u540D"}, {".providerClass.class.name.of.cryptographic.service.provider.s", - "[-providerClass \u6697\u53F7\u5316\u30B5\u30FC\u30D3\u30B9\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u306E\u540D\u524D"}, + "[-providerClass \u6697\u53F7\u5316\u30B5\u30FC\u30D3\u30B9\u30FB\u30D7\u30ED\u30D0\u30A4\u30C0\u306E\u540D\u524D"}, {".providerArg.arg.master.class.file.and.constructor.argument", " [-providerArg ]] ... \u30DE\u30B9\u30BF\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3068\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u306E\u5F15\u6570"}, {".strict.treat.warnings.as.errors", diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java index e3a34a7f59d..ee2334d9118 100644 --- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java +++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources_zh_CN.java @@ -71,9 +71,9 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {".signedjar.file.name.of.signed.JAR.file", "[-signedjar <\u6587\u4EF6>] \u5DF2\u7B7E\u540D\u7684 JAR \u6587\u4EF6\u7684\u540D\u79F0"}, {".digestalg.algorithm.name.of.digest.algorithm", - "[-digestalg <\u7B97\u6CD5>] \u6458\u8981\u7B97\u6CD5\u7684\u540D\u79F0"}, + "[-digestalg <\u7B97\u6CD5>] \u6458\u8981\u7B97\u6CD5\u7684\u540D\u79F0"}, {".sigalg.algorithm.name.of.signature.algorithm", - "[-sigalg <\u7B97\u6CD5>] \u7B7E\u540D\u7B97\u6CD5\u7684\u540D\u79F0"}, + "[-sigalg <\u7B97\u6CD5>] \u7B7E\u540D\u7B97\u6CD5\u7684\u540D\u79F0"}, {".verify.verify.a.signed.JAR.file", "[-verify] \u9A8C\u8BC1\u5DF2\u7B7E\u540D\u7684 JAR \u6587\u4EF6"}, {".verbose.suboptions.verbose.output.when.signing.verifying.", @@ -86,6 +86,8 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "[-tsa ] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684\u4F4D\u7F6E"}, {".tsacert.alias.public.key.certificate.for.Timestamping.Authority", "[-tsacert <\u522B\u540D>] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684\u516C\u5171\u5BC6\u94A5\u8BC1\u4E66"}, + {".tsapolicyid.tsapolicyid.for.Timestamping.Authority", + "[-tsapolicyid ] \u65F6\u95F4\u6233\u9881\u53D1\u673A\u6784\u7684 TSAPolicyID"}, {".altsigner.class.class.name.of.an.alternative.signing.mechanism", "[-altsigner <\u7C7B>] \u66FF\u4EE3\u7684\u7B7E\u540D\u673A\u5236\u7684\u7C7B\u540D"}, {".altsignerpath.pathlist.location.of.an.alternative.signing.mechanism", @@ -132,7 +134,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {".Signature.related.entries.","(\u4E0E\u7B7E\u540D\u76F8\u5173\u7684\u6761\u76EE)"}, {".Unsigned.entries.", "(\u672A\u7B7E\u540D\u6761\u76EE)"}, {"jar.is.unsigned.signatures.missing.or.not.parsable.", - "jar \u672A\u7B7E\u540D\u3002(\u7F3A\u5C11\u7B7E\u540D\u6216\u65E0\u6CD5\u5BF9\u7B7E\u540D\u8FDB\u884C\u8BED\u6CD5\u5206\u6790)"}, + "jar \u672A\u7B7E\u540D\u3002(\u7F3A\u5C11\u7B7E\u540D\u6216\u65E0\u6CD5\u89E3\u6790\u7B7E\u540D)"}, {"jar.verified.", "jar \u5DF2\u9A8C\u8BC1\u3002"}, {"jarsigner.", "jarsigner: "}, {"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.", diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java index 087362c7cec..623bf76be44 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java @@ -40,8 +40,7 @@ public class Resources_de extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Option]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Optionen:"}, {"Use.keytool.help.for.all.available.commands", "\"keytool -help\" f\u00FCr alle verf\u00FCgbaren Befehle verwenden"}, @@ -61,7 +60,6 @@ public class Resources_de extends java.util.ListResourceBundle { "Exportiert ein Zertifikat"}, //-exportcert {"Generates.a.key.pair", "Generiert ein Schl\u00FCsselpaar"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Generiert einen Secret Key"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_de extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Zertifizierungsanforderung in Datei <{0}> gespeichert"}, {"Submit.this.to.your.CA", "Leiten Sie dies an die CA weiter"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "Wenn kein Alias angegeben ist, d\u00FCrfen destalias, srckeypass und destkeypass nicht angegeben werden"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "Wenn kein Alias angegeben ist, d\u00FCrfen destalias und srckeypass nicht angegeben werden"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Der Ziel-Keystore pkcs12 hat unterschiedliche Kennw\u00F6rter f\u00FCr storepass und keypass. Wiederholen Sie den Vorgang, indem Sie -destkeypass angeben."}, {"Certificate.stored.in.file.filename.", "Zertifikat in Datei <{0}> gespeichert"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_de extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "M\u00F6chten Sie es trotzdem zu Ihrem eigenen Keystore hinzuf\u00FCgen? [Nein]: "}, {"Trust.this.certificate.no.", "Diesem Zertifikat vertrauen? [Nein]: "}, - {"YES", "Ja"}, + {"YES", "JA"}, {"New.prompt.", "Neues {0}: "}, {"Passwords.must.differ", "Kennw\u00F6rter m\u00FCssen sich unterscheiden"}, {"Re.enter.new.prompt.", "Neues {0} erneut eingeben: "}, @@ -361,7 +361,7 @@ public class Resources_de extends java.util.ListResourceBundle { "Alias <{0}> verweist auf einen Eintragstyp, der kein Private Key-Eintrag ist. Der Befehl -keyclone unterst\u00FCtzt nur das Clonen von Private Key-Eintr\u00E4gen"}, {".WARNING.WARNING.WARNING.", - "***************** Warnung Warnung Warnung *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signaturgeber #%d:"}, {"Timestamp.", "Zeitstempel:"}, {"Signature.", "Signatur:"}, @@ -386,7 +386,7 @@ public class Resources_de extends java.util.ListResourceBundle { "Zertifikat der obersten Ebene in Antwort:\n"}, {".is.not.trusted.", "... ist nicht vertrauensw\u00FCrdig. "}, {"Install.reply.anyway.no.", "Antwort trotzdem installieren? [Nein]: "}, - {"NO", "Nein"}, + {"NO", "NEIN"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Public Keys in Antwort und Keystore stimmen nicht \u00FCberein"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_de extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Geben Sie -keysize zum Erstellen eines Secret Keys an"}, + {"verified.by.s.in.s", "Gepr\u00FCft von %s in %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "WARNUNG: Nicht gepr\u00FCft. Stellen Sie sicher, dass -keystore korrekt ist."}, + {"Extensions.", "Erweiterungen: "}, {".Empty.value.", "(Leerer Wert)"}, {"Extension.Request.", "Erweiterungsanforderung:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java index 942c0ecf086..ac12dd0c027 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java @@ -40,8 +40,7 @@ public class Resources_es extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Opci\u00F3n]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Opciones:"}, {"Use.keytool.help.for.all.available.commands", "Utilice\"keytool -help\" para todos los comandos disponibles"}, @@ -61,7 +60,6 @@ public class Resources_es extends java.util.ListResourceBundle { "Exporta el certificado"}, //-exportcert {"Generates.a.key.pair", "Genera un par de claves"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Genera un clave secreta"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_es extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Solicitud de certificaci\u00F3n almacenada en el archivo <{0}>"}, {"Submit.this.to.your.CA", "Enviar a la CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "si no se especifica el alias, no se puede especificar destalias, srckeypass ni destkeypass"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "si no se especifica el alias, no se debe especificar destalias ni srckeypass"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "El almac\u00E9n de claves pkcs12 de destino tiene storepass y keypass diferentes. Vuelva a intentarlo con -destkeypass especificado."}, {"Certificate.stored.in.file.filename.", "Certificado almacenado en el archivo <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_es extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "\u00BFA\u00FAn desea agregarlo a su propio almac\u00E9n de claves? [no]: "}, {"Trust.this.certificate.no.", "\u00BFConfiar en este certificado? [no]: "}, - {"YES", "S\u00ED"}, + {"YES", "S\u00CD"}, {"New.prompt.", "Nuevo {0}: "}, {"Passwords.must.differ", "Las contrase\u00F1as deben ser distintas"}, {"Re.enter.new.prompt.", "Vuelva a escribir el nuevo {0}: "}, @@ -361,7 +361,7 @@ public class Resources_es extends java.util.ListResourceBundle { "El alias <{0}> hace referencia a un tipo de entrada que no es una clave privada. El comando -keyclone s\u00F3lo permite la clonaci\u00F3n de entradas de claves privadas"}, {".WARNING.WARNING.WARNING.", - "***************** Advertencia Advertencia Advertencia *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "#%d de Firmante:"}, {"Timestamp.", "Registro de Hora:"}, {"Signature.", "Firma:"}, @@ -386,7 +386,7 @@ public class Resources_es extends java.util.ListResourceBundle { "Certificado de nivel superior en la respuesta:\n"}, {".is.not.trusted.", "... no es de confianza. "}, {"Install.reply.anyway.no.", "\u00BFInstalar respuesta de todos modos? [no]: "}, - {"NO", "No"}, + {"NO", "NO"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Las claves p\u00FAblicas en la respuesta y en el almac\u00E9n de claves no coinciden"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_es extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Proporcione el valor de -keysize para la generaci\u00F3n de claves secretas"}, + {"verified.by.s.in.s", "Verificado por %s en %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "ADVERTENCIA: no se ha verificado. Aseg\u00FArese de que el valor de -keystore es correcto."}, + {"Extensions.", "Extensiones: "}, {".Empty.value.", "(Valor vac\u00EDo)"}, {"Extension.Request.", "Solicitud de Extensi\u00F3n:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java index 2ae14764d79..aaa7c2e60d5 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java @@ -40,8 +40,7 @@ public class Resources_fr extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Option]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Options :"}, {"Use.keytool.help.for.all.available.commands", "Utiliser \"keytool -help\" pour toutes les commandes disponibles"}, @@ -61,7 +60,6 @@ public class Resources_fr extends java.util.ListResourceBundle { "Exporte le certificat"}, //-exportcert {"Generates.a.key.pair", "G\u00E9n\u00E8re une paire de cl\u00E9s"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "G\u00E9n\u00E8re une cl\u00E9 secr\u00E8te"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_fr extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Demande de certification stock\u00E9e dans le fichier <{0}>"}, {"Submit.this.to.your.CA", "Soumettre \u00E0 votre CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "si l'alias n'est pas sp\u00E9cifi\u00E9, destalias, srckeypass et destkeypass ne doivent pas \u00EAtre sp\u00E9cifi\u00E9s"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "si l'alias n'est pas sp\u00E9cifi\u00E9, destalias et srckeypass ne doivent pas \u00EAtre sp\u00E9cifi\u00E9s"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Le fichier de cl\u00E9s pkcs12 de destination contient un mot de passe de fichier de cl\u00E9s et un mot de passe de cl\u00E9 diff\u00E9rents. R\u00E9essayez en sp\u00E9cifiant -destkeypass."}, {"Certificate.stored.in.file.filename.", "Certificat stock\u00E9 dans le fichier <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_fr extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "Voulez-vous toujours l'ajouter \u00E0 votre fichier de cl\u00E9s ? [non] : "}, {"Trust.this.certificate.no.", "Faire confiance \u00E0 ce certificat ? [non] : "}, - {"YES", "Oui"}, + {"YES", "OUI"}, {"New.prompt.", "Nouveau {0} : "}, {"Passwords.must.differ", "Les mots de passe doivent diff\u00E9rer"}, {"Re.enter.new.prompt.", "Indiquez encore le nouveau {0} : "}, @@ -361,7 +361,7 @@ public class Resources_fr extends java.util.ListResourceBundle { "L''entr\u00E9e \u00E0 laquelle l''alias <{0}> fait r\u00E9f\u00E9rence n''est pas une entr\u00E9e de type cl\u00E9 priv\u00E9e. La commande -keyclone prend uniquement en charge le clonage des cl\u00E9s priv\u00E9es"}, {".WARNING.WARNING.WARNING.", - "***************** Avertissement Avertissement Avertissement *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signataire n\u00B0%d :"}, {"Timestamp.", "Horodatage :"}, {"Signature.", "Signature :"}, @@ -386,7 +386,7 @@ public class Resources_fr extends java.util.ListResourceBundle { "Certificat de niveau sup\u00E9rieur dans la r\u00E9ponse :\n"}, {".is.not.trusted.", "... non s\u00E9curis\u00E9. "}, {"Install.reply.anyway.no.", "Installer la r\u00E9ponse quand m\u00EAme ? [non] : "}, - {"NO", "Non"}, + {"NO", "NON"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Les cl\u00E9s publiques de la r\u00E9ponse et du fichier de cl\u00E9s ne concordent pas"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_fr extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Indiquez -keysize pour la g\u00E9n\u00E9ration de la cl\u00E9 secr\u00E8te"}, + {"verified.by.s.in.s", "V\u00E9rifi\u00E9 par %s dans %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "AVERTISSEMENT : non v\u00E9rifi\u00E9. Assurez-vous que -keystore est correct."}, + {"Extensions.", "Extensions\u00A0: "}, {".Empty.value.", "(Valeur vide)"}, {"Extension.Request.", "Demande d'extension :"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java index 0557fdc0943..a47c97fab2a 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java @@ -40,8 +40,7 @@ public class Resources_it extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Opzione]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Opzioni:"}, {"Use.keytool.help.for.all.available.commands", "Utilizzare \"keytool -help\" per visualizzare tutti i comandi disponibili"}, @@ -61,7 +60,6 @@ public class Resources_it extends java.util.ListResourceBundle { "Esporta il certificato"}, //-exportcert {"Generates.a.key.pair", "Genera una coppia di chiavi"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Genera una chiave segreta"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_it extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "La richiesta di certificazione \u00E8 memorizzata nel file <{0}>"}, {"Submit.this.to.your.CA", "Sottomettere alla propria CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "Se l'alias non \u00E8 specificato, destalias, srckeypass e destkeypass non dovranno essere specificati"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "Se l'alias non \u00E8 specificato, destalias e srckeypass non dovranno essere specificati"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Keystore pkcs12 di destinazione con storepass e keypass differenti. Riprovare con -destkeypass specificato."}, {"Certificate.stored.in.file.filename.", "Il certificato \u00E8 memorizzato nel file <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_it extends java.util.ListResourceBundle { "L''alias <{0}> fa riferimento a un tipo di voce che non \u00E8 una voce di chiave privata. Il comando -keyclone supporta solo la copia delle voci di chiave private."}, {".WARNING.WARNING.WARNING.", - "***************** Avvertenza Avvertenza Avvertenza *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Firmatario #%d:"}, {"Timestamp.", "Indicatore orario:"}, {"Signature.", "Firma:"}, @@ -386,7 +386,7 @@ public class Resources_it extends java.util.ListResourceBundle { "Certificato di primo livello nella risposta:\n"}, {".is.not.trusted.", "...non \u00E8 considerato sicuro. "}, {"Install.reply.anyway.no.", "Installare la risposta? [no]: "}, - {"NO", "No"}, + {"NO", "NO"}, {"Public.keys.in.reply.and.keystore.don.t.match", "Le chiavi pubbliche nella risposta e nel keystore non corrispondono"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_it extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Specificare il valore -keysize per la generazione della chiave segreta"}, + {"verified.by.s.in.s", "Verificato da %s in %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "AVVERTENZA: non verificato. Assicurarsi che -keystore sia corretto."}, + {"Extensions.", "Estensioni: "}, {".Empty.value.", "(valore vuoto)"}, {"Extension.Request.", "Richiesta di estensione:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java index 9b6e6be1cf6..b40b046f06c 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java @@ -40,8 +40,7 @@ public class Resources_ja extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\u30AA\u30D7\u30B7\u30E7\u30F3]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\u30AA\u30D7\u30B7\u30E7\u30F3:"}, {"Use.keytool.help.for.all.available.commands", "\u4F7F\u7528\u53EF\u80FD\u306A\u3059\u3079\u3066\u306E\u30B3\u30DE\u30F3\u30C9\u306B\u3064\u3044\u3066\u306F\"keytool -help\"\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044"}, @@ -61,7 +60,6 @@ public class Resources_ja extends java.util.ListResourceBundle { "\u8A3C\u660E\u66F8\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3057\u307E\u3059"}, //-exportcert {"Generates.a.key.pair", "\u9375\u30DA\u30A2\u3092\u751F\u6210\u3057\u307E\u3059"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "\u79D8\u5BC6\u9375\u3092\u751F\u6210\u3057\u307E\u3059"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_ja extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "\u8A3C\u660E\u66F8\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u30D5\u30A1\u30A4\u30EB<{0}>\u306B\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F"}, {"Submit.this.to.your.CA", "\u3053\u308C\u3092CA\u306B\u63D0\u51FA\u3057\u3066\u304F\u3060\u3055\u3044"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\u5225\u540D\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001\u51FA\u529B\u5148\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5225\u540D\u3001\u30BD\u30FC\u30B9\u30FB\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u304A\u3088\u3073\u51FA\u529B\u5148\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\u5225\u540D\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001\u51FA\u529B\u5148\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5225\u540D\u304A\u3088\u3073\u30BD\u30FC\u30B9\u30FB\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\u51FA\u529B\u5148pkcs12\u30AD\u30FC\u30B9\u30C8\u30A2\u306B\u3001\u7570\u306A\u308Bstorepass\u304A\u3088\u3073keypass\u304C\u3042\u308A\u307E\u3059\u3002-destkeypass\u3092\u6307\u5B9A\u3057\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002"}, {"Certificate.stored.in.file.filename.", "\u8A3C\u660E\u66F8\u304C\u30D5\u30A1\u30A4\u30EB<{0}>\u306B\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F"}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_ja extends java.util.ListResourceBundle { "\u5225\u540D<{0}>\u304C\u53C2\u7167\u3057\u3066\u3044\u308B\u30A8\u30F3\u30C8\u30EA\u30FB\u30BF\u30A4\u30D7\u306F\u79D8\u5BC6\u9375\u30A8\u30F3\u30C8\u30EA\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002-keyclone\u30B3\u30DE\u30F3\u30C9\u306F\u79D8\u5BC6\u9375\u30A8\u30F3\u30C8\u30EA\u306E\u30AF\u30ED\u30FC\u30F3\u4F5C\u6210\u306E\u307F\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059"}, {".WARNING.WARNING.WARNING.", - "*****************\u8B66\u544A \u8B66\u544A \u8B66\u544A*****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\u7F72\u540D\u8005\u756A\u53F7%d:"}, {"Timestamp.", "\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7:"}, {"Signature.", "\u7F72\u540D:"}, @@ -400,6 +400,10 @@ public class Resources_ja extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "\u79D8\u5BC6\u9375\u306E\u751F\u6210\u6642\u306B\u306F -keysize\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"}, + {"verified.by.s.in.s", "%s(%s\u5185)\u306B\u3088\u308A\u691C\u8A3C\u3055\u308C\u307E\u3057\u305F"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\u8B66\u544A: \u691C\u8A3C\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002-keystore\u304C\u6B63\u3057\u3044\u3053\u3068\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002"}, + {"Extensions.", "\u62E1\u5F35: "}, {".Empty.value.", "(\u7A7A\u306E\u5024)"}, {"Extension.Request.", "\u62E1\u5F35\u30EA\u30AF\u30A8\u30B9\u30C8:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java index 9f3f70f5024..6140bc722c0 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java @@ -40,8 +40,7 @@ public class Resources_ko extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\uC635\uC158]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\uC635\uC158:"}, {"Use.keytool.help.for.all.available.commands", "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA8\uB4E0 \uBA85\uB839\uC5D0 \"keytool -help\" \uC0AC\uC6A9"}, @@ -61,7 +60,6 @@ public class Resources_ko extends java.util.ListResourceBundle { "\uC778\uC99D\uC11C\uB97C \uC775\uC2A4\uD3EC\uD2B8\uD569\uB2C8\uB2E4."}, //-exportcert {"Generates.a.key.pair", "\uD0A4 \uC30D\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4."}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "\uBCF4\uC548 \uD0A4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4."}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -174,7 +172,7 @@ public class Resources_ko extends java.util.ListResourceBundle { "\uCCA0\uD68C\uD560 \uC778\uC99D\uC11C\uC758 \uC77C\uB828 ID"}, //-id // keytool: Running part {"keytool.error.", "keytool \uC624\uB958: "}, - {"Illegal.option.", "\uC798\uBABB\uB41C \uC635\uC158: "}, + {"Illegal.option.", "\uC798\uBABB\uB41C \uC635\uC158: "}, {"Illegal.value.", "\uC798\uBABB\uB41C \uAC12: "}, {"Unknown.password.type.", "\uC54C \uC218 \uC5C6\uB294 \uBE44\uBC00\uBC88\uD638 \uC720\uD615: "}, {"Cannot.find.environment.variable.", @@ -244,8 +242,10 @@ public class Resources_ko extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "\uC778\uC99D \uC694\uCCAD\uC774 <{0}> \uD30C\uC77C\uC5D0 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."}, {"Submit.this.to.your.CA", "CA\uC5D0\uAC8C \uC81C\uCD9C\uD558\uC2ED\uC2DC\uC624."}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC9C0 \uC54A\uC740 \uACBD\uC6B0 destalias, srckeypass \uBC0F destkeypass\uB97C \uC9C0\uC815\uD558\uC9C0 \uC54A\uC544\uC57C \uD569\uB2C8\uB2E4."}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\uBCC4\uCE6D\uC744 \uC9C0\uC815\uD558\uC9C0 \uC54A\uC740 \uACBD\uC6B0 destalias \uBC0F srckeypass\uB97C \uC9C0\uC815\uD558\uC9C0 \uC54A\uC544\uC57C \uD569\uB2C8\uB2E4."}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\uB300\uC0C1 pkcs12 \uD0A4 \uC800\uC7A5\uC18C\uC5D0 \uB2E4\uB978 storepass \uBC0F keypass\uAC00 \uC788\uC2B5\uB2C8\uB2E4. \uC9C0\uC815\uB41C -destkeypass\uB85C \uC7AC\uC2DC\uB3C4\uD558\uC2ED\uC2DC\uC624."}, {"Certificate.stored.in.file.filename.", "\uC778\uC99D\uC11C\uAC00 <{0}> \uD30C\uC77C\uC5D0 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4."}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_ko extends java.util.ListResourceBundle { "<{0}> \uBCC4\uCE6D\uC740 \uC804\uC6A9 \uD0A4 \uD56D\uBAA9\uC774 \uC544\uB2CC \uD56D\uBAA9 \uC720\uD615\uC744 \uCC38\uC870\uD569\uB2C8\uB2E4. -keyclone \uBA85\uB839\uC740 \uC804\uC6A9 \uD0A4 \uD56D\uBAA9\uC758 \uBCF5\uC81C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4."}, {".WARNING.WARNING.WARNING.", - "***************** \uACBD\uACE0 \uACBD\uACE0 \uACBD\uACE0 *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\uC11C\uBA85\uC790 #%d:"}, {"Timestamp.", "\uC2DC\uAC04 \uAE30\uB85D:"}, {"Signature.", "\uC11C\uBA85:"}, @@ -400,6 +400,10 @@ public class Resources_ko extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "\uBCF4\uC548 \uD0A4\uB97C \uC0DD\uC131\uD558\uB824\uBA74 -keysize\uB97C \uC81C\uACF5\uD558\uC2ED\uC2DC\uC624."}, + {"verified.by.s.in.s", "%s(%s)\uC5D0 \uC758\uD574 \uD655\uC778\uB428"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\uACBD\uACE0: \uD655\uC778\uB418\uC9C0 \uC54A\uC74C. -keystore\uAC00 \uC62C\uBC14\uB978\uC9C0 \uD655\uC778\uD558\uC2ED\uC2DC\uC624."}, + {"Extensions.", "\uD655\uC7A5: "}, {".Empty.value.", "(\uBE44\uC5B4 \uC788\uB294 \uAC12)"}, {"Extension.Request.", "\uD655\uC7A5 \uC694\uCCAD:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java index 50b4d26067e..0080342146b 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java @@ -40,8 +40,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Op\u00E7\u00E3o]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Op\u00E7\u00F5es:"}, {"Use.keytool.help.for.all.available.commands", "Use \"keytool -help\" para todos os comandos dispon\u00EDveis"}, @@ -61,9 +60,8 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "Exporta o certificado"}, //-exportcert {"Generates.a.key.pair", "Gera um par de chaves"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", - "Gera uma chave Secreta"}, //-genseckey + "Gera uma chave secreta"}, //-genseckey {"Generates.certificate.from.a.certificate.request", "Gera um certificado de uma solicita\u00E7\u00E3o de certificado"}, //-gencert {"Generates.CRL", "Gera CRL"}, //-gencrl @@ -244,8 +242,10 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Solicita\u00E7\u00E3o de certificado armazenada no arquivo <{0}>"}, {"Submit.this.to.your.CA", "Submeter \u00E0 CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "se o alias n\u00E3o estiver especificado, destalias, srckeypass e destkeypass n\u00E3o dever\u00E3o ser especificados"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "se o alias n\u00E3o estiver especificado, destalias e srckeypass n\u00E3o dever\u00E3o ser especificados"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "O armazenamento de chaves pkcs12 de destino tem storepass e keypass diferentes. Tente novamente especificando -destkeypass."}, {"Certificate.stored.in.file.filename.", "Certificado armazenado no arquivo <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -298,14 +298,14 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Entry.type.type.", "Tipo de entrada: {0}"}, {"Certificate.chain.length.", "Comprimento da cadeia de certificados: "}, {"Certificate.i.1.", "Certificado[{0,number,integer}]:"}, - {"Certificate.fingerprint.SHA1.", "Fingerprint (MD5) do certificado: "}, + {"Certificate.fingerprint.SHA1.", "Fingerprint (SHA1) do certificado: "}, {"Keystore.type.", "Tipo de \u00E1rea de armazenamento de chaves: "}, {"Keystore.provider.", "Fornecedor da \u00E1rea de armazenamento de chaves: "}, {"Your.keystore.contains.keyStore.size.entry", "Sua \u00E1rea de armazenamento de chaves cont\u00E9m {0,number,integer} entrada"}, {"Your.keystore.contains.keyStore.size.entries", "Sua \u00E1rea de armazenamento de chaves cont\u00E9m {0,number,integer} entradas"}, - {"Failed.to.parse.input", "Falha durante o parse da entrada"}, + {"Failed.to.parse.input", "Falha durante o parsing da entrada"}, {"Empty.input", "Entrada vazia"}, {"Not.X.509.certificate", "N\u00E3o \u00E9 um certificado X.509"}, {"alias.has.no.public.key", "{0} n\u00E3o tem chave p\u00FAblica"}, @@ -324,7 +324,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "Ainda deseja adicion\u00E1-lo \u00E0 sua \u00E1rea de armazenamento de chaves? [n\u00E3o]: "}, {"Trust.this.certificate.no.", "Confiar neste certificado? [n\u00E3o]: "}, - {"YES", "Sim"}, + {"YES", "SIM"}, {"New.prompt.", "Nova {0}: "}, {"Passwords.must.differ", "As senhas devem ser diferentes"}, {"Re.enter.new.prompt.", "Informe novamente a nova {0}: "}, @@ -361,7 +361,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "O alias <{0}> faz refer\u00EAncia a um tipo de entrada que n\u00E3o \u00E9 uma entrada de chave privada. O comando -keyclone oferece suporte somente \u00E0 clonagem de entradas de chave privada"}, {".WARNING.WARNING.WARNING.", - "***************** Advert\u00EAncia Advert\u00EAncia Advert\u00EAncia *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signat\u00E1rio #%d:"}, {"Timestamp.", "Timestamp:"}, {"Signature.", "Assinatura:"}, @@ -386,7 +386,7 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { "Certificado de n\u00EDvel superior na resposta:\n"}, {".is.not.trusted.", "... n\u00E3o \u00E9 confi\u00E1vel. "}, {"Install.reply.anyway.no.", "Instalar resposta assim mesmo? [n\u00E3o]: "}, - {"NO", "N\u00E3o"}, + {"NO", "N\u00C3O"}, {"Public.keys.in.reply.and.keystore.don.t.match", "As chaves p\u00FAblicas da resposta e da \u00E1rea de armazenamento de chaves n\u00E3o correspondem"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Forne\u00E7a o -keysize para a gera\u00E7\u00E3o da chave secreta"}, + {"verified.by.s.in.s", "Verificado por %s em %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "ADVERT\u00CANCIA: n\u00E3o verificado. Certifique-se que -keystore esteja correto."}, + {"Extensions.", "Extens\u00F5es: "}, {".Empty.value.", "(Valor vazio)"}, {"Extension.Request.", "Solicita\u00E7\u00E3o de Extens\u00E3o:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java index a4727e64c88..7c2aa3cba43 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java @@ -40,8 +40,7 @@ public class Resources_sv extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [Alternativ]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "Alternativ:"}, {"Use.keytool.help.for.all.available.commands", "L\u00E4s \"Hj\u00E4lp - Nyckelverktyg\" f\u00F6r alla tillg\u00E4ngliga kommandon"}, @@ -61,7 +60,6 @@ public class Resources_sv extends java.util.ListResourceBundle { "Exporterar certifikat"}, //-exportcert {"Generates.a.key.pair", "Genererar nyckelpar"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "Genererar hemlig nyckel"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -178,7 +176,7 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Illegal.value.", "Otill\u00E5tet v\u00E4rde: "}, {"Unknown.password.type.", "Ok\u00E4nd l\u00F6senordstyp: "}, {"Cannot.find.environment.variable.", - "Kan inte hitta milj\u00F6variabel: "}, + "Hittar inte milj\u00F6variabel: "}, {"Cannot.find.file.", "Hittar inte fil: "}, {"Command.option.flag.needs.an.argument.", "Kommandoalternativet {0} beh\u00F6ver ett argument."}, {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.", @@ -244,8 +242,10 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "Certifikatbeg\u00E4ran har lagrats i filen <{0}>"}, {"Submit.this.to.your.CA", "Skicka detta till certifikatutf\u00E4rdaren"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "om n\u00E5got alias inte anges f\u00E5r destalias, srckeypass och destkeypass inte anges"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "om alias inte angivits ska inte heller destalias och srckeypass anges"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "Destinationsnyckellagret pkcs12 har olika storepass och keypass. F\u00F6rs\u00F6k igen med -destkeypass angivet."}, {"Certificate.stored.in.file.filename.", "Certifikatet har lagrats i filen <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -324,7 +324,7 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", "Vill du fortfarande l\u00E4gga till det i ditt eget nyckellagret? [nej]: "}, {"Trust.this.certificate.no.", "Litar du p\u00E5 det h\u00E4r certifikatet? [nej]: "}, - {"YES", "Ja"}, + {"YES", "JA"}, {"New.prompt.", "Nytt {0}: "}, {"Passwords.must.differ", "L\u00F6senorden m\u00E5ste vara olika"}, {"Re.enter.new.prompt.", "Ange nytt {0} igen: "}, @@ -361,7 +361,7 @@ public class Resources_sv extends java.util.ListResourceBundle { "Aliaset <{0}> refererar till en posttyp som inte \u00E4r n\u00E5gon privat nyckelpost. Kommandot -keyclone har endast st\u00F6d f\u00F6r kloning av privata nyckelposter"}, {".WARNING.WARNING.WARNING.", - "***************** Varning Varning Varning *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "Signerare #%d:"}, {"Timestamp.", "Tidsst\u00E4mpel:"}, {"Signature.", "Underskrift:"}, @@ -386,7 +386,7 @@ public class Resources_sv extends java.util.ListResourceBundle { "Toppniv\u00E5certifikatet i svaret:\n"}, {".is.not.trusted.", "... \u00E4r inte betrott. "}, {"Install.reply.anyway.no.", "Vill du installera svaret \u00E4nd\u00E5? [nej]: "}, - {"NO", "Nej"}, + {"NO", "NEJ"}, {"Public.keys.in.reply.and.keystore.don.t.match", "De offentliga nycklarna i svaret och nyckellagret matchar inte varandra"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -400,6 +400,10 @@ public class Resources_sv extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "Ange -keysize f\u00F6r att skapa hemlig nyckel"}, + {"verified.by.s.in.s", "Verifierad av %s i %s"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "VARNING: ej verifierad. Se till att -nyckellager \u00E4r korrekt."}, + {"Extensions.", "Till\u00E4gg: "}, {".Empty.value.", "(Tomt v\u00E4rde)"}, {"Extension.Request.", "Till\u00E4ggsbeg\u00E4ran:"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java index 6836bd769f9..814e0fe78c2 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java @@ -40,8 +40,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\u9009\u9879]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\u9009\u9879:"}, {"Use.keytool.help.for.all.available.commands", "\u4F7F\u7528 \"keytool -help\" \u83B7\u53D6\u6240\u6709\u53EF\u7528\u547D\u4EE4"}, @@ -61,9 +60,8 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u5BFC\u51FA\u8BC1\u4E66"}, //-exportcert {"Generates.a.key.pair", "\u751F\u6210\u5BC6\u94A5\u5BF9"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", - "\u751F\u6210\u5BF9\u79F0\u5BC6\u94A5"}, //-genseckey + "\u751F\u6210\u5BC6\u94A5"}, //-genseckey {"Generates.certificate.from.a.certificate.request", "\u6839\u636E\u8BC1\u4E66\u8BF7\u6C42\u751F\u6210\u8BC1\u4E66"}, //-gencert {"Generates.CRL", "\u751F\u6210 CRL"}, //-gencrl @@ -182,7 +180,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Cannot.find.file.", "\u627E\u4E0D\u5230\u6587\u4EF6: "}, {"Command.option.flag.needs.an.argument.", "\u547D\u4EE4\u9009\u9879{0}\u9700\u8981\u4E00\u4E2A\u53C2\u6570\u3002"}, {"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.", - "\u8B66\u544A: PKCS12 KeyStore \u4E0D\u652F\u6301\u5176\u4ED6\u5B58\u50A8\u548C\u5BC6\u94A5\u53E3\u4EE4\u3002\u6B63\u5728\u5FFD\u7565\u7528\u6237\u6307\u5B9A\u7684{0}\u503C\u3002"}, + "\u8B66\u544A: PKCS12 \u5BC6\u94A5\u5E93\u4E0D\u652F\u6301\u5176\u4ED6\u5B58\u50A8\u548C\u5BC6\u94A5\u53E3\u4EE4\u3002\u6B63\u5728\u5FFD\u7565\u7528\u6237\u6307\u5B9A\u7684{0}\u503C\u3002"}, {".keystore.must.be.NONE.if.storetype.is.{0}", "\u5982\u679C -storetype \u4E3A {0}, \u5219 -keystore \u5FC5\u987B\u4E3A NONE"}, {"Too.many.retries.program.terminated", @@ -203,13 +201,13 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u5982\u679C\u6E90\u5BC6\u94A5\u5E93\u672A\u53D7\u53E3\u4EE4\u4FDD\u62A4, \u5219\u4E0D\u80FD\u6307\u5B9A -srcstorepass \u548C -srckeypass"}, {"Illegal.startdate.value", "\u975E\u6CD5\u5F00\u59CB\u65E5\u671F\u503C"}, {"Validity.must.be.greater.than.zero", - "\u6709\u6548\u671F\u5FC5\u987B\u5927\u4E8E\u96F6"}, + "\u6709\u6548\u6027\u5FC5\u987B\u5927\u4E8E\u96F6"}, {"provName.not.a.provider", "{0}\u4E0D\u662F\u63D0\u4F9B\u65B9"}, {"Usage.error.no.command.provided", "\u7528\u6CD5\u9519\u8BEF: \u6CA1\u6709\u63D0\u4F9B\u547D\u4EE4"}, {"Source.keystore.file.exists.but.is.empty.", "\u6E90\u5BC6\u94A5\u5E93\u6587\u4EF6\u5B58\u5728, \u4F46\u4E3A\u7A7A: "}, {"Please.specify.srckeystore", "\u8BF7\u6307\u5B9A -srckeystore"}, {"Must.not.specify.both.v.and.rfc.with.list.command", - "'list' \u547D\u4EE4\u4E0D\u80FD\u540C\u65F6\u6307\u5B9A -v \u53CA -rfc"}, + "\u4E0D\u80FD\u4F7F\u7528 'list' \u547D\u4EE4\u6765\u6307\u5B9A -v \u53CA -rfc"}, {"Key.password.must.be.at.least.6.characters", "\u5BC6\u94A5\u53E3\u4EE4\u81F3\u5C11\u5FC5\u987B\u4E3A 6 \u4E2A\u5B57\u7B26"}, {"New.password.must.be.at.least.6.characters", @@ -239,13 +237,15 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Warning.Overwriting.existing.alias.alias.in.destination.keystore", "\u8B66\u544A: \u6B63\u5728\u8986\u76D6\u76EE\u6807\u5BC6\u94A5\u5E93\u4E2D\u7684\u73B0\u6709\u522B\u540D {0}"}, {"Existing.entry.alias.alias.exists.overwrite.no.", - "\u5B58\u5728\u73B0\u6709\u6761\u76EE\u522B\u540D {0}, \u662F\u5426\u8986\u76D6? [no]: "}, + "\u5B58\u5728\u73B0\u6709\u6761\u76EE\u522B\u540D {0}, \u662F\u5426\u8986\u76D6? [\u5426]: "}, {"Too.many.failures.try.later", "\u6545\u969C\u592A\u591A - \u8BF7\u7A0D\u540E\u518D\u8BD5"}, {"Certification.request.stored.in.file.filename.", "\u5B58\u50A8\u5728\u6587\u4EF6 <{0}> \u4E2D\u7684\u8BA4\u8BC1\u8BF7\u6C42"}, {"Submit.this.to.your.CA", "\u5C06\u6B64\u63D0\u4EA4\u7ED9\u60A8\u7684 CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\u5982\u679C\u6CA1\u6709\u6307\u5B9A\u522B\u540D, \u5219\u4E0D\u80FD\u6307\u5B9A\u76EE\u6807\u522B\u540D, \u6E90\u5BC6\u94A5\u5E93\u53E3\u4EE4\u548C\u76EE\u6807\u5BC6\u94A5\u5E93\u53E3\u4EE4"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\u5982\u679C\u6CA1\u6709\u6307\u5B9A\u522B\u540D, \u5219\u4E0D\u80FD\u6307\u5B9A\u76EE\u6807\u522B\u540D\u548C\u6E90\u5BC6\u94A5\u5E93\u53E3\u4EE4"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\u76EE\u6807 pkcs12 \u5BC6\u94A5\u5E93\u5177\u6709\u4E0D\u540C\u7684 storepass \u548C keypass\u3002\u8BF7\u5728\u6307\u5B9A\u4E86 -destkeypass \u65F6\u91CD\u8BD5\u3002"}, {"Certificate.stored.in.file.filename.", "\u5B58\u50A8\u5728\u6587\u4EF6 <{0}> \u4E2D\u7684\u8BC1\u4E66"}, {"Certificate.reply.was.installed.in.keystore", @@ -305,7 +305,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u60A8\u7684\u5BC6\u94A5\u5E93\u5305\u542B {0,number,integer} \u4E2A\u6761\u76EE"}, {"Your.keystore.contains.keyStore.size.entries", "\u60A8\u7684\u5BC6\u94A5\u5E93\u5305\u542B {0,number,integer} \u4E2A\u6761\u76EE"}, - {"Failed.to.parse.input", "\u65E0\u6CD5\u5BF9\u8F93\u5165\u8FDB\u884C\u8BED\u6CD5\u5206\u6790"}, + {"Failed.to.parse.input", "\u65E0\u6CD5\u89E3\u6790\u8F93\u5165"}, {"Empty.input", "\u7A7A\u8F93\u5165"}, {"Not.X.509.certificate", "\u975E X.509 \u8BC1\u4E66"}, {"alias.has.no.public.key", "{0}\u6CA1\u6709\u516C\u5171\u5BC6\u94A5"}, @@ -318,13 +318,13 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Certificate.already.exists.in.keystore.under.alias.trustalias.", "\u5728\u522B\u540D <{0}> \u4E4B\u4E0B, \u8BC1\u4E66\u5DF2\u7ECF\u5B58\u5728\u4E8E\u5BC6\u94A5\u5E93\u4E2D"}, {"Do.you.still.want.to.add.it.no.", - "\u662F\u5426\u4ECD\u8981\u6DFB\u52A0? [no]: "}, + "\u662F\u5426\u4ECD\u8981\u6DFB\u52A0? [\u5426]: "}, {"Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias.", "\u5728\u522B\u540D <{0}> \u4E4B\u4E0B, \u8BC1\u4E66\u5DF2\u7ECF\u5B58\u5728\u4E8E\u7CFB\u7EDF\u8303\u56F4\u7684 CA \u5BC6\u94A5\u5E93\u4E2D"}, {"Do.you.still.want.to.add.it.to.your.own.keystore.no.", - "\u662F\u5426\u4ECD\u8981\u5C06\u5B83\u6DFB\u52A0\u5230\u81EA\u5DF1\u7684\u5BC6\u94A5\u5E93? [no]: "}, - {"Trust.this.certificate.no.", "\u662F\u5426\u4FE1\u4EFB\u6B64\u8BC1\u4E66? [no]: "}, - {"YES", "\u662F"}, + "\u662F\u5426\u4ECD\u8981\u5C06\u5B83\u6DFB\u52A0\u5230\u81EA\u5DF1\u7684\u5BC6\u94A5\u5E93? [\u5426]: "}, + {"Trust.this.certificate.no.", "\u662F\u5426\u4FE1\u4EFB\u6B64\u8BC1\u4E66? [\u5426]: "}, + {"YES", "YES"}, {"New.prompt.", "\u65B0{0}: "}, {"Passwords.must.differ", "\u53E3\u4EE4\u4E0D\u80FD\u76F8\u540C"}, {"Re.enter.new.prompt.", "\u91CD\u65B0\u8F93\u5165\u65B0{0}: "}, @@ -332,7 +332,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"They.don.t.match.Try.again", "\u5B83\u4EEC\u4E0D\u5339\u914D\u3002\u8BF7\u91CD\u8BD5"}, {"Enter.prompt.alias.name.", "\u8F93\u5165{0}\u522B\u540D: "}, {"Enter.new.alias.name.RETURN.to.cancel.import.for.this.entry.", - "\u8F93\u5165\u65B0\u7684\u522B\u540D\t(\u6309\u56DE\u8F66\u4EE5\u53D6\u6D88\u5BF9\u6B64\u6761\u76EE\u7684\u5BFC\u5165): "}, + "\u5BFC\u5165\u65B0\u7684\u522B\u540D\t(\u6309\u56DE\u8F66\u4EE5\u53D6\u6D88\u5BF9\u6B64\u6761\u76EE\u7684\u5BFC\u5165): "}, {"Enter.alias.name.", "\u8F93\u5165\u522B\u540D: "}, {".RETURN.if.same.as.for.otherAlias.", "\t(\u5982\u679C\u548C <{0}> \u76F8\u540C, \u5219\u6309\u56DE\u8F66)"}, @@ -361,7 +361,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { "\u522B\u540D <{0}> \u5F15\u7528\u4E86\u4E0D\u5C5E\u4E8E\u79C1\u6709\u5BC6\u94A5\u6761\u76EE\u7684\u6761\u76EE\u7C7B\u578B\u3002-keyclone \u547D\u4EE4\u4EC5\u652F\u6301\u5BF9\u79C1\u6709\u5BC6\u94A5\u6761\u76EE\u7684\u514B\u9686"}, {".WARNING.WARNING.WARNING.", - "***************** \u8B66\u544A \u8B66\u544A \u8B66\u544A *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\u7B7E\u540D\u8005 #%d:"}, {"Timestamp.", "\u65F6\u95F4\u6233:"}, {"Signature.", "\u7B7E\u540D:"}, @@ -385,8 +385,8 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Top.level.certificate.in.reply.", "\u56DE\u590D\u4E2D\u7684\u9876\u7EA7\u8BC1\u4E66:\n"}, {".is.not.trusted.", "... \u662F\u4E0D\u53EF\u4FE1\u7684\u3002"}, - {"Install.reply.anyway.no.", "\u662F\u5426\u4ECD\u8981\u5B89\u88C5\u56DE\u590D? [no]: "}, - {"NO", "\u5426"}, + {"Install.reply.anyway.no.", "\u662F\u5426\u4ECD\u8981\u5B89\u88C5\u56DE\u590D? [\u5426]: "}, + {"NO", "NO"}, {"Public.keys.in.reply.and.keystore.don.t.match", "\u56DE\u590D\u4E2D\u7684\u516C\u5171\u5BC6\u94A5\u4E0E\u5BC6\u94A5\u5E93\u4E0D\u5339\u914D"}, {"Certificate.reply.and.certificate.in.keystore.are.identical", @@ -398,7 +398,11 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Secret.key.not.generated.alias.alias.already.exists", "\u6CA1\u6709\u751F\u6210\u5BC6\u94A5, \u522B\u540D <{0}> \u5DF2\u7ECF\u5B58\u5728"}, {"Please.provide.keysize.for.secret.key.generation", - "\u8BF7\u63D0\u4F9B -keysize \u4EE5\u751F\u6210\u5BF9\u79F0\u5BC6\u94A5"}, + "\u8BF7\u63D0\u4F9B -keysize \u4EE5\u751F\u6210\u5BC6\u94A5"}, + + {"verified.by.s.in.s", "\u7531 %s \u9A8C\u8BC1(\u5728 %s \u4E2D)"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\u8B66\u544A: \u672A\u9A8C\u8BC1\u3002\u8BF7\u786E\u4FDD\u5BC6\u94A5\u5E93\u662F\u6B63\u786E\u7684\u3002"}, {"Extensions.", "\u6269\u5C55: "}, {".Empty.value.", "(\u7A7A\u503C)"}, diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java index 2c7bdf5e1b7..0b6afb8a74f 100644 --- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java +++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java @@ -40,8 +40,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { "*******************************************\n\n"}, // keytool: Help part -// "Option" should be translated. - {".OPTION.", " [\u9078\u9805]..."}, + {".OPTION.", " [OPTION]..."}, {"Options.", "\u9078\u9805:"}, {"Use.keytool.help.for.all.available.commands", "\u4F7F\u7528 \"keytool -help\" \u53D6\u5F97\u6240\u6709\u53EF\u7528\u7684\u547D\u4EE4"}, @@ -61,7 +60,6 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { "\u532F\u51FA\u6191\u8B49"}, //-exportcert {"Generates.a.key.pair", "\u7522\u751F\u91D1\u9470\u7D44"}, //-genkeypair -// translation of "secret" key should be different to "private" key. {"Generates.a.secret.key", "\u7522\u751F\u79D8\u5BC6\u91D1\u9470"}, //-genseckey {"Generates.certificate.from.a.certificate.request", @@ -244,8 +242,10 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"Certification.request.stored.in.file.filename.", "\u8A8D\u8B49\u8981\u6C42\u5132\u5B58\u5728\u6A94\u6848 <{0}>"}, {"Submit.this.to.your.CA", "\u5C07\u6B64\u9001\u51FA\u81F3\u60A8\u7684 CA"}, - {"if.alias.not.specified.destalias.srckeypass.and.destkeypass.must.not.be.specified", - "\u5982\u679C\u672A\u6307\u5B9A\u5225\u540D\uFF0C\u5247\u4E0D\u80FD\u6307\u5B9A destalias\u3001srckeypass \u53CA destkeypass"}, + {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified", + "\u5982\u679C\u672A\u6307\u5B9A\u5225\u540D\uFF0C\u5247\u4E0D\u80FD\u6307\u5B9A destalias \u548C srckeypass"}, + {"The.destination.pkcs12.keystore.has.different.storepass.and.keypass.Please.retry.with.destkeypass.specified.", + "\u76EE\u7684\u5730 pkcs12 \u91D1\u9470\u5132\u5B58\u5EAB\u7684 storepass \u548C keypass \u4E0D\u540C\u3002\u8ACB\u91CD\u65B0\u4EE5 -destkeypass \u6307\u5B9A\u3002"}, {"Certificate.stored.in.file.filename.", "\u6191\u8B49\u5132\u5B58\u5728\u6A94\u6848 <{0}>"}, {"Certificate.reply.was.installed.in.keystore", @@ -361,7 +361,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { "\u5225\u540D <{0}> \u6240\u53C3\u7167\u7684\u9805\u76EE\u4E0D\u662F\u79C1\u5BC6\u91D1\u9470\u985E\u578B\u3002-keyclone \u547D\u4EE4\u50C5\u652F\u63F4\u79C1\u5BC6\u91D1\u9470\u9805\u76EE\u7684\u8907\u88FD"}, {".WARNING.WARNING.WARNING.", - "***************** \u8B66\u544A \u8B66\u544A \u8B66\u544A *****************"}, + "***************** WARNING WARNING WARNING *****************"}, {"Signer.d.", "\u7C3D\u7F72\u8005 #%d:"}, {"Timestamp.", "\u6642\u6233:"}, {"Signature.", "\u7C3D\u7AE0:"}, @@ -383,7 +383,7 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"Certificate.chain.in.reply.does.not.verify.", "\u56DE\u8986\u6642\u7684\u6191\u8B49\u93C8\u672A\u9A57\u8B49: "}, {"Top.level.certificate.in.reply.", - "\u56DE\u8986\u6642\u7684\u6700\u9AD8\u7D1A\u6191\u8B49:\\n"}, + "\u56DE\u8986\u6642\u7684\u6700\u9AD8\u7D1A\u6191\u8B49:\n"}, {".is.not.trusted.", "... \u662F\u4E0D\u88AB\u4FE1\u4EFB\u7684\u3002"}, {"Install.reply.anyway.no.", "\u9084\u662F\u8981\u5B89\u88DD\u56DE\u8986\uFF1F [\u5426]: "}, {"NO", "\u5426"}, @@ -400,6 +400,10 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"Please.provide.keysize.for.secret.key.generation", "\u8ACB\u63D0\u4F9B -keysize \u4EE5\u7522\u751F\u79D8\u5BC6\u91D1\u9470"}, + {"verified.by.s.in.s", "\u7531 %s \u9A57\u8B49 (\u5728 %s \u4E2D)"}, + {"warning.not.verified.make.sure.keystore.is.correct", + "\u8B66\u544A: \u672A\u9A57\u8B49\u3002\u8ACB\u78BA\u5B9A -keystore \u6B63\u78BA\u3002"}, + {"Extensions.", "\u64F4\u5145\u5957\u4EF6: "}, {".Empty.value.", "(\u7A7A\u767D\u503C)"}, {"Extension.Request.", "\u64F4\u5145\u5957\u4EF6\u8981\u6C42:"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java index 4ca4c7e3394..a00f9e9d809 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_de.java @@ -57,7 +57,7 @@ public class Resources_de extends java.util.ListResourceBundle { {"Retain", "Beibehalten"}, {"Warning.File.name.may.include.escaped.backslash.characters.It.is.not.necessary.to.escape.backslash.characters.the.tool.escapes", - "Warnung: M\u00F6glicherweise enth\u00E4lt der Dateiname Escape-Zeichen mit Backslash. Es ist nicht notwendig, Backslash-Zeichen zu escapen (das Tool f\u00FChrt dies automatisch beim Schreiben des Policy-Contents in den persistenten Speicher aus).\n\nKlicken Sie auf \"Beibehalten\", um den eingegebenen Namen beizubehalten oder auf \"Bearbeiten\", um den Namen zu bearbeiten."}, + "Warnung: M\u00F6glicherweise enth\u00E4lt der Dateiname Escapezeichen mit Backslash. Es ist nicht notwendig, Backslash-Zeichen zu escapen (das Tool f\u00FChrt dies automatisch beim Schreiben des Policy-Contents in den persistenten Speicher aus).\n\nKlicken Sie auf \"Beibehalten\", um den eingegebenen Namen beizubehalten oder auf \"Bearbeiten\", um den Namen zu bearbeiten."}, {"Add.Public.Key.Alias", "Public Key-Alias hinzuf\u00FCgen"}, {"Remove.Public.Key.Alias", "Public Key-Alias entfernen"}, @@ -134,6 +134,9 @@ public class Resources_de extends java.util.ListResourceBundle { {"policy.type", "Policy-Typ"}, {"property.name", "Eigenschaftsname"}, {"provider.name", "Providername"}, + {"url", "URL"}, + {"method.list", "Methodenliste"}, + {"request.headers.list", "Headerliste anfordern"}, {"Principal.List", "Principal-Liste"}, {"Permission.List", "Berechtigungsliste"}, {"Code.Base", "Codebase"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java index 142550094bd..6e92889c1bd 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_es.java @@ -134,6 +134,9 @@ public class Resources_es extends java.util.ListResourceBundle { {"policy.type", "tipo de pol\u00EDtica"}, {"property.name", "nombre de la propiedad"}, {"provider.name", "nombre del proveedor"}, + {"url", "url"}, + {"method.list", "lista de m\u00E9todos"}, + {"request.headers.list", "lista de cabeceras de solicitudes"}, {"Principal.List", "Lista de Principales"}, {"Permission.List", "Lista de Permisos"}, {"Code.Base", "Base de C\u00F3digo"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java index 898e9cc8c9b..adba418d9b4 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_fr.java @@ -134,6 +134,9 @@ public class Resources_fr extends java.util.ListResourceBundle { {"policy.type", "type de r\u00E8gle"}, {"property.name", "nom de propri\u00E9t\u00E9"}, {"provider.name", "nom du fournisseur"}, + {"url", "url"}, + {"method.list", "liste des m\u00E9thodes"}, + {"request.headers.list", "liste des en-t\u00EAtes de demande"}, {"Principal.List", "Liste de principaux"}, {"Permission.List", "Liste de droits"}, {"Code.Base", "Base de code"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java index 3daf8616bee..813be7cfb19 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_it.java @@ -41,7 +41,7 @@ public class Resources_it extends java.util.ListResourceBundle { "Avvertenza: argomento o argomenti non validi per il costruttore {0}"}, {"Illegal.Principal.Type.type", "Tipo principal non valido: {0}"}, {"Illegal.option.option", "Opzione non valida: {0}"}, - {"Usage.policytool.options.", "Utilizzo: policytool [opzioni]"}, + {"Usage.policytool.options.", "Uso: policytool [opzioni]"}, {".file.file.policy.file.location", " [-file ] posizione del file dei criteri"}, {"New", "Nuovo"}, @@ -134,6 +134,9 @@ public class Resources_it extends java.util.ListResourceBundle { {"policy.type", "tipo di criteri"}, {"property.name", "nome propriet\u00E0"}, {"provider.name", "nome provider"}, + {"url", "url"}, + {"method.list", "lista metodi"}, + {"request.headers.list", "lista intestazioni di richiesta"}, {"Principal.List", "Lista principal"}, {"Permission.List", "Lista autorizzazioni"}, {"Code.Base", "Codebase"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java index a3f901aa8f5..bd07eb0ee70 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ja.java @@ -134,6 +134,9 @@ public class Resources_ja extends java.util.ListResourceBundle { {"policy.type", "\u30DD\u30EA\u30B7\u30FC\u30FB\u30BF\u30A4\u30D7"}, {"property.name", "\u30D7\u30ED\u30D1\u30C6\u30A3\u540D"}, {"provider.name", "\u30D7\u30ED\u30D0\u30A4\u30C0\u540D"}, + {"url", "URL"}, + {"method.list", "\u30E1\u30BD\u30C3\u30C9\u30FB\u30EA\u30B9\u30C8"}, + {"request.headers.list", "\u30EA\u30AF\u30A8\u30B9\u30C8\u30FB\u30D8\u30C3\u30C0\u30FC\u30FB\u30EA\u30B9\u30C8"}, {"Principal.List", "\u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u306E\u30EA\u30B9\u30C8"}, {"Permission.List", "\u30A2\u30AF\u30BB\u30B9\u6A29\u306E\u30EA\u30B9\u30C8"}, {"Code.Base", "\u30B3\u30FC\u30C9\u30FB\u30D9\u30FC\u30B9"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java index 7797ec803a0..3dc58f2eeb2 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_ko.java @@ -134,6 +134,9 @@ public class Resources_ko extends java.util.ListResourceBundle { {"policy.type", "\uC815\uCC45 \uC720\uD615"}, {"property.name", "\uC18D\uC131 \uC774\uB984"}, {"provider.name", "\uC81C\uACF5\uC790 \uC774\uB984"}, + {"url", "URL"}, + {"method.list", "\uBA54\uC18C\uB4DC \uBAA9\uB85D"}, + {"request.headers.list", "\uC694\uCCAD \uD5E4\uB354 \uBAA9\uB85D"}, {"Principal.List", "\uC8FC\uCCB4 \uBAA9\uB85D"}, {"Permission.List", "\uAD8C\uD55C \uBAA9\uB85D"}, {"Code.Base", "\uCF54\uB4DC \uBCA0\uC774\uC2A4"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java index 9bd9808d0b5..2290701f755 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_pt_BR.java @@ -134,6 +134,9 @@ public class Resources_pt_BR extends java.util.ListResourceBundle { {"policy.type", "tipo de pol\u00EDtica"}, {"property.name", "nome da propriedade"}, {"provider.name", "nome do fornecedor"}, + {"url", "url"}, + {"method.list", "lista de m\u00E9todos"}, + {"request.headers.list", "solicitar lista de cabe\u00E7alhos"}, {"Principal.List", "Lista de Principais"}, {"Permission.List", "Lista de Permiss\u00F5es"}, {"Code.Base", "Base de C\u00F3digo"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java index f0bf734ae40..0929eec984e 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_sv.java @@ -134,6 +134,9 @@ public class Resources_sv extends java.util.ListResourceBundle { {"policy.type", "policytyp"}, {"property.name", "egenskapsnamn"}, {"provider.name", "leverant\u00F6rsnamn"}, + {"url", "url"}, + {"method.list", "metodlista"}, + {"request.headers.list", "beg\u00E4ranrubriklista"}, {"Principal.List", "Lista \u00F6ver identitetshavare"}, {"Permission.List", "Beh\u00F6righetslista"}, {"Code.Base", "Kodbas"}, diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java index fcf8e126d4c..d96dc07d71b 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_CN.java @@ -35,7 +35,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { private static final Object[][] contents = { {"NEWLINE", "\n"}, {"Warning.A.public.key.for.alias.signers.i.does.not.exist.Make.sure.a.KeyStore.is.properly.configured.", - "\u8B66\u544A: \u522B\u540D {0} \u7684\u516C\u5171\u5BC6\u94A5\u4E0D\u5B58\u5728\u3002\u8BF7\u786E\u4FDD\u5DF2\u6B63\u786E\u914D\u7F6E KeyStore\u3002"}, + "\u8B66\u544A: \u522B\u540D {0} \u7684\u516C\u5171\u5BC6\u94A5\u4E0D\u5B58\u5728\u3002\u8BF7\u786E\u4FDD\u5DF2\u6B63\u786E\u914D\u7F6E\u5BC6\u94A5\u5E93\u3002"}, {"Warning.Class.not.found.class", "\u8B66\u544A: \u627E\u4E0D\u5230\u7C7B: {0}"}, {"Warning.Invalid.argument.s.for.constructor.arg", "\u8B66\u544A: \u6784\u9020\u5668\u7684\u53C2\u6570\u65E0\u6548: {0}"}, @@ -62,7 +62,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Add.Public.Key.Alias", "\u6DFB\u52A0\u516C\u5171\u5BC6\u94A5\u522B\u540D"}, {"Remove.Public.Key.Alias", "\u5220\u9664\u516C\u5171\u5BC6\u94A5\u522B\u540D"}, {"File", "\u6587\u4EF6"}, - {"KeyStore", "KeyStore"}, + {"KeyStore", "\u5BC6\u94A5\u5E93"}, {"Policy.File.", "\u7B56\u7565\u6587\u4EF6:"}, {"Could.not.open.policy.file.policyFile.e.toString.", "\u65E0\u6CD5\u6253\u5F00\u7B56\u7565\u6587\u4EF6: {0}: {1}"}, @@ -94,10 +94,10 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {".Edit.Permission", " \u7F16\u8F91\u6743\u9650"}, {"Remove.Permission", "\u5220\u9664\u6743\u9650"}, {"Done", "\u5B8C\u6210"}, - {"KeyStore.URL.", "KeyStore URL:"}, - {"KeyStore.Type.", "KeyStore \u7C7B\u578B:"}, - {"KeyStore.Provider.", "KeyStore \u63D0\u4F9B\u65B9:"}, - {"KeyStore.Password.URL.", "KeyStore \u53E3\u4EE4 URL:"}, + {"KeyStore.URL.", "\u5BC6\u94A5\u5E93 URL:"}, + {"KeyStore.Type.", "\u5BC6\u94A5\u5E93\u7C7B\u578B:"}, + {"KeyStore.Provider.", "\u5BC6\u94A5\u5E93\u63D0\u4F9B\u65B9:"}, + {"KeyStore.Password.URL.", "\u5BC6\u94A5\u5E93\u53E3\u4EE4 URL:"}, {"Principals", "\u4E3B\u7528\u6237"}, {".Edit.Principal.", " \u7F16\u8F91\u4E3B\u7528\u6237:"}, {".Add.New.Principal.", " \u6DFB\u52A0\u65B0\u4E3B\u7528\u6237:"}, @@ -123,7 +123,7 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"Save.Changes", "\u4FDD\u5B58\u66F4\u6539"}, {"No.Policy.Entry.selected", "\u6CA1\u6709\u9009\u62E9\u7B56\u7565\u6761\u76EE"}, {"Unable.to.open.KeyStore.ex.toString.", - "\u65E0\u6CD5\u6253\u5F00 KeyStore: {0}"}, + "\u65E0\u6CD5\u6253\u5F00\u5BC6\u94A5\u5E93: {0}"}, {"No.principal.selected", "\u672A\u9009\u62E9\u4E3B\u7528\u6237"}, {"No.permission.selected", "\u6CA1\u6709\u9009\u62E9\u6743\u9650"}, {"name", "\u540D\u79F0"}, @@ -134,11 +134,14 @@ public class Resources_zh_CN extends java.util.ListResourceBundle { {"policy.type", "\u7B56\u7565\u7C7B\u578B"}, {"property.name", "\u5C5E\u6027\u540D\u79F0"}, {"provider.name", "\u63D0\u4F9B\u65B9\u540D\u79F0"}, + {"url", "URL"}, + {"method.list", "\u65B9\u6CD5\u5217\u8868"}, + {"request.headers.list", "\u8BF7\u6C42\u6807\u5934\u5217\u8868"}, {"Principal.List", "\u4E3B\u7528\u6237\u5217\u8868"}, {"Permission.List", "\u6743\u9650\u5217\u8868"}, {"Code.Base", "\u4EE3\u7801\u5E93"}, - {"KeyStore.U.R.L.", "KeyStore URL:"}, - {"KeyStore.Password.U.R.L.", "KeyStore \u53E3\u4EE4 URL:"} + {"KeyStore.U.R.L.", "\u5BC6\u94A5\u5E93 URL:"}, + {"KeyStore.Password.U.R.L.", "\u5BC6\u94A5\u5E93\u53E3\u4EE4 URL:"} }; diff --git a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java index 1c241a6afa1..5a9af4ed40f 100644 --- a/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java +++ b/jdk/src/share/classes/sun/security/tools/policytool/Resources_zh_TW.java @@ -134,6 +134,9 @@ public class Resources_zh_TW extends java.util.ListResourceBundle { {"policy.type", "\u539F\u5247\u985E\u578B"}, {"property.name", "\u5C6C\u6027\u540D\u7A31"}, {"provider.name", "\u63D0\u4F9B\u8005\u540D\u7A31"}, + {"url", "URL"}, + {"method.list", "\u65B9\u6CD5\u6E05\u55AE"}, + {"request.headers.list", "\u8981\u6C42\u6A19\u982D\u6E05\u55AE"}, {"Principal.List", "Principal \u6E05\u55AE"}, {"Permission.List", "\u6B0A\u9650\u6E05\u55AE"}, {"Code.Base", "\u4EE3\u78BC\u57FA\u6E96"}, diff --git a/jdk/src/share/classes/sun/security/util/Resources_fr.java b/jdk/src/share/classes/sun/security/util/Resources_fr.java index 44a6d5f9e79..f31968fcf42 100644 --- a/jdk/src/share/classes/sun/security/util/Resources_fr.java +++ b/jdk/src/share/classes/sun/security/util/Resources_fr.java @@ -65,12 +65,12 @@ public class Resources_fr extends java.util.ListResourceBundle { {"invalid.null.Class.provided", "classe NULL fournie non valide"}, {"Subject.", "Objet :\n"}, {".Principal.", "\tPrincipal : "}, - {".Public.Credential.", "\tInformations d'identification et de connexion publiques : "}, + {".Public.Credential.", "\tInformations d'identification publiques : "}, {".Private.Credentials.inaccessible.", - "\tInformations d'identification et de connexion priv\u00E9es inaccessibles\n"}, - {".Private.Credential.", "\tInformations d'identification et de connexion priv\u00E9es : "}, + "\tInformations d'identification priv\u00E9es inaccessibles\n"}, + {".Private.Credential.", "\tInformations d'identification priv\u00E9es : "}, {".Private.Credential.inaccessible.", - "\tInformations d'identification et de connexion priv\u00E9es inaccessibles\n"}, + "\tInformations d'identification priv\u00E9es inaccessibles\n"}, {"Subject.is.read.only", "Sujet en lecture seule"}, {"attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set", "tentative d'ajout d'un objet qui n'est pas une instance de java.security.Principal dans un ensemble de principaux du sujet"}, diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties index 678d292b4f2..4dd5d5f9129 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_de.properties @@ -29,7 +29,6 @@ error.bad.option=Eine der Optionen -{ctxu} muss angegeben werden. error.bad.cflag=Kennzeichen "c" erfordert Angabe von Manifest oder Eingabedateien. error.bad.uflag=Kennzeichen "u" erfordert Angabe von Manifest, Kennzeichen "e" oder Eingabedateien. error.bad.eflag=Kennzeichen "e" und Manifest mit dem Attribut "Main-Class" k\u00F6nnen nicht zusammen angegeben\nwerden. -error.bad.pvalue=ung\u00FCltiger Wert f\u00FCr Attribut "Profil": {0} error.nosuch.fileordir={0}: Datei oder Verzeichnis nicht vorhanden error.write.file=Fehler beim Schreiben in vorhandener JAR-Datei error.create.dir={0}: Verzeichnis konnte nicht erstellt werden @@ -42,7 +41,7 @@ out.deflated=({0} % verkleinert) out.stored=(0 % gespeichert) out.create=\ erstellt: {0} out.extracted=extrahiert: {0} -out.inflated=\ \\vergr\u00F6\u00DFert: {0} +out.inflated=\ vergr\u00F6\u00DFert: {0} out.size=(ein = {0}) (aus = {1}) -usage=Verwendung: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien...\nOptionen:\n -c Neues Archiv erstellen\n -t Inhaltsverzeichnis f\u00FCr Archiv auflisten\n -x Genannte (oder alle) Dateien aus Archiv extrahieren\n -u Vorhandenes Archiv aktualisieren\n -v Verbose-Ausgabe f\u00FCr Standardausgabe generieren\n -f Namen der Archivdatei angeben\n -m Manifestinformationen von angegebener Manifestdatei einschlie\u00DFen\n -e Anwendungseinstiegspunkt f\u00FCr die \n in einer ausf\u00FChrbaren JAR-Datei geb\u00FCndelte Standalone-Anwendung angeben\n -p Profilnamen angeben\n -0 Nur speichern (keine ZIP-Komprimierung)\n -M Keine Manifest-Datei f\u00FCr die Eintr\u00E4ge erstellen\n -i Indexinformationen f\u00FCr angegebene JAR-Dateien erstellen\n -C zum angegebenen Verzeichnis wechseln und folgende Datei einschlie\u00DFen\nFalls eine Datei ein Verzeichnis ist, wird dieses rekursiv verarbeitet.\nDer Name der Manifestdatei, der Name der Archivdatei und der Name des Einstiegspunkts werden\nin derselben Reihenfolge wie die Kennzeichen "m", "f" und "e" angegeben.\n\nBeispiel 1: Archivieren Sie zwei Klassendateien in ein Archiv mit dem Namen "classes.jar": \n jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Verwenden Sie die vorhandenen Manifestdatei "mymanifest", und archivieren Sie\n alle Dateien im Verzeichnis foo/ in "classes.jar": \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Verwendung: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien...\nOptionen:\n -c Neues Archiv erstellen\n -t Inhaltsverzeichnis f\u00FCr Archiv auflisten\n -x Genannte (oder alle) Dateien aus Archiv extrahieren\n -u Vorhandenes Archiv aktualisieren\n -v Verbose-Ausgabe f\u00FCr Standardausgabe generieren\n -f Namen der Archivdatei angeben\n -m Manifest-Informationen von angegebener Manifest-Datei einschlie\u00DFen\n -e Anwendungs-Einstiegspunkt f\u00FCr die \n in einer ausf\u00FChrbaren JAR-Datei geb\u00FCndelte Standalone-Anwendung angeben\n -0 Nur speichern (keine ZIP-Komprimierung)\n -M Keine Manifest-Datei f\u00FCr die Eintr\u00E4ge erstellen\n -i Indexinformationen f\u00FCr angegebenen JAR-Dateien erstellen\n -C zum angegebenen Verzeichnis wechseln und folgende Datei einschlie\u00DFen\nFalls eine Datei ein Verzeichnis ist, wird dieses rekursiv verarbeitet.\nDer Name der Manifest-Datei, der Name der Archivdatei und der Name des Einstiegspunkts werden\nin derselben Reihenfolge wie die Kennzeichen "m", "f" und "e" angegeben.\n\nBeispiel 1: Archivieren Sie zwei Klassendateien in ein Archiv mit Namen "classes.jar": \n jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Verwenden Sie die vorhandenen Manifest-Datei "mymanifest", und archivieren Sie\n alle Dateien im Verzeichnis foo/ in "classes.jar": \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties index ff24bed068d..e5ce11bda79 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_es.properties @@ -29,7 +29,6 @@ error.bad.option=Se debe especificar una de las opciones -{ctxu}. error.bad.cflag=El indicador 'c' necesita la especificaci\u00F3n de archivos de manifiesto o de entrada. error.bad.uflag=El indicador 'u' necesita la especificaci\u00F3n de archivos de manifiesto, de entrada o indicador 'e'. error.bad.eflag=El indicador 'e' y el manifiesto con el atributo 'Main-Class' no pueden especificarse \na la vez. -error.bad.pvalue=valor err\u00F3neo para el atributo ''Profile'': {0} error.nosuch.fileordir={0} : no existe tal archivo o directorio error.write.file=Error al escribir un archivo jar existente error.create.dir={0} : no se ha podido crear el directorio @@ -42,7 +41,7 @@ out.deflated=(desinflado {0}%) out.stored=(almacenado 0%) out.create=\ creado: {0} out.extracted=extra\u00EDdo: {0} -out.inflated=\ \\inflado: {0} +out.inflated=\ inflado: {0} out.size=(entrada = {0}) (salida = {1}) -usage=Sintaxis: archivos jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] ...\nOpciones:\n -c crear nuevo archivo\n -t mostrar la tabla de contenido del archivo\n -x extraer los archivos mencionados (o todos) del archivo\n -u actualizar archivo existente\n -v generar salida detallada de los datos de salida est\u00E1ndar\n -f especificar nombre de archivo de almacenamiento\n -m incluir informaci\u00F3n de manifiesto del archivo de manifiesto especificado\n -e especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n que se incluye dentro de un archivo jar ejecutable\n -p especificar nombre de perfil\n -0 solo almacenar; no utilizar compresi\u00F3n ZIP\n -M no crear un archivo de manifiesto para las entradas\n -i generar informaci\u00F3n de \u00EDndice para los archivos jar especificados\n -C cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente.\nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\nespecifican en el mismo orden que los indicadores 'm', 'f' y 'e'.\n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\narchivos del directorio foo/ en'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Sintaxis: jar {ctxui}[vfm0Me] [archive-jar] [archive-manifiesto] [punto-entrada] [-C dir] archivos...\nOpciones:\n -c crear nuevo archivo\n -t crear la tabla de contenido del archivo\n -x extraer el archive mencionado (o todos) del archivo\n -u actualizar archive existente\n -v generar salida detallada de los datos de salida est\u00E1ndar\n -f especificar nombre de archive de almacenamiento\n -m incluir informaci\u00F3n de manifiesto del archive de manifiesto especificado\n -e especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n que se incluye dentro de un archive jar ejecutable\n -0 s\u00F3lo almacenar; no utilizar compresi\u00F3n ZIP\n -M no crear un archive de manifiesto para las entradas\n -i generar informaci\u00F3n de \u00EDndice para los archives jar especificados\n -C cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente.\nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\nespecifican en el mismo orden que los indicadores 'm', 'f' y 'e'.\n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\n archivos del directorio foo/ en 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties index f26335287fb..c7cae813be4 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_fr.properties @@ -29,7 +29,6 @@ error.bad.option=Une des options -{ctxu} doit \u00EAtre sp\u00E9cifi\u00E9e. error.bad.cflag=L'indicateur c requiert la sp\u00E9cification d'un fichier manifeste ou d'un fichier d'entr\u00E9e. error.bad.uflag=L'indicateur u requiert la sp\u00E9cification d'un fichier manifeste, d'un fichier d'entr\u00E9e ou d'un indicateur e. error.bad.eflag=L'indicateur e et le fichier manifeste portant l'attribut Main-Class ne peuvent pas \u00EAtre sp\u00E9cifi\u00E9s \nensemble. -error.bad.pvalue=valeur incorrecte pour l''attribut ''Profile'' : {0} error.nosuch.fileordir={0} : fichier ou r\u00E9pertoire introuvable error.write.file=Erreur lors de l'\u00E9criture d'un fichier JAR existant error.create.dir={0} : impossible de cr\u00E9er le r\u00E9pertoire @@ -42,7 +41,7 @@ out.deflated=(compression : {0} %) out.stored=(stockage : 0 %) out.create=\ cr\u00E9\u00E9 : {0} out.extracted=extrait : {0} -out.inflated=\ \\d\u00E9compress\u00E9 : {0} +out.inflated=\ d\u00E9compress\u00E9 : {0} out.size=(entr\u00E9e = {0}) (sortie = {1}) -usage=Syntaxe : jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOptions :\n -c cr\u00E9e une archive\n -t affiche la table des mati\u00E8res de l'archive\n -x extrait les fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n -u met \u00E0 jour l'archive existante\n -v g\u00E9n\u00E8re une sortie en mode verbose d'une sortie standard\n -f sp\u00E9cifie le nom du fichier d'archive\n -m inclut les informations de manifest \u00E0 partir du fichier manifest sp\u00E9cifi\u00E9\n -e sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n -p indique le nom de profil\n -0 stockage uniquement, pas de compression ZIP\n -M ne cr\u00E9e pas de fichier manifest pour les entr\u00E9es\n -i g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n -C passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifest, du fichier d'archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifest existant 'mymanifest', puis archiver tous les\n fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Syntaxe : jar {ctxui}[vfm0Me] [fichier-jar] [fichier-manifeste] [point-entr\u00E9e] [-C r\u00E9p] fichiers...\nOptions :\n -c cr\u00E9e une archive\n -t affiche la table des mati\u00E8res de l'archive\n -x extrait les fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n -u met \u00E0 jour l'archive existante\n -v g\u00E9n\u00E8re une version d\u00E9taill\u00E9e d'une sortie standard\n -f sp\u00E9cifie le nom du fichier archive\n -m inclut les informations de manifeste \u00E0 partir du fichier de manifeste sp\u00E9cifi\u00E9\n -e sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n -0 stockage uniquement, pas de compression ZIP\n -M ne cr\u00E9e pas de fichier manifeste pour les entr\u00E9es\n -i g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n -C passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifeste, du fichier archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifeste existant 'monmanifeste', puis archiver tous les\n fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n jar cvfm classes.jar monmanifeste -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties index 313169c83b0..50652a82056 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_it.properties @@ -29,7 +29,6 @@ error.bad.option=\u00C8 necessario specificare una delle opzioni -{ctxu}. error.bad.cflag=Per il flag 'c' \u00E8 necessario specificare file manifest o di input. error.bad.uflag=Per il flag 'u' \u00E8 necessario specificare il flag 'e' oppure file manifest o di input. error.bad.eflag=Il flag 'e' e il manifest con l'attributo 'Main-Class' non possono essere specificati\ninsieme. -error.bad.pvalue=valore non valido per l''attributo ''Profile'': {0} error.nosuch.fileordir={0} : file o directory inesistente error.write.file=Errore durante la scrittura del file jar esistente error.create.dir={0} : impossibile creare la directory @@ -42,7 +41,7 @@ out.deflated=(compresso {0}%) out.stored=(memorizzato 0%) out.create=\ creato: {0} out.extracted=estratto: {0} -out.inflated=\ \\decompresso: {0} +out.inflated=\ decompresso: {0} out.size=(in = {0}) (out = {1}) -usage=Uso: jar {ctxui}[vfm0Me] [jar-file] [file manifest] [punto di accesso] [-C dir] file ...\nOpzioni:\n -c crea un nuovo archivio\n -t visualizza il sommario dell'archivio\n -x estrae i file specificati (o tutti i file) dall'archivio\n -u aggiorna un archivio esistente\n -v genera un output descrittivo dall'output standard\n -f specifica il nome file dell'archivio\n -m include le informazioni manifest dal file manifest specificato\n -e specifica il punto di accesso per l'applicazione standalone \n inclusa in un file JAR eseguibile\n -p specifica il nome del profilo\n -0 esegue solo la memorizzazione; non utilizza la compressione ZIP\n -M non crea un file manifest per le voci\n -i genera le informazioni di indice per i file JAR specificati\n -C passa alla directory specificata e include il file seguente\nSe un file qualsiasi \u00E8 una directory, viene elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di accesso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' e 'e'.\n\nEsempio 1: archiviazione di due file di classe nell'archivio denominato classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEsempio 2: uso del file manifest esistente 'mymanifest' e archiviazione di tutti i\n file della directory foo/ in 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/.\n +usage=Uso: jar {ctxui}[vfm0Me] [file-jar] [file-manifest] [punto di ingresso] [-C dir] file ...\nOpzioni:\n -c crea un nuovo archivio\n -t visualizza l'indice dell'archivio\n -x estrae i file con nome (o tutti i file) dall'archivio\n -u aggiorna l'archivio esistente\n -v genera output commentato dall'output standard\n -f specifica il nome file dell'archivio\n -m include informazioni manifest dal file manifest specificato\n -e specifica il punto di ingresso per l'applicazione stand-alone \n inclusa nel file jar eseguibile\n -0 solo memorizzazione; senza compressione ZIP\n -M consente di non creare un file manifest per le voci\n -i genera informazioni sull'indice per i file jar specificati\n -C imposta la directory specificata e include il file seguente\nSe un file \u00E8 una directory, verr\u00E0 elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di ingresso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' ed 'e'.\n\nEsempio 1: archiviazione di due file di classe in un archivio con il nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEsempio 2: utilizzo del file manifest esistente 'mymanifest' e archiviazione di tutti i\n file della directory foo/ in 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/.\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties index b909c46d04a..7167ef10ec0 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_ja.properties @@ -29,7 +29,6 @@ error.bad.option=\u30AA\u30D7\u30B7\u30E7\u30F3-{ctxu}\u306E\u3046\u3061\u306E1\ error.bad.cflag=\u30D5\u30E9\u30B0'c'\u3067\u306F\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u307E\u305F\u306F\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059\u3002 error.bad.uflag=\u30D5\u30E9\u30B0'u'\u3067\u306F\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304B'e'\u30D5\u30E9\u30B0\u3001\u307E\u305F\u306F\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059\u3002 error.bad.eflag='e'\u30D5\u30E9\u30B0\u3068'Main-Class'\u5C5E\u6027\u3092\u6301\u3064\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306F\u540C\u6642\u306B\n\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002 -error.bad.pvalue=''Profile''\u5C5E\u6027\u306E\u5024\u304C\u4E0D\u6B63\u3067\u3059: {0} error.nosuch.fileordir={0}\u3068\u3044\u3046\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u3042\u308A\u307E\u305B\u3093 error.write.file=\u65E2\u5B58jar\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F error.create.dir=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F @@ -42,7 +41,7 @@ out.deflated=({0}%\u53CE\u7E2E\u3055\u308C\u307E\u3057\u305F) out.stored=(0%\u683C\u7D0D\u3055\u308C\u307E\u3057\u305F) out.create=\ {0}\u304C\u4F5C\u6210\u3055\u308C\u307E\u3057\u305F out.extracted={0}\u304C\u62BD\u51FA\u3055\u308C\u307E\u3057\u305F -out.inflated=\ \\{0}\u304C\u5C55\u958B\u3055\u308C\u307E\u3057\u305F +out.inflated=\ {0}\u304C\u5C55\u958B\u3055\u308C\u307E\u3057\u305F out.size=(\u5165={0})(\u51FA={1}) -usage=\u4F7F\u7528\u65B9\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n -c \u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B\n -t \u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u5185\u5BB9\u3092\u4E00\u89A7\u8868\u793A\u3059\u308B\n -x \u6307\u5B9A\u306E(\u307E\u305F\u306F\u3059\u3079\u3066\u306E)\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u62BD\u51FA\u3059\u308B\n -u \u65E2\u5B58\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u66F4\u65B0\u3059\u308B\n -v \u6A19\u6E96\u51FA\u529B\u306B\u8A73\u7D30\u306A\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n -f \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n -m \u6307\u5B9A\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u60C5\u5831\u3092\u53D6\u308A\u8FBC\u3080\n -e \u5B9F\u884C\u53EF\u80FDjar\u30D5\u30A1\u30A4\u30EB\u306B\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305F\u30B9\u30BF\u30F3\u30C9\u30A2\u30ED\u30F3\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\n \u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A\u3059\u308B\n -p \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n -0 \u683C\u7D0D\u306E\u307F\u3002ZIP\u5727\u7E2E\u3092\u4F7F\u7528\u3057\u306A\u3044\n -M \u30A8\u30F3\u30C8\u30EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3057\u306A\u3044\n -i \u6307\u5B9A\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306E\u7D22\u5F15\u60C5\u5831\u3092\u751F\u6210\u3059\u308B\n -C \u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u5909\u66F4\u3057\u3001\u4EE5\u4E0B\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u308A\u8FBC\u3080\n\u30D5\u30A1\u30A4\u30EB\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u5834\u5408\u306F\u518D\u5E30\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\n\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u304A\u3088\u3073\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u540D\u306F\u3001\n\u30D5\u30E9\u30B0'm'\u3001'f'\u3001'e'\u3068\u540C\u3058\u9806\u5E8F\u3067\u6307\u5B9A\u3057\u307E\u3059\u3002\n\n\u4F8B1: 2\u3064\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6classes.jar\u306B\u4FDD\u5B58\u3059\u308B:\n jar cvf classes.jar Foo.class Bar.class\n\u4F8B2: \u65E2\u5B58\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB'mymanifest'\u3092\u4F7F\u7528\u3057\u3001foo/\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\n \u5168\u30D5\u30A1\u30A4\u30EB\u3092'classes.jar'\u306B\u30A2\u30FC\u30AB\u30A4\u30D6\u3059\u308B:\n jar cvfm classes.jar mymanifest -C foo/ \n +usage=\u4F7F\u7528\u65B9\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n -c \u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B\n -t \u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u5185\u5BB9\u3092\u4E00\u89A7\u8868\u793A\u3059\u308B\n -x \u6307\u5B9A\u306E(\u307E\u305F\u306F\u3059\u3079\u3066\u306E)\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u62BD\u51FA\u3059\u308B\n -u \u65E2\u5B58\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u66F4\u65B0\u3059\u308B\n -v \u6A19\u6E96\u51FA\u529B\u306B\u8A73\u7D30\u306A\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n -f \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n -m \u6307\u5B9A\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u60C5\u5831\u3092\u53D6\u308A\u8FBC\u3080\n -e \u5B9F\u884C\u53EF\u80FDjar\u30D5\u30A1\u30A4\u30EB\u306B\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305F\u30B9\u30BF\u30F3\u30C9\u30A2\u30ED\u30F3\u30FB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\n \u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A\u3059\u308B\n -0 \u683C\u7D0D\u306E\u307F\u3002ZIP\u5727\u7E2E\u3092\u4F7F\u7528\u3057\u306A\u3044\n -M \u30A8\u30F3\u30C8\u30EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3057\u306A\u3044\n -i \u6307\u5B9A\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306E\u7D22\u5F15\u60C5\u5831\u3092\u751F\u6210\u3059\u308B\n -C \u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u5909\u66F4\u3057\u3001\u4EE5\u4E0B\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u308A\u8FBC\u3080\n\u30D5\u30A1\u30A4\u30EB\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u5834\u5408\u306F\u518D\u5E30\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\n\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u304A\u3088\u3073\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u540D\u306F\u3001\n\u30D5\u30E9\u30B0'm'\u3001'f'\u3001'e'\u306E\u6307\u5B9A\u3068\u540C\u3058\u9806\u756A\u3067\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\n\u4F8B1: 2\u3064\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6classes.jar\u306B\u4FDD\u5B58\u3059\u308B:\n jar cvf classes.jar Foo.class Bar.class\n\u4F8B2: \u65E2\u5B58\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB'mymanifest'\u3092\u4F7F\u7528\u3057\u3001foo/\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\n \u5168\u30D5\u30A1\u30A4\u30EB\u3092'classes.jar'\u306B\u30A2\u30FC\u30AB\u30A4\u30D6\u3059\u308B:\n jar cvfm classes.jar mymanifest -C foo/ \n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties index 472d2d94dc2..2b414a0369d 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_ko.properties @@ -29,20 +29,19 @@ error.bad.option=\uC635\uC158 -{ctxu} \uC911 \uD558\uB098\uB97C \uC9C0\uC815\uD5 error.bad.cflag='c' \uD50C\uB798\uADF8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 Manifest \uB610\uB294 \uC785\uB825 \uD30C\uC77C\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4! error.bad.uflag='u' \uD50C\uB798\uADF8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 Manifest, 'e' \uD50C\uB798\uADF8 \uB610\uB294 \uC785\uB825 \uD30C\uC77C\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4! error.bad.eflag='e' \uD50C\uB798\uADF8 \uBC0F Manifest\uB97C 'Main-Class' \uC18D\uC131\uACFC \uD568\uAED8 \uC9C0\uC815\uD560 \uC218\n\uC5C6\uC2B5\uB2C8\uB2E4! -error.bad.pvalue=''Profile'' \uC18D\uC131\uC5D0 \uB300\uD574 \uC798\uBABB\uB41C \uAC12: {0} error.nosuch.fileordir={0}: \uD574\uB2F9 \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. error.write.file=\uAE30\uC874 jar \uD30C\uC77C\uC5D0 \uC4F0\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. error.create.dir={0}: \uB514\uB809\uD1A0\uB9AC\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. error.incorrect.length=\uCC98\uB9AC \uC911 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC740 \uAE38\uC774\uAC00 \uBC1C\uACAC\uB428: {0} out.added.manifest=Manifest\uB97C \uCD94\uAC00\uD568 -out.update.manifest=Manifest\uB97C \uAC31\uC2E0\uD568 +out.update.manifest=Manifest\uB97C \uC5C5\uB370\uC774\uD2B8\uD568 out.ignore.entry={0} \uD56D\uBAA9\uC744 \uBB34\uC2DC\uD558\uB294 \uC911 out.adding=\uCD94\uAC00\uD558\uB294 \uC911: {0} out.deflated=({0}%\uB97C \uAC10\uC18C\uD568) out.stored=(0%\uB97C \uC800\uC7A5\uD568) out.create=\ \uC0DD\uC131\uB428: {0} out.extracted=\uCD94\uCD9C\uB428: {0} -out.inflated=\ \\\uC99D\uAC00\uB428: {0} +out.inflated=\ \uC99D\uAC00\uB428: {0} out.size=(\uC785\uB825 = {0}) (\uCD9C\uB825 = {1}) -usage=\uC0AC\uC6A9\uBC95: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\uC635\uC158:\n -c \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -t \uC544\uCE74\uC774\uBE0C\uC5D0 \uB300\uD55C \uBAA9\uCC28\uB97C \uB098\uC5F4\uD569\uB2C8\uB2E4.\n -x \uBA85\uBA85\uB41C(\uB610\uB294 \uBAA8\uB4E0) \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uCD94\uCD9C\uD569\uB2C8\uB2E4.\n -u \uAE30\uC874 \uC544\uCE74\uC774\uBE0C\uB97C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n -v \uD45C\uC900 \uCD9C\uB825\uC5D0 \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -f \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -m \uC9C0\uC815\uB41C Manifest \uD30C\uC77C\uC758 Manifest \uC815\uBCF4\uB97C \uD3EC\uD568\uD569\uB2C8\uB2E4.\n -e jar \uC2E4\uD589 \uD30C\uC77C\uC5D0 \uBC88\uB4E4\uB85C \uC81C\uACF5\uB41C \uB3C5\uB9BD\uD615 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8\uC758 \n \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8 \uC2DC\uC791 \uC9C0\uC810\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -p \uD504\uB85C\uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -0 \uC800\uC7A5 \uC804\uC6A9: ZIP \uC555\uCD95\uC744 \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -M \uD56D\uBAA9\uC5D0 \uB300\uD574 Manifest \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -i \uC9C0\uC815\uB41C jar \uD30C\uC77C\uC5D0 \uB300\uD55C \uC778\uB371\uC2A4 \uC815\uBCF4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -C \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uB85C \uBCC0\uACBD\uD558\uACE0 \uB2E4\uC74C \uD30C\uC77C\uC744 \uD3EC\uD568\uD569\uB2C8\uB2E4.\n\uD2B9\uC815 \uD30C\uC77C\uC774 \uB514\uB809\uD1A0\uB9AC\uC77C \uACBD\uC6B0 \uC21C\uD658\uC801\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4.\nManifest \uD30C\uC77C \uC774\uB984, \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984 \uBC0F \uC2DC\uC791 \uC9C0\uC810 \uC774\uB984\uC740\n'm', 'f' \uBC0F 'e' \uD50C\uB798\uADF8\uC640 \uB3D9\uC77C\uD55C \uC21C\uC11C\uB85C \uC9C0\uC815\uB429\uB2C8\uB2E4.\n\n\uC608 1: classes.jar\uB77C\uB294 \uC544\uCE74\uC774\uBE0C\uC5D0 \uB450 \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvf classes.jar Foo.class Bar.class \n\uC608 2: \uAE30\uC874 Manifest \uD30C\uC77C 'mymanifest'\uB97C \uC0AC\uC6A9\uD558\uC5EC\n foo/ \uB514\uB809\uD1A0\uB9AC\uC758 \uBAA8\uB4E0 \uD30C\uC77C\uC744 'classes.jar'\uB85C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvfm classes.jar mymanifest -C foo/\n +usage=\uC0AC\uC6A9\uBC95: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\uC635\uC158:\n -c \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -t \uC544\uCE74\uC774\uBE0C\uC5D0 \uB300\uD55C \uBAA9\uCC28\uB97C \uB098\uC5F4\uD569\uB2C8\uB2E4.\n -x \uBA85\uBA85\uB41C(\uB610\uB294 \uBAA8\uB4E0) \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uCD94\uCD9C\uD569\uB2C8\uB2E4.\n -u \uAE30\uC874 \uC544\uCE74\uC774\uBE0C\uB97C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n -v \uD45C\uC900 \uCD9C\uB825\uC5D0 \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -f \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -m \uC9C0\uC815\uB41C Manifest \uD30C\uC77C\uC758 Manifest \uC815\uBCF4\uB97C \uD3EC\uD568\uD569\uB2C8\uB2E4.\n -e jar \uC2E4\uD589 \uD30C\uC77C\uC5D0 \uBC88\uB4E4\uB85C \uC81C\uACF5\uB41C \uB3C5\uB9BD\uD615 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8\uC758 \n \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8 \uC2DC\uC791 \uC9C0\uC810\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -0 \uC800\uC7A5 \uC804\uC6A9: ZIP \uC555\uCD95\uC744 \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -M \uD56D\uBAA9\uC5D0 \uB300\uD574 Manifest \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -i \uC9C0\uC815\uB41C jar \uD30C\uC77C\uC5D0 \uB300\uD55C \uC778\uB371\uC2A4 \uC815\uBCF4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -C \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uB85C \uBCC0\uACBD\uD558\uACE0 \uB2E4\uC74C \uD30C\uC77C\uC744 \uD3EC\uD568\uD569\uB2C8\uB2E4.\n\uD2B9\uC815 \uD30C\uC77C\uC774 \uB514\uB809\uD1A0\uB9AC\uC77C \uACBD\uC6B0 \uC21C\uD658\uC801\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4.\nManifest \uD30C\uC77C \uC774\uB984, \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984 \uBC0F \uC2DC\uC791 \uC9C0\uC810 \uC774\uB984\uC740\n'm', 'f' \uBC0F 'e' \uD50C\uB798\uADF8\uC640 \uB3D9\uC77C\uD55C \uC21C\uC11C\uB85C \uC9C0\uC815\uB429\uB2C8\uB2E4.\n\n\uC608 1: classes.jar\uB77C\uB294 \uC544\uCE74\uC774\uBE0C\uC5D0 \uB450 \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvf classes.jar Foo.class Bar.class \n\uC608 2: \uAE30\uC874 Manifest \uD30C\uC77C 'mymanifest'\uB97C \uC0AC\uC6A9\uD558\uC5EC\n foo/ \uB514\uB809\uD1A0\uB9AC\uC758 \uBAA8\uB4E0 \uD30C\uC77C\uC744 'classes.jar'\uB85C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties index 4c4c9f89e21..db6bd74b1e3 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_pt_BR.properties @@ -29,7 +29,6 @@ error.bad.option=Uma das op\u00E7\u00F5es -{ctxu} deve ser especificada. error.bad.cflag=flag 'c' requer que os arquivos de manifesto ou entrada sejam especificados! error.bad.uflag=o flag 'u' requer que arquivos de manifesto, o flag 'e' ou arquivos de entrada sejam especificados! error.bad.eflag=o flag 'e' e manifesto com o atributo 'Main-Class' n\u00E3o podem ser especificados \njuntos! -error.bad.pvalue=valor inv\u00E1lido do atributo de ''Perfil'': {0} error.nosuch.fileordir={0} : n\u00E3o h\u00E1 tal arquivo ou diret\u00F3rio error.write.file=Erro ao gravar o arquivo jar existente error.create.dir={0} : n\u00E3o foi poss\u00EDvel criar o diret\u00F3rio @@ -38,11 +37,11 @@ out.added.manifest=manifesto adicionado out.update.manifest=manifesto atualizado out.ignore.entry=ignorando entrada {0} out.adding=adicionando: {0} -out.deflated=(vazio {0}%) +out.deflated=(compactado {0}%) out.stored=(armazenado 0%) out.create=\ criado: {0} out.extracted=extra\u00EDdo: {0} -out.inflated=\ \\cheio: {0} -out.size=(dentro = {0}) (fora= {1}) +out.inflated=\ inflado: {0} +out.size=(entrada = {0}) (sa\u00EDda= {1}) -usage=Uso: arquivos jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] ...\nOp\u00E7\u00F5es:\n -c cria novo arquivo compactado\n -t lista o sum\u00E1rio do arquivo compactado\n -x extrai arquivos com o nome (ou todos) do arquivo compactado\n -u atualizar o arquivo compactado existente\n -v gera sa\u00EDda detalhada na sa\u00EDda padr\u00E3o\n -f especifica o nome do arquivo do arquivo compactado\n -m inclui as informa\u00E7\u00F5es do manifesto do arquivo de manifesto especificado\n -e especifica o ponto de entrada da aplica\u00E7\u00E3o para aplica\u00E7\u00E3o independente \n empacotado em um arquivo jar execut\u00E1vel\n -p especifca o nome do perfil\n -0 armazena somente; n\u00E3o usa compacta\u00E7\u00E3o ZIP\n -M n\u00E3o cria um arquivo de manifesto para as entradas\n -i gera informa\u00E7\u00F5es de \u00EDndice para os arquivos especificados\n -C altera para o diret\u00F3rio e inclui o arquivo seguinte\nSe nenhum arquivo for um diret\u00F3rio, ent\u00E3o ser\u00E1 processado repetidamente.\nO nome do arquivo de manifesto, o nome do arquivo compactado e o nome do ponto de entrada s\u00E3o\nespecificados na mesma ordem dos flags 'm', 'f' e 'e'.\n\nExemplo 1: para arquivar dois arquivos de classe em um arquivo compactado com o nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExemplo 2: use um arquivo de manifesto existente 'mymanifest' e arquive todos os\n arquivos no diret\u00F3rio foo/ na 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Uso: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] arquivos ...\nOp\u00E7\u00F5es:\n -c cria novo arquivo compactado\n -t lista o sum\u00E1rio do arquivo compactado\n -x extrai arquivos com o nome (ou todos) do arquivo compactado\n -u atualizar o arquivo compactado existente\n -v gera sa\u00EDda detalhada na sa\u00EDda padr\u00E3o\n -f especifica o nome do arquivo do arquivo compactado\n -m inclui as informa\u00E7\u00F5es do manifesto do arquivo de manifesto especificado\n -e especifica o ponto de entrada da aplica\u00E7\u00E3o para aplica\u00E7\u00E3o independente \n empacotando em um arquivo jar execut\u00E1vel\n -0 armazena somente; n\u00E3o usa compacta\u00E7\u00E3o ZIP\n -M n\u00E3o cria um arquivo de manifesto para as entradas\n -i gera informa\u00E7\u00F5es de \u00EDndice para os arquivos especificados\n -C altera para o diret\u00F3rio e inclui o arquivo seguinte\nSe nenhum arquivo for um diret\u00F3rio, ent\u00E3o ser\u00E1 processado repetidamente.\nO nome do arquivo de manifesto, o nome do arquivo compactado e o nome do ponto de entrada s\u00E3o\nespecificados na mesma ordem dos flags 'm', 'f' e 'e'.\n\nExemplo 1: para arquivar dois arquivos de classe em um arquivo compactado com o nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExemplo 2: use um arquivo de manifesto existente 'mymanifest' e arquive todos os\n arquivos no diret\u00F3rio foo/ na 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties index e91207a7151..a90708825c1 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_sv.properties @@ -29,7 +29,6 @@ error.bad.option=Ett av alternativen -{ctxu} m\u00E5ste anges. error.bad.cflag=f\u00F6r c-flaggan m\u00E5ste manifest- eller indatafiler anges. error.bad.uflag=f\u00F6r u-flaggan m\u00E5ste manifest-, e-flagg- eller indatafiler anges. error.bad.eflag=e-flaggan och manifest med attributet Main-Class kan inte anges \ntillsammans. -error.bad.pvalue=felaktigt v\u00E4rde f\u00F6r ''Profile''-attribut: {0} error.nosuch.fileordir={0} : det finns ingen s\u00E5dan fil eller katalog error.write.file=Det uppstod ett fel vid skrivning till befintlig jar-fil. error.create.dir={0} : kunde inte skapa n\u00E5gon katalog @@ -45,4 +44,4 @@ out.extracted=extraherat: {0} out.inflated=\ uppackat: {0} out.size=(in = {0}) (ut = {1}) -usage=Syntax: jar {ctxui}[vfm0Me] [jar-fil] [manifestfil] [startpunkt] [-C katalog] filer ...\nAlternativ:\n -c skapa nytt arkiv\n -t lista inneh\u00E5llsf\u00F6rteckning f\u00F6r arkiv\n -x extrahera namngivna (eller alla) filer fr\u00E5n arkiv\n -u uppdatera befintligt arkiv\n -v generera utf\u00F6rliga utdata vid standardutmatning\n -f ange arkivfilens namn\n -m inkludera manifestinformation fr\u00E5n angivet manifest\n -e ange programstartpunkt f\u00F6r frist\u00E5ende applikation \n som medf\u00F6ljer i en jar-programfil\n -p ange profilnamn\n -0 endast lagra (ingen zip-komprimering)\n -M skapa inte n\u00E5gon manifestfil f\u00F6r posterna\n -i generera indexinformation f\u00F6r de angivna jar-filerna\n -C \u00E4ndra till den angivna katalogen och inkludera f\u00F6ljande fil\nOm en fil \u00E4r en katalog bearbetas den rekursivt.\nNamnen p\u00E5 manifestfilen, arkivfilen och startpunkten anges\ni samma ordning som m-, f- och e-flaggorna.\n\nExempel 1: S\u00E5 h\u00E4r arkiverar du tv\u00E5 klassfiler i ett arkiv med namnet classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExempel 2: Anv\u00E4nd en befintlig manifestfil (mymanifest) och arkivera alla\n filer fr\u00E5n katalogen foo/ i classes.jar: \n jar cvfm classes.jar mymanifest -C foo/ .\n +usage=Syntax: jar {ctxui}[vfm0Me] [jar fil] [manifestfil] [startpunkt] [-C-katalog] ...\nAlternativ:\n -c skapa nytt arkiv\n -t lista inneh\u00E5llsf\u00F6rteckning f\u00F6r arkiv\n -x extrahera namngivna (eller alla) filer fr\u00E5n arkiv\n -u uppdatera befintligt arkiv\n -v generera utf\u00F6rliga utdata vid standardutmatning\n -f ange arkivfilens namn\n -m inkludera manifestinformation fr\u00E5n angivet manifest\n -e ange programstartpunkt f\u00F6r frist\u00E5ende applikation \n som medf\u00F6ljer i en jar-programfil\n -0 endast lagra (ingen zip-komprimering)\n -M skapa inte n\u00E5gon manifestfil f\u00F6r posterna\n -i generera indexinformation f\u00F6r de angivna jar-filerna\n -C \u00E4ndra till den angivna katalogen och inkludera f\u00F6ljande fil\nOm en fil \u00E4r en katalog bearbetas den rekursivt.\nNamnen p\u00E5 manifestfilen, arkivfilen och startpunkten anges i samma\nordning som m-, f- och e-flaggorna.\n\nExempel 1: S\u00E5 h\u00E4r arkiverar du tv\u00E5 klassfiler i ett arkiv med namnet classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExempel 2: Anv\u00E4nd en befintlig manifestfil (mymanifest) och arkivera alla\n filer fr\u00E5n katalogen foo/ i classes.jar: \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties index 250bf2b783e..2ee8e568ffa 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_CN.properties @@ -29,7 +29,6 @@ error.bad.option=\u5FC5\u987B\u6307\u5B9A {ctxu} \u4E2D\u7684\u4EFB\u4E00\u9009\ error.bad.cflag='c' \u6807\u8BB0\u8981\u6C42\u6307\u5B9A\u6E05\u5355\u6216\u8F93\u5165\u6587\u4EF6! error.bad.uflag='u' \u6807\u8BB0\u8981\u6C42\u6307\u5B9A\u6E05\u5355, 'e' \u6807\u8BB0\u6216\u8F93\u5165\u6587\u4EF6! error.bad.eflag=\u4E0D\u80FD\u540C\u65F6\u6307\u5B9A 'e' \u6807\u8BB0\u548C\u5177\u6709 'Main-Class' \u5C5E\u6027\u7684\n\u6E05\u5355! -error.bad.pvalue=''Profile'' \u5C5E\u6027\u7684\u503C\u9519\u8BEF: {0} error.nosuch.fileordir={0}: \u6CA1\u6709\u8FD9\u4E2A\u6587\u4EF6\u6216\u76EE\u5F55 error.write.file=\u5199\u5165\u73B0\u6709\u7684 jar \u6587\u4EF6\u65F6\u51FA\u9519 error.create.dir={0}: \u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55 @@ -45,4 +44,4 @@ out.extracted=\u5DF2\u63D0\u53D6: {0} out.inflated=\ \u5DF2\u89E3\u538B: {0} out.size=(\u8F93\u5165 = {0}) (\u8F93\u51FA = {1}) -usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u9009\u9879:\n -c \u521B\u5EFA\u65B0\u6863\u6848\n -t \u5217\u51FA\u6863\u6848\u76EE\u5F55\n -x \u4ECE\u6863\u6848\u4E2D\u63D0\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6587\u4EF6\n -u \u66F4\u65B0\u73B0\u6709\u6863\u6848\n -v \u5728\u6807\u51C6\u8F93\u51FA\u4E2D\u751F\u6210\u8BE6\u7EC6\u8F93\u51FA\n -f \u6307\u5B9A\u6863\u6848\u6587\u4EF6\u540D\n -m \u5305\u542B\u6307\u5B9A\u6E05\u5355\u6587\u4EF6\u4E2D\u7684\u6E05\u5355\u4FE1\u606F\n -e \u4E3A\u7ED1\u5B9A\u5230\u53EF\u6267\u884C jar \u6587\u4EF6\u7684\u72EC\u7ACB\u5E94\u7528\u7A0B\u5E8F\n \u6307\u5B9A\u5E94\u7528\u7A0B\u5E8F\u5165\u53E3\u70B9\n -p \u6307\u5B9A\u914D\u7F6E\u6587\u4EF6\u540D\u79F0\n -0 \u4EC5\u5B58\u50A8; \u4E0D\u4F7F\u7528\u4EFB\u4F55 ZIP \u538B\u7F29\n -M \u4E0D\u521B\u5EFA\u6761\u76EE\u7684\u6E05\u5355\u6587\u4EF6\n -i \u4E3A\u6307\u5B9A\u7684 jar \u6587\u4EF6\u751F\u6210\u7D22\u5F15\u4FE1\u606F\n -C \u66F4\u6539\u4E3A\u6307\u5B9A\u7684\u76EE\u5F55\u5E76\u5305\u542B\u4EE5\u4E0B\u6587\u4EF6\n\u5982\u679C\u6587\u4EF6\u4E3A\u76EE\u5F55, \u5219\u5BF9\u5176\u8FDB\u884C\u9012\u5F52\u5904\u7406\u3002\n\u6E05\u5355\u6587\u4EF6\u540D, \u6863\u6848\u6587\u4EF6\u540D\u548C\u5165\u53E3\u70B9\u540D\u79F0\u7684\u6307\u5B9A\u987A\u5E8F\n\u4E0E 'm', 'f' \u548C 'e' \u6807\u8BB0\u7684\u6307\u5B9A\u987A\u5E8F\u76F8\u540C\u3002\n\n\u793A\u4F8B 1: \u5C06\u4E24\u4E2A\u7C7B\u6587\u4EF6\u5F52\u6863\u5230\u4E00\u4E2A\u540D\u4E3A classes.jar \u7684\u6863\u6848\u4E2D: \n jar cvf classes.jar Foo.class Bar.class \n\u793A\u4F8B 2: \u4F7F\u7528\u73B0\u6709\u7684\u6E05\u5355\u6587\u4EF6 'mymanifest' \u5E76\n \u5C06 foo/ \u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u5F52\u6863\u5230 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/\u3002\n +usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u9009\u9879\u5305\u62EC: \n -c \u521B\u5EFA\u65B0\u7684\u5F52\u6863\u6587\u4EF6\n -t \u5217\u51FA\u5F52\u6863\u76EE\u5F55\n -x \u4ECE\u6863\u6848\u4E2D\u63D0\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6587\u4EF6\n -u \u66F4\u65B0\u73B0\u6709\u7684\u5F52\u6863\u6587\u4EF6\n -v \u5728\u6807\u51C6\u8F93\u51FA\u4E2D\u751F\u6210\u8BE6\u7EC6\u8F93\u51FA\n -f \u6307\u5B9A\u5F52\u6863\u6587\u4EF6\u540D\n -m \u5305\u542B\u6307\u5B9A\u6E05\u5355\u6587\u4EF6\u4E2D\u7684\u6E05\u5355\u4FE1\u606F\n -e \u4E3A\u6346\u7ED1\u5230\u53EF\u6267\u884C jar \u6587\u4EF6\u7684\u72EC\u7ACB\u5E94\u7528\u7A0B\u5E8F\n \u6307\u5B9A\u5E94\u7528\u7A0B\u5E8F\u5165\u53E3\u70B9\n -0 \u4EC5\u5B58\u50A8; \u4E0D\u4F7F\u7528\u60C5\u51B5\u4EFB\u4F55 ZIP \u538B\u7F29\n -M \u4E0D\u521B\u5EFA\u6761\u76EE\u7684\u6E05\u5355\u6587\u4EF6\n -i \u4E3A\u6307\u5B9A\u7684 jar \u6587\u4EF6\u751F\u6210\u7D22\u5F15\u4FE1\u606F\n -C \u66F4\u6539\u4E3A\u6307\u5B9A\u7684\u76EE\u5F55\u5E76\u5305\u542B\u5176\u4E2D\u7684\u6587\u4EF6\n\u5982\u679C\u6709\u4EFB\u4F55\u76EE\u5F55\u6587\u4EF6, \u5219\u5BF9\u5176\u8FDB\u884C\u9012\u5F52\u5904\u7406\u3002\n\u6E05\u5355\u6587\u4EF6\u540D, \u5F52\u6863\u6587\u4EF6\u540D\u548C\u5165\u53E3\u70B9\u540D\u79F0\u7684\u6307\u5B9A\u987A\u5E8F\n\u4E0E 'm', 'f' \u548C 'e' \u6807\u8BB0\u7684\u6307\u5B9A\u987A\u5E8F\u76F8\u540C\u3002\n\n\u793A\u4F8B 1: \u5C06\u4E24\u4E2A\u7C7B\u6587\u4EF6\u5F52\u6863\u5230\u4E00\u4E2A\u540D\u4E3A classes.jar \u7684\u5F52\u6863\u6587\u4EF6\u4E2D: \n jar cvf classes.jar Foo.class Bar.class \n\u793A\u4F8B 2: \u4F7F\u7528\u73B0\u6709\u7684\u6E05\u5355\u6587\u4EF6 'mymanifest' \u5E76\n \u5C06 foo/ \u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u5F52\u6863\u5230 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/\u3002\n diff --git a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties index ff5eedccaa8..7dd4f65390b 100644 --- a/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties +++ b/jdk/src/share/classes/sun/tools/jar/resources/jar_zh_TW.properties @@ -29,7 +29,6 @@ error.bad.option=\u5176\u4E2D\u4E00\u500B\u9078\u9805 -{ctxu} \u5FC5\u9808\u52A0 error.bad.cflag='c' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u6216\u8F38\u5165\u6A94\u6848\uFF01 error.bad.uflag='u' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u3001'e' \u65D7\u6A19\u6216\u8F38\u5165\u6A94\u6848\uFF01 error.bad.eflag=\u7121\u6CD5\u540C\u6642\u6307\u5B9A 'e' \u65D7\u6A19\u548C\u5177\u6709 'Main-Class' \u5C6C\u6027\u7684\n\u8CC7\u8A0A\u6E05\u55AE\uFF01 -error.bad.pvalue=''Profile'' \u5C6C\u6027\u503C\u7121\u6548: {0} error.nosuch.fileordir={0} : \u6C92\u6709\u9019\u985E\u6A94\u6848\u6216\u76EE\u9304 error.write.file=\u5BEB\u5165\u73FE\u6709\u7684 jar \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4 error.create.dir={0} : \u7121\u6CD5\u5EFA\u7ACB\u76EE\u9304 @@ -42,7 +41,7 @@ out.deflated=(\u58D3\u7E2E {0}%) out.stored=(\u5132\u5B58 0%) out.create=\ \u5EFA\u7ACB: {0} out.extracted=\u64F7\u53D6: {0} -out.inflated=\ \\\u64F4\u5C55: {0} +out.inflated=\ \u64F4\u5C55: {0} out.size=\ (\u8B80={0})(\u5BEB={1}) -usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u9078\u9805:\n -c \u5EFA\u7ACB\u65B0\u7684\u5B58\u6A94\n -t \u5217\u51FA\u5B58\u6A94\u7684\u76EE\u9304\n -x \u5F9E\u5B58\u6A94\u4E2D\u64F7\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6A94\u6848\n -u \u66F4\u65B0\u73FE\u6709\u5B58\u6A94\n -v \u5728\u6A19\u6E96\u8F38\u51FA\u7522\u751F\u8A73\u7D30\u8F38\u51FA\n -f \u6307\u5B9A\u5B58\u6A94\u6A94\u6848\u540D\u7A31\n -m \u5305\u542B\u6307\u5B9A\u4E4B\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u4E2D\u7684\u8CC7\u8A0A\u6E05\u55AE\u8CC7\u8A0A\n -e \u6307\u5B9A\u7368\u7ACB\u61C9\u7528\u7A0B\u5F0F\u7684\u61C9\u7528\u7A0B\u5F0F\u9032\u5165\u9EDE \n \u5DF2\u96A8\u9644\u65BC\u53EF\u57F7\u884C jar \u6A94\u6848\u4E2D\n -p \u6307\u5B9A\u8A2D\u5B9A\u6A94\u540D\u7A31\n -0 \u53EA\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F\n -M \u4E0D\u66FF\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\n -i \u7522\u751F\u6307\u5B9A\u4E4B jar \u6A94\u6848\u7684\u7D22\u5F15\u8CC7\u8A0A\n -C \u8B8A\u66F4\u81F3\u6307\u5B9A\u7684\u76EE\u9304\u4E26\u5305\u542B\u4E0B\u5217\u6A94\u6848\n\u5982\u679C\u6709\u4EFB\u4F55\u6A94\u6848\u662F\u76EE\u9304\uFF0C\u5247\u6703\u905E\u8FF4\u5730\u8655\u7406\u6A94\u6848\u3002\n\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u540D\u7A31\u3001\u5B58\u6A94\u6A94\u6848\u540D\u7A31\u4EE5\u53CA\u9032\u5165\u9EDE\u540D\u7A31\u7684\n\u6307\u5B9A\u9806\u5E8F\u8207 'm' \u65D7\u6A19\u3001'f' \u65D7\u6A19\u548C 'e' \u65D7\u6A19\u7684\u9806\u5E8F\u76F8\u540C\u3002\n\n\u7BC4\u4F8B 1: \u5C07\u5169\u500B\u985E\u5225\u6A94\u6848\u5B58\u6A94\u81F3\u540D\u70BA classes.jar \u7684\u5B58\u6A94\u4E2D: \n jar cvf classes.jar Foo.class Bar.class \n\u7BC4\u4F8B 2: \u4F7F\u7528\u73FE\u6709\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848 'mymanifest'\uFF0C\u5C07 foo/ \u76EE\u9304\n \u4E2D\u7684\u6240\u6709\u6A94\u6848\u5B58\u6A94\u81F3 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/ \n +usage=\u7528\u6CD5: jar {ctxui}[vfm0Me] [jar-file] [manifest-file] [entry-point] [-C dir] \u6A94\u6848 ...\n\u9078\u9805:\n -c \u5EFA\u7ACB\u65B0\u7684\u6B78\u6A94\n -t \u5217\u51FA\u6B78\u6A94\u7684\u76EE\u9304\n -x \u5F9E\u6B78\u6A94\u4E2D\u64F7\u53D6\u5DF2\u547D\u540D\u7684 (\u6216\u6240\u6709) \u6A94\u6848\n -u \u66F4\u65B0\u73FE\u6709\u6B78\u6A94\n -v \u5728\u6A19\u6E96\u8F38\u51FA\u4E2D\u7522\u751F\u8A73\u7D30\u8F38\u51FA\n -f \u6307\u5B9A\u6B78\u6A94\u6A94\u6848\u540D\u7A31\n -m \u5305\u542B\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u4E2D\u7684\u8CC7\u8A0A\u6E05\u55AE\u8CC7\u8A0A\n -e \u70BA\u7368\u7ACB\u61C9\u7528\u7A0B\u5F0F\u6307\u5B9A\u61C9\u7528\u7A0B\u5F0F\u9032\u5165\u9EDE\n \u5DF2\u96A8\u9644\u65BC\u53EF\u57F7\u884C jar \u6A94\u6848\u4E2D\n -0 \u50C5\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F\n -M \u4E0D\u70BA\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\n -i \u70BA\u6307\u5B9A\u7684 jar \u6A94\u6848\u7522\u751F\u7D22\u5F15\u8CC7\u8A0A\n -C \u8B8A\u66F4\u81F3\u6307\u5B9A\u76EE\u9304\u4E26\u5305\u542B\u5F8C\u9762\u6240\u5217\u7684\u6A94\u6848\n\u5982\u679C\u6709\u4EFB\u4F55\u6A94\u6848\u662F\u76EE\u9304\uFF0C\u5247\u6703\u5C0D\u5176\u9032\u884C\u905E\u8FF4\u8655\u7406\u3002\n\u6E05\u55AE\u6A94\u6848\u540D\u7A31\u3001\u6B78\u6A94\u6A94\u6848\u540D\u7A31\u548C\u9032\u5165\u9EDE\u540D\u7A31\n\u7684\u6307\u5B9A\u9806\u5E8F\u8207\u6307\u5B9A 'm' \u65D7\u6A19\u3001'f' \u65D7\u6A19\u548C 'e' \u65D7\u6A19\u7684\u9806\u5E8F\u76F8\u540C\u3002\n\n\u7BC4\u4F8B 1: \u5C07\u5169\u500B\u985E\u5225\u6A94\u6848\u6B78\u6A94\u81F3\u540D\u70BA classes.jar \u7684\u6B78\u6A94\u4E2D: \n jar cvf classes.jar Foo.class Bar.class\n\u7BC4\u4F8B 2: \u4F7F\u7528\u73FE\u6709\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848 'mymanifest' \u4E26\u5C07\n foo/ \u76EE\u9304\u4E2D\u7684\u6240\u6709\u6A94\u6848\u6B78\u6A94\u81F3 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/ .\n diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties index c66ace77035..7c14da631e1 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties @@ -113,6 +113,7 @@ HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION=Hotspot MBeans\u306E\u7BA1\u7406\u7 IMPACT=\u5F71\u97FF INFO=\u60C5\u5831 INFO_CAPITALIZED=INFO +INSECURE=\u4FDD\u8B77\u3055\u308C\u3066\u3044\u306A\u3044\u63A5\u7D9A INVALID_PLUGIN_PATH=\u8B66\u544A: \u7121\u52B9\u306A\u30D7\u30E9\u30B0\u30A4\u30F3\u30FB\u30D1\u30B9: {0} INVALID_URL=\u7121\u52B9\u306AURL: {0} IS=\u6B21\u306B\u4E00\u81F4\u3059\u308B @@ -135,14 +136,14 @@ MBEAN_OPERATION_INFO=MBeanOperationInfo MBEANS=MBeans MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=\u30AF\u30EA\u30A2(&C) MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=\u901A\u77E5\u306E\u30AF\u30EA\u30A2 -MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} -MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 +MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} +MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u30B3\u30F3\u30DD\u30B8\u30C3\u30C8\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5(&R) MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=\u5C5E\u6027\u306E\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5 MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=\u30B5\u30D6\u30B9\u30AF\u30E9\u30A4\u30D6(&S) MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u901A\u77E5\u30EA\u30B9\u30CB\u30F3\u30B0\u306E\u958B\u59CB -MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u30BF\u30D6\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} -MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u30BF\u30D6\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 +MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u30BF\u30D6\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3{0}/{1} +MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u30BF\u30D6\u30FB\u30C7\u30FC\u30BF\u30FB\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3 MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=\u30B5\u30D6\u30B9\u30AF\u30E9\u30A4\u30D6\u89E3\u9664(&U) MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u901A\u77E5\u30EA\u30B9\u30CB\u30F3\u30B0\u306E\u505C\u6B62 MANAGE_HOTSPOT_MBEANS_IN_COLON_=Hotspot MBeans\u306E\u7BA1\u7406: @@ -196,6 +197,11 @@ PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE={0}={1}\n PLOTTER_ACCESSIBLE_NAME_NO_DATA=\u30C7\u30FC\u30BF\u304C\u30D7\u30ED\u30C3\u30C8\u3055\u308C\u307E\u305B\u3093\u3002 PLOTTER_SAVE_AS_MENU_ITEM=\u540D\u524D\u3092\u4ED8\u3051\u3066\u30C7\u30FC\u30BF\u3092\u4FDD\u5B58(&A)... PLOTTER_TIME_RANGE_MENU=\u6642\u9593\u7BC4\u56F2(&T) +PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT=\u7D42\u4E86 +PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE=\u7121\u8996 +PLUGIN_EXCEPTION_DIALOG_BUTTON_OK=OK +PLUGIN_EXCEPTION_DIALOG_MESSAGE=%s\u3067\u4E88\u671F\u3057\u306A\u3044\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F:\n\n%s\n\n\u8A73\u7D30\u306F\u3001\u5148\u982D\u306B-debug\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u7121\u8996\u3059\u308B\u3068\u3001\u4F8B\u5916\u306F\u3053\u308C\u4EE5\u4E0A\u8868\u793A\u3055\u308C\u306A\u304F\u306A\u308A\u307E\u3059\u3002 +PLUGIN_EXCEPTION_DIALOG_TITLE=\u30D7\u30E9\u30B0\u30A4\u30F3\u4F8B\u5916 PROBLEM_ADDING_LISTENER=\u30EA\u30B9\u30CA\u30FC\u8FFD\u52A0\u4E2D\u306E\u554F\u984C PROBLEM_DISPLAYING_MBEAN=MBean\u8868\u793A\u4E2D\u306E\u554F\u984C PROBLEM_INVOKING=\u547C\u51FA\u3057\u4E2D\u306E\u554F\u984C @@ -223,6 +229,7 @@ SUMMARY_TAB_VM_VERSION={0}\u30D0\u30FC\u30B8\u30E7\u30F3{1} THREADS=\u30B9\u30EC\u30C3\u30C9 THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=\u30B9\u30EC\u30C3\u30C9\u60C5\u5831 THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=\u30B9\u30EC\u30C3\u30C9\u6570\u306E\u30C1\u30E3\u30FC\u30C8\u3002 +THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[\u30B9\u30EC\u30C3\u30C9\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093] THRESHOLD=\u3057\u304D\u3044\u5024 TILE=\u4E26\u3079\u3066\u8868\u793A(&T) TIME_RANGE_COLON=\u6642\u9593\u7BC4\u56F2(&T): @@ -260,6 +267,8 @@ WINDOWS=\u30A6\u30A3\u30F3\u30C9\u30A6 WRITABLE=\u66F8\u8FBC\u307F\u53EF\u80FD CONNECTION_FAILED1=\u63A5\u7D9A\u306B\u5931\u6557\u3057\u307E\u3057\u305F: \u518D\u8A66\u884C\u3057\u307E\u3059\u304B\u3002 CONNECTION_FAILED2={0}\u3078\u306E\u63A5\u7D9A\u304C\u6210\u529F\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002
    \u3082\u3046\u4E00\u5EA6\u8A66\u3057\u307E\u3059\u304B\u3002 +CONNECTION_FAILED_SSL1=\u4FDD\u8B77\u3055\u308C\u305F\u63A5\u7D9A\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u4FDD\u8B77\u305B\u305A\u306B\u518D\u8A66\u884C\u3057\u307E\u3059\u304B\u3002 +CONNECTION_FAILED_SSL2=SSL\u3092\u4F7F\u7528\u3057\u3066{0}\u306B\u63A5\u7D9A\u3067\u304D\u307E\u305B\u3093\u3002
    SSL\u306A\u3057\u3067\u63A5\u7D9A\u3057\u307E\u3059\u304B\u3002
    (\u30E6\u30FC\u30B6\u30FC\u540D\u304A\u3088\u3073\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u30D7\u30EC\u30FC\u30F3\u30FB\u30C6\u30AD\u30B9\u30C8\u3067\u9001\u4FE1\u3055\u308C\u307E\u3059\u3002) CONNECTION_LOST1=\u63A5\u7D9A\u304C\u5931\u308F\u308C\u307E\u3057\u305F: \u518D\u63A5\u7D9A\u3057\u307E\u3059\u304B\u3002 CONNECTING_TO1={0}\u306B\u63A5\u7D9A\u4E2D CONNECTING_TO2={0}\u306B\u73FE\u5728\u63A5\u7D9A\u4E2D\u3067\u3059\u3002
    \u3053\u308C\u306B\u306F\u6570\u5206\u304B\u304B\u308A\u307E\u3059\u3002 diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties index 3f782adc620..eff5155bce7 100644 --- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties +++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties @@ -113,6 +113,7 @@ HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION=\u7528\u4E8E\u7BA1\u7406 HotSpot MB IMPACT=\u5F71\u54CD INFO=\u4FE1\u606F INFO_CAPITALIZED=\u4FE1\u606F +INSECURE=\u4E0D\u5B89\u5168\u7684\u8FDE\u63A5 INVALID_PLUGIN_PATH=\u8B66\u544A: \u63D2\u4EF6\u8DEF\u5F84\u65E0\u6548: {0} INVALID_URL=URL \u65E0\u6548: {0} IS=\u662F @@ -135,14 +136,14 @@ MBEAN_OPERATION_INFO=MBeanOperationInfo MBEANS=MBean MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=\u6E05\u9664(&C) MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=\u6E05\u9664\u901A\u77E5 -MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u7EC4\u5408\u5BFC\u822A{0}/{1} -MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u7EC4\u5408\u5BFC\u822A +MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=\u7EC4\u5408\u6570\u636E\u5BFC\u822A{0}/{1} +MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=\u7EC4\u5408\u6570\u636E\u5BFC\u822A MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=\u5237\u65B0(&R) MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=\u5237\u65B0\u5C5E\u6027 MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=\u8BA2\u9605(&S) MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u5F00\u59CB\u76D1\u542C\u901A\u77E5 -MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u8868\u683C\u5F0F\u5BFC\u822A{0}/{1} -MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u8868\u683C\u5F0F\u5BFC\u822A +MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=\u8868\u683C\u5F0F\u6570\u636E\u5BFC\u822A{0}/{1} +MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=\u8868\u683C\u5F0F\u6570\u636E\u5BFC\u822A MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=\u53D6\u6D88\u8BA2\u9605(&U) MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=\u505C\u6B62\u76D1\u542C\u901A\u77E5 MANAGE_HOTSPOT_MBEANS_IN_COLON_=\u7BA1\u7406\u4EE5\u4E0B\u4F4D\u7F6E\u7684 HotSpot MBean: @@ -196,6 +197,11 @@ PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE={0}={1}\n PLOTTER_ACCESSIBLE_NAME_NO_DATA=\u672A\u7ED8\u5236\u6570\u636E\u3002 PLOTTER_SAVE_AS_MENU_ITEM=\u5C06\u6570\u636E\u53E6\u5B58\u4E3A(&A)... PLOTTER_TIME_RANGE_MENU=\u65F6\u95F4\u8303\u56F4(&T) +PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT=\u9000\u51FA +PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE=\u5FFD\u7565 +PLUGIN_EXCEPTION_DIALOG_BUTTON_OK=\u786E\u5B9A +PLUGIN_EXCEPTION_DIALOG_MESSAGE=%s \u4E2D\u51FA\u73B0\u610F\u5916\u7684\u5F02\u5E38\u9519\u8BEF:\n\n%s\n\n\u6709\u5173\u8BE6\u7EC6\u4FE1\u606F, \u8BF7\u8FD0\u884C\u4EE5 -debug \u5F00\u5934\u7684\u547D\u4EE4\u83B7\u53D6\u3002\u5982\u679C\u5FFD\u7565, \u5219\u5C06\u9690\u85CF\u540E\u9762\u7684\u5F02\u5E38\u9519\u8BEF\u3002 +PLUGIN_EXCEPTION_DIALOG_TITLE=\u63D2\u4EF6\u5F02\u5E38\u9519\u8BEF PROBLEM_ADDING_LISTENER=\u6DFB\u52A0\u76D1\u542C\u7A0B\u5E8F\u65F6\u51FA\u73B0\u95EE\u9898 PROBLEM_DISPLAYING_MBEAN=\u663E\u793A MBean \u65F6\u51FA\u73B0\u95EE\u9898 PROBLEM_INVOKING=\u8C03\u7528\u65F6\u51FA\u73B0\u95EE\u9898 @@ -223,6 +229,7 @@ SUMMARY_TAB_VM_VERSION={0}\u7248\u672C {1} THREADS=\u7EBF\u7A0B THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=\u7EBF\u7A0B\u4FE1\u606F THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=\u8868\u793A\u7EBF\u7A0B\u6570\u7684\u56FE\u8868\u3002 +THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[\u672A\u9009\u62E9\u7EBF\u7A0B] THRESHOLD=\u9608\u503C TILE=\u5E73\u94FA(&T) TIME_RANGE_COLON=\u65F6\u95F4\u8303\u56F4(&T): @@ -260,6 +267,8 @@ WINDOWS=\u7A97\u53E3 WRITABLE=\u53EF\u5199\u5165 CONNECTION_FAILED1=\u8FDE\u63A5\u5931\u8D25: \u662F\u5426\u91CD\u8BD5? CONNECTION_FAILED2=\u672A\u6210\u529F\u8FDE\u63A5\u5230{0}\u3002
    \u662F\u5426\u8981\u91CD\u8BD5? +CONNECTION_FAILED_SSL1=\u5B89\u5168\u8FDE\u63A5\u5931\u8D25\u3002\u662F\u5426\u4EE5\u4E0D\u5B89\u5168\u7684\u65B9\u5F0F\u91CD\u8BD5? +CONNECTION_FAILED_SSL2=\u65E0\u6CD5\u4F7F\u7528 SSL \u8FDE\u63A5\u5230{0}\u3002
    \u662F\u5426\u5728\u4E0D\u4F7F\u7528 SSL \u7684\u60C5\u51B5\u4E0B\u8FDB\u884C\u5C1D\u8BD5?
    (\u7528\u6237\u540D\u548C\u53E3\u4EE4\u5C06\u4EE5\u7EAF\u6587\u672C\u683C\u5F0F\u53D1\u9001\u3002) CONNECTION_LOST1=\u8FDE\u63A5\u4E22\u5931: \u662F\u5426\u91CD\u65B0\u8FDE\u63A5? CONNECTING_TO1=\u6B63\u5728\u8FDE\u63A5\u5230{0} CONNECTING_TO2=\u60A8\u5F53\u524D\u6B63\u5728\u8FDE\u63A5\u5230{0}\u3002
    \u8FD9\u5C06\u9700\u8981\u51E0\u5206\u949F\u7684\u65F6\u95F4\u3002 From 072f43e117657352a099187cbf051e407038b70b Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Tue, 24 Sep 2013 14:20:33 -0700 Subject: [PATCH 180/293] 8025215: jdk8 l10n resource file translation update 4 Reviewed-by: naoto, yhuang --- .../html/resources/standard_ja.properties | 8 ++--- .../html/resources/standard_zh_CN.properties | 6 ++-- .../toolkit/resources/doclets_ja.properties | 14 ++++++-- .../resources/doclets_zh_CN.properties | 14 ++++++-- .../doclint/resources/doclint_ja.properties | 9 +++++- .../resources/doclint_zh_CN.properties | 8 ++++- .../javac/resources/compiler_ja.properties | 32 ++++++++++++++++--- .../javac/resources/compiler_zh_CN.properties | 32 ++++++++++++++++--- .../tools/javac/resources/javac_ja.properties | 11 +++++-- .../javac/resources/javac_zh_CN.properties | 11 +++++-- .../javadoc/resources/javadoc_ja.properties | 11 +++++-- .../resources/javadoc_zh_CN.properties | 11 +++++-- .../tools/javah/resources/l10n_ja.properties | 7 ++-- .../javah/resources/l10n_zh_CN.properties | 5 +-- .../tools/javap/resources/javap_ja.properties | 4 ++- .../javap/resources/javap_zh_CN.properties | 4 ++- 16 files changed, 145 insertions(+), 42 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties index 373b5334c42..5592f1032d6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_ja.properties @@ -185,9 +185,9 @@ doclet.Error_in_packagelist=-group\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u4F7F\u75 doclet.Groupname_already_used=-group\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u304A\u3044\u3066\u3001\u3059\u3067\u306B\u30B0\u30EB\u30FC\u30D7\u540D\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059: {0} doclet.Same_package_name_used=\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u5F62\u5F0F\u304C2\u56DE\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059: {0} doclet.exception_encountered={1}\u306E\u51E6\u7406\u4E2D\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002\n{0} -doclet.usage=\u6A19\u6E96\u306Edoclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:\n-d \u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n-use \u30AF\u30E9\u30B9\u3068\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4F7F\u7528\u30DA\u30FC\u30B8\u3092\u4F5C\u6210\u3059\u308B\n-version @version\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-author @author\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-docfilessubdirs doc-file\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u518D\u5E30\u7684\u306B\u30B3\u30D4\u30FC\u3059\u308B\n-splitindex 1\u5B57\u3054\u3068\u306B1\u30D5\u30A1\u30A4\u30EB\u306B\u7D22\u5F15\u3092\u5206\u5272\u3059\u308B\n-windowtitle \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7528\u306E\u30D6\u30E9\u30A6\u30B6\u30FB\u30A6\u30A3\u30F3\u30C9\u30A6\u30FB\u30BF\u30A4\u30C8\u30EB\n-doctitle \u6982\u8981\u30DA\u30FC\u30B8\u306B\u30BF\u30A4\u30C8\u30EB\u3092\u542B\u3081\u308B\n-header \u5404\u30DA\u30FC\u30B8\u306B\u30D8\u30C3\u30C0\u30FC\u3092\u542B\u3081\u308B\n-footer \u5404\u30DA\u30FC\u30B8\u306B\u30D5\u30C3\u30BF\u30FC\u3092\u542B\u3081\u308B\n-top \u5404\u30DA\u30FC\u30B8\u306B\u4E0A\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-bottom \u5404\u30DA\u30FC\u30B8\u306B\u4E0B\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-link \u306Bjavadoc\u51FA\u529B\u3078\u306E\u30EA\u30F3\u30AF\u3092\u4F5C\u6210\u3059\u308B\n-linkoffline \u306B\u3042\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u4F7F\u7528\u3057\u3066\u306Edocs\u306B\u30EA\u30F3\u30AF\u3059\u308B\n-excludedocfilessubdir :.. \u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u306Edoc-files\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u3059\u3079\u3066\u9664\u5916\u3059\u308B\n-group :.. \u6307\u5B9A\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6982\u8981\u30DA\u30FC\u30B8\u306B\u304A\u3044\u3066\u30B0\u30EB\u30FC\u30D7\u5316\u3059\u308B\n-nocomment \u8A18\u8FF0\u304A\u3088\u3073\u30BF\u30B0\u3092\u6291\u5236\u3057\u3066\u5BA3\u8A00\u306E\u307F\u3092\u751F\u6210\u3059\u308B\n-nodeprecated @deprecated\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-noqualifier ::... \u51FA\u529B\u304B\u3089\u4FEE\u98FE\u5B50\u306E\u30EA\u30B9\u30C8\u3092\u9664\u5916\u3059\u308B\n-nosince @since\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-notimestamp \u975E\u8868\u793A\u306E\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u3092\u9664\u5916\u3059\u308B\n-nodeprecatedlist \u975E\u63A8\u5968\u306E\u30EA\u30B9\u30C8\u3092\u751F\u6210\u3057\u306A\u3044\n-notree \u30AF\u30E9\u30B9\u968E\u5C64\u3092\u751F\u6210\u3057\u306A\u3044\n-noindex \u7D22\u5F15\u3092\u751F\u6210\u3057\u306A\u3044\n-nohelp \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u3092\u751F\u6210\u3057\u306A\u3044\n-nonavbar \u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30FC\u3092\u751F\u6210\u3057\u306A\u3044\n-serialwarn @serial\u30BF\u30B0\u306B\u95A2\u3059\u308B\u8B66\u544A\u3092\u751F\u6210\u3059\u308B\n-tag ::
    \u5358\u4E00\u306E\u5F15\u6570\u3092\u6301\u3064\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0\u3092\u6307\u5B9A\u3059\u308B\n-taglet \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u5B8C\u5168\u4FEE\u98FE\u540D\u3092\u767B\u9332\u3059\u308B\n-tagletpath \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u30D1\u30B9\n-Xdocrootparent \ - \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30B3\u30E1\u30F3\u30C8\u5185\u306E@docRoot(\u3053\u306E\u5F8C\u306B\u306F/..\u304C\u7D9A\u304F)\u306E\u3059\u3079\u3066\u306E\u51FA\u73FE\u7B87\u6240\u3092\u3067\u7F6E\u63DB\u3059\u308B\n-charset \u751F\u6210\u3055\u308C\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30AF\u30ED\u30B9\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u3067\u306E\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\n-helpfile \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u306E\u30EA\u30F3\u30AF\u5148\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B\n-linksource HTML\u5F62\u5F0F\u3067\u30BD\u30FC\u30B9\u3092\u751F\u6210\u3059\u308B\n-sourcetab \u30BD\u30FC\u30B9\u5185\u306E\u30BF\u30D6\u306E\u7A7A\u767D\u6587\u5B57\u306E\u6570\u3092\u6307\u5B9A\u3059\u308B\n-keywords HTML\u306Emeta\u30BF\u30B0\u306B\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u3001\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u60C5\u5831\u3092\u542B\u3081\u308B\n-stylesheetfile \u751F\u6210\u3055\u308C\u305F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30B9\u30BF\u30A4\u30EB\u5909\u66F4\u7528\u30D5\u30A1\u30A4\u30EB\n-docencoding \u51FA\u529B\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D - - +doclet.usage=\u6A19\u6E96\u306Edoclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:\n-d \u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u8EE2\u9001\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n-use \u30AF\u30E9\u30B9\u3068\u30D1\u30C3\u30B1\u30FC\u30B8\u306E\u4F7F\u7528\u30DA\u30FC\u30B8\u3092\u4F5C\u6210\u3059\u308B\n-version @version\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-author @author\u30D1\u30E9\u30B0\u30E9\u30D5\u3092\u542B\u3081\u308B\n-docfilessubdirs doc-file\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u518D\u5E30\u7684\u306B\u30B3\u30D4\u30FC\u3059\u308B\n-splitindex 1\u5B57\u3054\u3068\u306B1\u30D5\u30A1\u30A4\u30EB\u306B\u7D22\u5F15\u3092\u5206\u5272\u3059\u308B\n-windowtitle \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7528\u306E\u30D6\u30E9\u30A6\u30B6\u30FB\u30A6\u30A3\u30F3\u30C9\u30A6\u30FB\u30BF\u30A4\u30C8\u30EB\n-doctitle \u6982\u8981\u30DA\u30FC\u30B8\u306B\u30BF\u30A4\u30C8\u30EB\u3092\u542B\u3081\u308B\n-header \u5404\u30DA\u30FC\u30B8\u306B\u30D8\u30C3\u30C0\u30FC\u3092\u542B\u3081\u308B\n-footer \u5404\u30DA\u30FC\u30B8\u306B\u30D5\u30C3\u30BF\u30FC\u3092\u542B\u3081\u308B\n-top \u5404\u30DA\u30FC\u30B8\u306B\u4E0A\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-bottom \u5404\u30DA\u30FC\u30B8\u306B\u4E0B\u90E8\u30C6\u30AD\u30B9\u30C8\u3092\u542B\u3081\u308B\n-link \u306Bjavadoc\u51FA\u529B\u3078\u306E\u30EA\u30F3\u30AF\u3092\u4F5C\u6210\u3059\u308B\n-linkoffline \u306B\u3042\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u4F7F\u7528\u3057\u3066\u306Edocs\u306B\u30EA\u30F3\u30AF\u3059\u308B\n-excludedocfilessubdir :.. \u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u306Edoc-files\u30B5\u30D6\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u3059\u3079\u3066\u9664\u5916\u3059\u308B\n-group :.. \u6307\u5B9A\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6982\u8981\u30DA\u30FC\u30B8\u306B\u304A\u3044\u3066\u30B0\u30EB\u30FC\u30D7\u5316\u3059\u308B\n-nocomment \u8A18\u8FF0\u304A\u3088\u3073\u30BF\u30B0\u3092\u6291\u5236\u3057\u3066\u5BA3\u8A00\u306E\u307F\u3092\u751F\u6210\u3059\u308B\n-nodeprecated @deprecated\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-noqualifier ::... \u51FA\u529B\u304B\u3089\u4FEE\u98FE\u5B50\u306E\u30EA\u30B9\u30C8\u3092\u9664\u5916\u3059\u308B\n-nosince @since\u60C5\u5831\u3092\u9664\u5916\u3059\u308B\n-notimestamp \u975E\u8868\u793A\u306E\u30BF\u30A4\u30E0\u30B9\u30BF\u30F3\u30D7\u3092\u9664\u5916\u3059\u308B\n-nodeprecatedlist \u975E\u63A8\u5968\u306E\u30EA\u30B9\u30C8\u3092\u751F\u6210\u3057\u306A\u3044\n-notree \u30AF\u30E9\u30B9\u968E\u5C64\u3092\u751F\u6210\u3057\u306A\u3044\n-noindex \u7D22\u5F15\u3092\u751F\u6210\u3057\u306A\u3044\n-nohelp \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u3092\u751F\u6210\u3057\u306A\u3044\n-nonavbar \u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30FB\u30D0\u30FC\u3092\u751F\u6210\u3057\u306A\u3044\n-serialwarn @serial\u30BF\u30B0\u306B\u95A2\u3059\u308B\u8B66\u544A\u3092\u751F\u6210\u3059\u308B\n-tag ::
    \u5358\u4E00\u306E\u5F15\u6570\u3092\u6301\u3064\u30AB\u30B9\u30BF\u30E0\u30FB\u30BF\u30B0\u3092\u6307\u5B9A\u3059\u308B\n-taglet \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u5B8C\u5168\u4FEE\u98FE\u540D\u3092\u767B\u9332\u3059\u308B\n-tagletpath \u30BF\u30B0\u30EC\u30C3\u30C8\u306E\u30D1\u30B9\n-charset \ + \u751F\u6210\u3055\u308C\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30AF\u30ED\u30B9\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u3067\u306E\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\n-helpfile \u30D8\u30EB\u30D7\u30FB\u30EA\u30F3\u30AF\u306E\u30EA\u30F3\u30AF\u5148\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B\n-linksource HTML\u5F62\u5F0F\u3067\u30BD\u30FC\u30B9\u3092\u751F\u6210\u3059\u308B\n-sourcetab \u30BD\u30FC\u30B9\u5185\u306E\u30BF\u30D6\u306E\u7A7A\u767D\u6587\u5B57\u306E\u6570\u3092\u6307\u5B9A\u3059\u308B\n-keywords HTML\u306Emeta\u30BF\u30B0\u306B\u3001\u30D1\u30C3\u30B1\u30FC\u30B8\u3001\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u60C5\u5831\u3092\u542B\u3081\u308B\n-stylesheetfile \u751F\u6210\u3055\u308C\u305F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30B9\u30BF\u30A4\u30EB\u5909\u66F4\u7528\u30D5\u30A1\u30A4\u30EB\n-docencoding \u51FA\u529B\u306E\u6587\u5B57\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3092\u6307\u5B9A\u3059\u308B +# L10N: do not localize these words: all none accessibility html missing reference syntax +doclet.X.usage=\u6A19\u6E96\u306Edoclet\u306B\u3088\u308A\u63D0\u4F9B\u3055\u308C\u308B\u3082\u306E:\n -Xdocrootparent doc\u30B3\u30E1\u30F3\u30C8\u5185\u306E/..\u304C\u5F8C\u306B\u7D9A\u304F@docRoot\u306E\u3059\u3079\u3066\u3092\n \u3067\u7F6E\u63DB\u3057\u307E\u3059\n -Xdoclint javadoc\u30B3\u30E1\u30F3\u30C8\u5185\u306E\u554F\u984C\u306B\u5BFE\u3059\u308B\u63A8\u5968\u3055\u308C\u308B\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3057\u307E\u3059\n -Xdoclint:(all|none|[-]) \n javadoc\u30B3\u30E1\u30F3\u30C8\u5185\u306E\u554F\u984C\u306B\u5BFE\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n \u3053\u3053\u3067\u3001\u306Fhtml\u3001missing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002\n diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties index 61fd72cbe10..23d1b9b46d1 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard_zh_CN.properties @@ -185,8 +185,8 @@ doclet.Error_in_packagelist=\u4F7F\u7528 -group \u9009\u9879\u65F6\u51FA\u9519: doclet.Groupname_already_used=\u5728 -group \u9009\u9879\u4E2D, groupname \u5DF2\u4F7F\u7528: {0} doclet.Same_package_name_used=\u7A0B\u5E8F\u5305\u540D\u79F0\u5F62\u5F0F\u4F7F\u7528\u4E86\u4E24\u6B21: {0} doclet.exception_encountered=\u5904\u7406{1}\u65F6\u51FA\u73B0\u5F02\u5E38\u9519\u8BEF\n{0} -doclet.usage=\u901A\u8FC7\u6807\u51C6 doclet \u63D0\u4F9B:\n-d \u8F93\u51FA\u6587\u4EF6\u7684\u76EE\u6807\u76EE\u5F55\n-use \u521B\u5EFA\u7C7B\u548C\u7A0B\u5E8F\u5305\u7528\u6CD5\u9875\u9762\n-version \u5305\u542B @version \u6BB5\n-author \u5305\u542B @author \u6BB5\n-docfilessubdirs \u9012\u5F52\u590D\u5236\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\n-splitindex \u5C06\u7D22\u5F15\u5206\u4E3A\u6BCF\u4E2A\u5B57\u6BCD\u5BF9\u5E94\u4E00\u4E2A\u6587\u4EF6\n-windowtitle \u6587\u6863\u7684\u6D4F\u89C8\u5668\u7A97\u53E3\u6807\u9898\n-doctitle \u5305\u542B\u6982\u89C8\u9875\u9762\u7684\u6807\u9898\n-header \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u7709\u6587\u672C\n-footer \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u811A\u6587\u672C\n-top \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9876\u90E8\u6587\u672C\n-bottom \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u5E95\u90E8\u6587\u672C\n-link \u521B\u5EFA\u6307\u5411\u4F4D\u4E8E \u7684 javadoc \u8F93\u51FA\u7684\u94FE\u63A5\n-linkoffline \u5229\u7528\u4F4D\u4E8E \u7684\u7A0B\u5E8F\u5305\u5217\u8868\u94FE\u63A5\u81F3\u4F4D\u4E8E \u7684\u6587\u6863\n-excludedocfilessubdir :.. \u6392\u9664\u5177\u6709\u7ED9\u5B9A\u540D\u79F0\u7684\u6240\u6709\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\u3002\n-group :.. \u5728\u6982\u89C8\u9875\u9762\u4E2D, \u5C06\u6307\u5B9A\u7684\u7A0B\u5E8F\u5305\u5206\u7EC4\n-nocomment \u4E0D\u751F\u6210\u8BF4\u660E\u548C\u6807\u8BB0, \u53EA\u751F\u6210\u58F0\u660E\u3002\n-nodeprecated \u4E0D\u5305\u542B @deprecated \u4FE1\u606F\n-noqualifier ::... \u8F93\u51FA\u4E2D\u4E0D\u5305\u62EC\u9650\u5B9A\u7B26\u7684\u5217\u8868\u3002\n-nosince \u4E0D\u5305\u542B @since \u4FE1\u606F\n-notimestamp \u4E0D\u5305\u542B\u9690\u85CF\u65F6\u95F4\u6233\n-nodeprecatedlist \u4E0D\u751F\u6210\u5DF2\u8FC7\u65F6\u7684\u5217\u8868\n-notree \u4E0D\u751F\u6210\u7C7B\u5206\u5C42\u7ED3\u6784\n-noindex \u4E0D\u751F\u6210\u7D22\u5F15\n-nohelp \u4E0D\u751F\u6210\u5E2E\u52A9\u94FE\u63A5\n-nonavbar \u4E0D\u751F\u6210\u5BFC\u822A\u680F\n-serialwarn \u751F\u6210\u6709\u5173 @serial \u6807\u8BB0\u7684\u8B66\u544A\n-tag ::
    \u6307\u5B9A\u5355\u4E2A\u53C2\u6570\u5B9A\u5236\u6807\u8BB0\n-taglet \u8981\u6CE8\u518C\u7684 Taglet \u7684\u5168\u9650\u5B9A\u540D\u79F0\n-tagletpath Taglet \u7684\u8DEF\u5F84\n-Xdocrootparent \u5C06\u6587\u6863\u6CE8\u91CA\u4E2D\u51FA\u73B0\u7684\u6240\u6709\u540E\u8DDF /.. \u7684 @docRoot \u66FF\u6362\u4E3A \n-charset \u7528\u4E8E\u8DE8\u5E73\u53F0\u67E5\u770B\u751F\u6210\u7684\u6587\u6863\u7684\u5B57\u7B26\u96C6\u3002\n-helpfile \u5305\u542B\u5E2E\u52A9\u94FE\u63A5\u6240\u94FE\u63A5\u5230\u7684\u6587\u4EF6\n-linksource \u4EE5 HTML \u683C\u5F0F\u751F\u6210\u6E90\u6587\u4EF6\n-sourcetab \u6307\u5B9A\u6E90\u4E2D\u6BCF\u4E2A\u5236\u8868\u7B26\u5360\u636E\u7684\u7A7A\u683C\u6570\n-keywords \u4F7F\u7A0B\u5E8F\u5305, \u7C7B\u548C\u6210\u5458\u4FE1\u606F\u9644\u5E26 HTML \u5143\u6807\u8BB0\n-stylesheetfile \u7528\u4E8E\u66F4\u6539\u751F\u6210\u6587\u6863\u7684\u6837\u5F0F\u7684\u6587\u4EF6\n-docencoding \u8F93\u51FA\u7F16\u7801\u540D\u79F0 - - +doclet.usage=\u901A\u8FC7\u6807\u51C6 doclet \u63D0\u4F9B:\n -d \u8F93\u51FA\u6587\u4EF6\u7684\u76EE\u6807\u76EE\u5F55\n -use \u521B\u5EFA\u7C7B\u548C\u7A0B\u5E8F\u5305\u7528\u6CD5\u9875\u9762\n -version \u5305\u542B @version \u6BB5\n -author \u5305\u542B @author \u6BB5\n -docfilessubdirs \u9012\u5F52\u590D\u5236\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\n -splitindex \u5C06\u7D22\u5F15\u5206\u4E3A\u6BCF\u4E2A\u5B57\u6BCD\u5BF9\u5E94\u4E00\u4E2A\u6587\u4EF6\n -windowtitle \u6587\u6863\u7684\u6D4F\u89C8\u5668\u7A97\u53E3\u6807\u9898\n -doctitle \u5305\u542B\u6982\u89C8\u9875\u9762\u7684\u6807\u9898\n -header \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u7709\u6587\u672C\n -footer \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9875\u811A\u6587\u672C\n -top \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u9876\u90E8\u6587\u672C\n -bottom \u5305\u542B\u6BCF\u4E2A\u9875\u9762\u7684\u5E95\u90E8\u6587\u672C\n -link \u521B\u5EFA\u6307\u5411\u4F4D\u4E8E \u7684 javadoc \u8F93\u51FA\u7684\u94FE\u63A5\n -linkoffline \u5229\u7528\u4F4D\u4E8E \u7684\u7A0B\u5E8F\u5305\u5217\u8868\u94FE\u63A5\u81F3\u4F4D\u4E8E \u7684\u6587\u6863\n -excludedocfilessubdir :.. \u6392\u9664\u5177\u6709\u7ED9\u5B9A\u540D\u79F0\u7684\u6240\u6709\u6587\u6863\u6587\u4EF6\u5B50\u76EE\u5F55\u3002\n -group :.. \u5728\u6982\u89C8\u9875\u9762\u4E2D, \u5C06\u6307\u5B9A\u7684\u7A0B\u5E8F\u5305\u5206\u7EC4\n -nocomment \u4E0D\u751F\u6210\u8BF4\u660E\u548C\u6807\u8BB0, \u53EA\u751F\u6210\u58F0\u660E\u3002\n -nodeprecated \u4E0D\u5305\u542B @deprecated \u4FE1\u606F\n -noqualifier ::... \u8F93\u51FA\u4E2D\u4E0D\u5305\u62EC\u6307\u5B9A\u9650\u5B9A\u7B26\u7684\u5217\u8868\u3002\n -nosince \u4E0D\u5305\u542B @since \u4FE1\u606F\n -notimestamp \u4E0D\u5305\u542B\u9690\u85CF\u65F6\u95F4\u6233\n -nodeprecatedlist \u4E0D\u751F\u6210\u5DF2\u8FC7\u65F6\u7684\u5217\u8868\n -notree \u4E0D\u751F\u6210\u7C7B\u5206\u5C42\u7ED3\u6784\n -noindex \u4E0D\u751F\u6210\u7D22\u5F15\n -nohelp \u4E0D\u751F\u6210\u5E2E\u52A9\u94FE\u63A5\n -nonavbar \u4E0D\u751F\u6210\u5BFC\u822A\u680F\n -serialwarn \u751F\u6210\u6709\u5173 @serial \u6807\u8BB0\u7684\u8B66\u544A\n -tag ::
    \u6307\u5B9A\u5355\u4E2A\u53C2\u6570\u5B9A\u5236\u6807\u8BB0\n -taglet \u8981\u6CE8\u518C\u7684 Taglet \u7684\u5168\u9650\u5B9A\u540D\u79F0\n -tagletpath Taglet \u7684\u8DEF\u5F84\n -charset \u7528\u4E8E\u8DE8\u5E73\u53F0\u67E5\u770B\u751F\u6210\u7684\u6587\u6863\u7684\u5B57\u7B26\u96C6\u3002\n -helpfile \u5305\u542B\u5E2E\u52A9\u94FE\u63A5\u6240\u94FE\u63A5\u5230\u7684\u6587\u4EF6\n -linksource \u4EE5 HTML \u683C\u5F0F\u751F\u6210\u6E90\u6587\u4EF6\n -sourcetab \u6307\u5B9A\u6E90\u4E2D\u6BCF\u4E2A\u5236\u8868\u7B26\u5360\u636E\u7684\u7A7A\u683C\u6570\n -keywords \u4F7F\u7A0B\u5E8F\u5305, \u7C7B\u548C\u6210\u5458\u4FE1\u606F\u9644\u5E26 HTML \u5143\u6807\u8BB0\n -stylesheetfile \u7528\u4E8E\u66F4\u6539\u751F\u6210\u6587\u6863\u7684\u6837\u5F0F\u7684\u6587\u4EF6\n -docencoding \u6307\u5B9A\u8F93\u51FA\u7684\u5B57\u7B26\u7F16\u7801 +# L10N: do not localize these words: all none accessibility html missing reference syntax +doclet.X.usage=\u901A\u8FC7\u6807\u51C6 doclet \u63D0\u4F9B:\n -Xdocrootparent \u4F7F\u7528 \u66FF\u6362\u6587\u6863\u6CE8\u91CA\u4E2D\u51FA\u73B0\u7684\n \u6240\u6709\u5176\u540E\u8DDF\u968F /.. \u7684 @docRoot\n -Xdoclint \u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u5EFA\u8BAE\u7684\u68C0\u67E5\n -Xdoclint:(all|none|[-]) \n \u5BF9 javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5\u3002\n \u5176\u4E2D \u662F accessibility, html, missing, reference \u6216 syntax \u4E4B\u4E00\u3002\n diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties index 82509fc3a63..24909fe13c1 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties @@ -174,6 +174,16 @@ doclet.Value=\u5024 doclet.0_and_1={0}\u3068{1} #Documentation for Enums -doclet.enum_values_doc=\n\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u914D\u5217\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u8FD4\u3057\u307E\u3059\u3002\n\u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u6B21\u306E\u3088\u3046\u306B\u3057\u3066\u5B9A\u6570\u3092\u53CD\u5FA9\u3059\u308B\u305F\u3081\u306B\n\u4F7F\u7528\u3067\u304D\u307E\u3059:\n
    \nfor({0} c: {0}.values())\n  System.out.println(c);\n
    \n@return\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\n\u542B\u3080\u914D\u5217 +doclet.enum_values_doc.main=\n\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u914D\u5217\u3092\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u8FD4\u3057\u307E\u3059\u3002\n\u3053\u306E\u30E1\u30BD\u30C3\u30C9\u306F\u6B21\u306E\u3088\u3046\u306B\u3057\u3066\u5B9A\u6570\u3092\u53CD\u5FA9\u3059\u308B\u305F\u3081\u306B\n\u4F7F\u7528\u3067\u304D\u307E\u3059:\n
    \nfor({0} c: {0}.values())\n  System.out.println(c);\n
    \n -doclet.enum_valueof_doc=\n\u6307\u5B9A\u3057\u305F\u540D\u524D\u3092\u6301\u3064\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u8FD4\u3057\u307E\u3059\u3002\n\u6587\u5B57\u5217\u306F\u3001\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u5BA3\u8A00\u3059\u308B\u306E\u306B\u4F7F\u7528\u3057\u305F\u8B58\u5225\u5B50\u3068\u6B63\u78BA\u306B\n\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n(\u4F59\u5206\u306A\u7A7A\u767D\u6587\u5B57\u3092\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002)\n\n@param name\u8FD4\u3055\u308C\u308B\u5217\u6319\u578B\u5B9A\u6570\u306E\u540D\u524D\n@return\u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u3092\u6301\u3064\u5217\u6319\u578B\u5B9A\u6570\n@throws IllegalArgumentException\u6307\u5B9A\u3055\u308C\u305F\u540D\u524D\u3092\u6301\u3064\u5B9A\u6570\u3092\n\u3053\u306E\u5217\u6319\u578B\u304C\u6301\u3063\u3066\u3044\u306A\u3044\u5834\u5408\n@throws NullPointerException\u5F15\u6570\u304Cnull\u306E\u5834\u5408 +doclet.enum_values_doc.return=\n\u3053\u306E\u5217\u6319\u578B\u306E\u5B9A\u6570\u3092\u542B\u3080\u3001\u5BA3\u8A00\u3055\u308C\u3066\u3044\u308B\u9806\u5E8F\u3067\u306E\u914D\u5217 + +doclet.enum_valueof_doc.main=\n\u6307\u5B9A\u3057\u305F\u540D\u524D\u3092\u6301\u3064\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u8FD4\u3057\u307E\u3059\u3002\n\u6587\u5B57\u5217\u306F\u3001\u3053\u306E\u578B\u306E\u5217\u6319\u578B\u5B9A\u6570\u3092\u5BA3\u8A00\u3059\u308B\u306E\u306B\u4F7F\u7528\u3057\u305F\u8B58\u5225\u5B50\u3068\u6B63\u78BA\u306B\n\u4E00\u81F4\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n(\u4F59\u5206\u306A\u7A7A\u767D\u6587\u5B57\u3092\u542B\u3081\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002)\n + +doclet.enum_valueof_doc.param_name=\u8FD4\u3055\u308C\u308B\u5217\u6319\u578B\u5B9A\u6570\u306E\u540D\u524D\u3002 + +doclet.enum_valueof_doc.return=\u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u5217\u6319\u578B\u5B9A\u6570 + +doclet.enum_valueof_doc.throws_ila=\u3053\u306E\u5217\u6319\u578B\u306B\u3001\u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u5B9A\u6570\u304C\u306A\u3044\u5834\u5408 + +doclet.enum_valueof_doc.throws_npe=\u5F15\u6570\u304Cnull\u306E\u5834\u5408 diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties index 602682459a4..905a179fdb4 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties @@ -174,6 +174,16 @@ doclet.Value=\u503C doclet.0_and_1={0}\u548C{1} #Documentation for Enums -doclet.enum_values_doc=\n\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \u8FD4\u56DE\n\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4\u3002\u8BE5\u65B9\u6CD5\u53EF\u7528\u4E8E\u8FED\u4EE3\n\u5E38\u91CF, \u5982\u4E0B\u6240\u793A:\n
    \nfor ({0} c : {0}.values())\n    System.out.println(c);\n
    \n@return \u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \u8FD4\u56DE\n\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4 +doclet.enum_values_doc.main=\n\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F, \u8FD4\u56DE\n\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4\u3002\u8BE5\u65B9\u6CD5\u53EF\u7528\u4E8E\u8FED\u4EE3\n\u5E38\u91CF, \u5982\u4E0B\u6240\u793A:\n
    \nfor ({0} c : {0}.values())\n    System.out.println(c);\n
    -doclet.enum_valueof_doc=\n\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u3002\n\u5B57\u7B26\u4E32\u5FC5\u987B\u4E0E\u7528\u4E8E\u58F0\u660E\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u7684\n\u6807\u8BC6\u7B26\u5B8C\u5168\u5339\u914D\u3002(\u4E0D\u5141\u8BB8\u6709\u591A\u4F59\n\u7684\u7A7A\u683C\u5B57\u7B26\u3002)\n\n@param name \u8981\u8FD4\u56DE\u7684\u679A\u4E3E\u5E38\u91CF\u7684\u540D\u79F0\u3002\n@return \u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u679A\u4E3E\u5E38\u91CF\n@throws \u5982\u679C\u8BE5\u679A\u4E3E\u7C7B\u578B\u6CA1\u6709\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u5E38\u91CF, \n\u5219\u629B\u51FA IllegalArgumentException\n@throws \u5982\u679C\u53C2\u6570\u4E3A\u7A7A\u503C, \u5219\u629B\u51FA NullPointerException +doclet.enum_values_doc.return=\n\u6309\u7167\u58F0\u660E\u8BE5\u679A\u4E3E\u7C7B\u578B\u7684\u5E38\u91CF\u7684\u987A\u5E8F\u8FD4\u56DE\u7684\u5305\u542B\u8FD9\u4E9B\u5E38\u91CF\u7684\u6570\u7EC4 + +doclet.enum_valueof_doc.main=\n\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u3002\n\u5B57\u7B26\u4E32\u5FC5\u987B\u4E0E\u7528\u4E8E\u58F0\u660E\u8BE5\u7C7B\u578B\u7684\u679A\u4E3E\u5E38\u91CF\u7684\n\u6807\u8BC6\u7B26\u5B8C\u5168\u5339\u914D\u3002(\u4E0D\u5141\u8BB8\u6709\u591A\u4F59\n\u7684\u7A7A\u683C\u5B57\u7B26\u3002) + +doclet.enum_valueof_doc.param_name=\u8981\u8FD4\u56DE\u7684\u679A\u4E3E\u5E38\u91CF\u7684\u540D\u79F0\u3002 + +doclet.enum_valueof_doc.return=\u8FD4\u56DE\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u679A\u4E3E\u5E38\u91CF + +doclet.enum_valueof_doc.throws_ila=\u5982\u679C\u8BE5\u679A\u4E3E\u7C7B\u578B\u6CA1\u6709\u5E26\u6709\u6307\u5B9A\u540D\u79F0\u7684\u5E38\u91CF + +doclet.enum_valueof_doc.throws_npe=\u5982\u679C\u53C2\u6570\u4E3A\u7A7A\u503C diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties index 10282be9632..6089737db60 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_ja.properties @@ -26,6 +26,7 @@ dc.anchor.already.defined = \u30A2\u30F3\u30AB\u30FC\u304C\u3059\u3067\u306B\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059: {0} dc.anchor.value.missing = \u30A2\u30F3\u30AB\u30FC\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 dc.attr.lacks.value = \u5C5E\u6027\u306B\u5024\u304C\u3042\u308A\u307E\u305B\u3093 +dc.attr.not.number = \u5C5E\u6027\u5024\u304C\u6570\u5B57\u3067\u306F\u3042\u308A\u307E\u305B\u3093 dc.attr.obsolete = \u5C5E\u6027\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u307E\u3059: {0} dc.attr.obsolete.use.css = \u5C5E\u6027\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u304B\u308F\u308A\u306BCSS\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044: {0} dc.attr.repeated = \u7E70\u308A\u8FD4\u3055\u308C\u305F\u5C5E\u6027: {0} @@ -46,7 +47,7 @@ dc.missing.return = @return\u304C\u3042\u308A\u307E\u305B\u3093 dc.missing.throws = {0}\u306E@throws\u304C\u3042\u308A\u307E\u305B\u3093 dc.no.alt.attr.for.image = \u30A4\u30E1\u30FC\u30B8\u306E"alt"\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093 dc.no.summary.or.caption.for.table=\u8868\u306E\u8981\u7D04\u307E\u305F\u306F\u30AD\u30E3\u30D7\u30B7\u30E7\u30F3\u304C\u3042\u308A\u307E\u305B\u3093 -dc.param.name.not.found = @param\u540D\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 +dc.param.name.not.found = @param name\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 dc.ref.not.found = \u53C2\u7167\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093 dc.tag.code.within.code = \u5185\u306E'{@code'} dc.tag.empty = \u7A7A\u306E<{0}>\u30BF\u30B0 @@ -66,3 +67,9 @@ dc.tag.self.closing = \u81EA\u5DF1\u7D42\u4E86\u8981\u7D20\u306F\u4F7F\u7528\u30 dc.tag.start.unmatched = \u7D42\u4E86\u30BF\u30B0\u304C\u3042\u308A\u307E\u305B\u3093: dc.tag.unknown = \u4E0D\u660E\u306A\u30BF\u30B0: {0} dc.text.not.allowed = <{0}>\u8981\u7D20\u3067\u306F\u30C6\u30AD\u30B9\u30C8\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 +dc.unexpected.comment=\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u30FB\u30B3\u30E1\u30F3\u30C8\u306F\u3053\u3053\u3067\u306F\u5FC5\u8981\u3042\u308A\u307E\u305B\u3093 + +dc.main.ioerror=IO\u30A8\u30E9\u30FC: {0} +dc.main.no.files.given=\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 +dc.main.usage=\u4F7F\u7528\u65B9\u6CD5:\n doclint [options] source-files...\n\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n -Xmsgs \n -Xmsgs:all\u3068\u540C\u3058\n -Xmsgs:values\n \u30C1\u30A7\u30C3\u30AF\u3059\u308B\u554F\u984C\u306E\u30AB\u30C6\u30B4\u30EA\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002\u3053\u3053\u3067\u306E''values''\u306F\u3001\n \u30AB\u30F3\u30DE\u3067\u533A\u5207\u3089\u308C\u305F\u6B21\u306E\u5024\u306E\u30EA\u30B9\u30C8\u3067\u3059:\n reference Java\u30BD\u30FC\u30B9\u30FB\u30B3\u30FC\u30C9\u8981\u7D20\u3078\u306E\u4E0D\u6B63\u306A\u53C2\u7167\u3092\u542B\u3080\u30B3\u30E1\u30F3\u30C8\u306E\n \u5834\u6240\u3092\u8868\u793A\u3057\u307E\u3059\n syntax \u30B3\u30E1\u30F3\u30C8\u5185\u306E\u57FA\u672C\u69CB\u6587\u30A8\u30E9\u30FC\u3092\u8868\u793A\u3057\u307E\u3059\n html HTML\u30BF\u30D6\u304A\u3088\u3073\u5C5E\u6027\u306E\u554F\u984C\u3092\u8868\u793A\u3057\u307E\u3059\n accessibility \u30A2\u30AF\u30BB\u30B7\u30D3\u30EA\u30C6\u30A3\u306E\u554F\u984C\u3092\u8868\u793A\u3057\u307E\u3059\n missing \u6B20\u843D\u3057\u3066\u3044\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u554F\u984C\u3092\u8868\u793A\u3057\u307E\u3059\n all \u524D\u8FF0\u306E\u3059\u3079\u3066\n \u3053\u308C\u3092\u5426\u5B9A\u3059\u308B\u306B\u306F\u3001\u5024\u306E\u524D\u306B''-''\u3092\u6307\u5B9A\u3057\u307E\u3059\n \u30AB\u30C6\u30B4\u30EA\u306F\u3001\u6B21\u306E\u3044\u305A\u308C\u304B\u3067\u4FEE\u98FE\u3067\u304D\u307E\u3059:\n /public /protected /package /private\n \u6B63\u306E\u30AB\u30C6\u30B4\u30EA(''-''\u3067\u59CB\u307E\u3089\u306A\u3044)\u306E\u5834\u5408\n \u4FEE\u98FE\u5B50\u306F\u3001\u305D\u306E\u30A2\u30AF\u30BB\u30B9\u30FB\u30EC\u30D9\u30EB\u4EE5\u4E0A\u306B\u9069\u7528\u3055\u308C\u307E\u3059\u3002\n \u8CA0\u306E\u30AB\u30C6\u30B4\u30EA(''-''\u3067\u59CB\u307E\u308B)\u306E\u5834\u5408\n \u4FEE\u98FE\u5B50\u306F\u3001\u305D\u306E\u30A2\u30AF\u30BB\u30B9\u30FB\u30EC\u30D9\u30EB\u4EE5\u4E0B\u306B\u9069\u7528\u3055\u308C\u307E\u3059\u3002\n \u4FEE\u98FE\u5B50\u304C\u306A\u3044\u5834\u5408\u3001\u30AB\u30C6\u30B4\u30EA\u306F\u3059\u3079\u3066\u306E\u30A2\u30AF\u30BB\u30B9\u30FB\u30EC\u30D9\u30EB\u306B\n \u9069\u7528\u3055\u308C\u307E\u3059\u3002\n \u4F8B: -Xmsgs:all,-syntax/private\n \u3053\u306E\u5834\u5408\u3001private\u30E1\u30BD\u30C3\u30C9\u306Edoc\u30B3\u30E1\u30F3\u30C8\u5185\u306E\u69CB\u6587\u30A8\u30E9\u30FC\u3092\u9664\u304D\u3001\n \u3059\u3079\u3066\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u6709\u52B9\u5316\u3055\u308C\u307E\u3059\u3002\n -Xmsgs\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u5834\u5408\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306F\u3001\n -Xmsgs:all/protected\u3068\u540C\u7B49\u306B\u306A\u308A\u3001\u3053\u308C\u306F\n \u3059\u3079\u3066\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u3001protected\u304A\u3088\u3073public\u306E\u5BA3\u8A00\u306E\u307F\u306B\u5831\u544A\u3055\u308C\u308B\u3053\u3068\u3092\n \u610F\u5473\u3057\u307E\u3059\u3002\n -stats\n \u5831\u544A\u3055\u308C\u305F\u554F\u984C\u306B\u5BFE\u3057\u3066\u7D71\u8A08\u3092\u5831\u544A\u3057\u307E\u3059\u3002\n -h -help --help -usage -?\n \u3053\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002\n\n\u6B21\u306Ejavac\u30AA\u30D7\u30B7\u30E7\u30F3\u3082\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u3059\n \ +-bootclasspath\u3001-classpath\u3001-cp\u3001-sourcepath\u3001-Xmaxerrs\u3001-Xmaxwarns\n\n\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u4E00\u90E8\u306B\u5BFE\u3057\u3066doclint\u3092\u5B9F\u884C\u3059\u308B\u306B\u306F\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u30B3\u30F3\u30D1\u30A4\u30EB\u3055\u308C\u305F\u30AF\u30E9\u30B9\u3092\n\u30AF\u30E9\u30B9\u30D1\u30B9(\u307E\u305F\u306F\u30D6\u30FC\u30C8\u30FB\u30AF\u30E9\u30B9\u30D1\u30B9)\u306B\u6307\u5B9A\u3057\u3001\u30B3\u30DE\u30F3\u30C9\u30FB\u30E9\u30A4\u30F3\u3067\n\u30C1\u30A7\u30C3\u30AF\u3059\u308B\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A\u3057\u307E\u3059\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties index b3a9c7041bc..4d25a4d5c71 100644 --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint_zh_CN.properties @@ -26,6 +26,7 @@ dc.anchor.already.defined = \u951A\u5B9A\u70B9\u5DF2\u5B9A\u4E49: {0} dc.anchor.value.missing = \u6CA1\u6709\u4E3A\u951A\u5B9A\u70B9\u6307\u5B9A\u503C dc.attr.lacks.value = \u5C5E\u6027\u7F3A\u5C11\u503C +dc.attr.not.number = \u5C5E\u6027\u503C\u4E0D\u662F\u6570\u5B57 dc.attr.obsolete = \u5C5E\u6027\u5DF2\u8FC7\u65F6: {0} dc.attr.obsolete.use.css = \u5C5E\u6027\u5DF2\u8FC7\u65F6, \u8BF7\u6539\u7528 CSS: {0} dc.attr.repeated = \u5C5E\u6027\u91CD\u590D: {0} @@ -46,7 +47,7 @@ dc.missing.return = \u6CA1\u6709 @return dc.missing.throws = {0}\u6CA1\u6709 @throws dc.no.alt.attr.for.image = \u56FE\u50CF\u6CA1\u6709 "alt" \u5C5E\u6027 dc.no.summary.or.caption.for.table=\u8868\u6CA1\u6709\u6982\u8981\u6216\u6807\u9898 -dc.param.name.not.found = \u627E\u4E0D\u5230 @param \u540D\u79F0 +dc.param.name.not.found = @param name \u672A\u627E\u5230 dc.ref.not.found = \u627E\u4E0D\u5230\u5F15\u7528 dc.tag.code.within.code = '{@code'} \u5728 \u4E2D dc.tag.empty = <{0}> \u6807\u8BB0\u4E3A\u7A7A @@ -66,3 +67,8 @@ dc.tag.self.closing = \u4E0D\u5141\u8BB8\u4F7F\u7528\u81EA\u5173\u95ED\u5143\u7D dc.tag.start.unmatched = \u7F3A\u5C11\u7ED3\u675F\u6807\u8BB0: dc.tag.unknown = \u672A\u77E5\u6807\u8BB0: {0} dc.text.not.allowed = <{0}> \u5143\u7D20\u4E2D\u4E0D\u5141\u8BB8\u4F7F\u7528\u6587\u672C +dc.unexpected.comment=\u6B64\u5904\u672A\u9884\u671F\u6587\u6863\u6CE8\u91CA + +dc.main.ioerror=IO \u9519\u8BEF: {0} +dc.main.no.files.given=\u672A\u6307\u5B9A\u6587\u4EF6 +dc.main.usage=\u7528\u6CD5:\n doclint [options] source-files...\n\n\u9009\u9879:\n -Xmsgs \n \u4E0E -Xmsgs:all \u76F8\u540C\n -Xmsgs:values\n \u6307\u5B9A\u8981\u68C0\u67E5\u7684\u95EE\u9898\u7684\u7C7B\u522B, \u5176\u4E2D ''values''\n \u662F\u4EFB\u610F\u4EE5\u4E0B\u5185\u5BB9\u7684\u4EE5\u9017\u53F7\u5206\u9694\u7684\u5217\u8868:\n reference \u663E\u793A\u5305\u542B\u5BF9 Java \u6E90\u4EE3\u7801\u5143\u7D20\n \u9519\u8BEF\u5F15\u7528\u7684\u6CE8\u91CA\u7684\u4F4D\u7F6E\n syntax \u663E\u793A\u6CE8\u91CA\u4E2D\u7684\u57FA\u672C\u8BED\u6CD5\u9519\u8BEF\n html \u663E\u793A HTML \u6807\u8BB0\u548C\u5C5E\u6027\u95EE\u9898\n accessibility \u663E\u793A\u53EF\u8BBF\u95EE\u6027\u7684\u95EE\u9898\n missing \u663E\u793A\u7F3A\u5C11\u6587\u6863\u7684\u95EE\u9898\n all \u6240\u6709\u4EE5\u4E0A\u5185\u5BB9\n \u5728\u503C\u4E4B\u524D\u4F7F\u7528 ''-'' \u53EF\u4F7F\u7528\u5176\u53CD\u503C\n \u53EF\u4EE5\u4F7F\u7528\u4EE5\u4E0B\u4E00\u9879\u6765\u9650\u5B9A\u7C7B\u522B:\n /public /protected /package /private\n \u5BF9\u4E8E\u6B63\u7C7B\u522B (\u4E0D\u4EE5 ''-'' \u5F00\u5934)\n \u9650\u5B9A\u7B26\u9002\u7528\u4E8E\u8BE5\u8BBF\u95EE\u7EA7\u522B\u53CA\u66F4\u9AD8\u7EA7\u522B\u3002\n \u5BF9\u4E8E\u8D1F\u7C7B\u522B (\u4EE5 ''-'' \u5F00\u5934)\n \u9650\u5B9A\u7B26\u9002\u7528\u4E8E\u8BE5\u8BBF\u95EE\u7EA7\u522B\u53CA\u66F4\u4F4E\u7EA7\u522B\u3002\n \u5982\u679C\u6CA1\u6709\u9650\u5B9A\u7B26, \u5219\u8BE5\u7C7B\u522B\u9002\u7528\u4E8E\n \u6240\u6709\u8BBF\u95EE\u7EA7\u522B\u3002\n \u4F8B\u5982, -Xmsgs:all,-syntax/private\n \u8FD9\u5C06\u5728\u4E13\u7528\u65B9\u6CD5\u7684\u6587\u6863\u6CE8\u91CA\u4E2D\n \u542F\u7528\u9664\u8BED\u6CD5\u9519\u8BEF\u4E4B\u5916\u7684\u6240\u6709\u6D88\u606F\u3002\n \u5982\u679C\u672A\u63D0\u4F9B -Xmsgs \u9009\u9879, \u5219\u9ED8\u8BA4\u503C\n \u7B49\u540C\u4E8E -Xmsgs:all/protected, \u8868\u793A\n \u4EC5\u62A5\u544A\u53D7\u4FDD\u62A4\u548C\u516C\u5171\u58F0\u660E\u4E2D\u7684\n \u6240\u6709\u6D88\u606F\n -stats\n \u62A5\u544A\u6240\u62A5\u544A\u95EE\u9898\u7684\u7EDF\u8BA1\u4FE1\u606F\u3002\n -h -help --help -usage -?\n \u663E\u793A\u6B64\u6D88\u606F\u3002\n\n\u8FD8\u652F\u6301\u4EE5\u4E0B javac \u9009\u9879\n -bootclasspath, -classpath, -cp, -sourcepath, -Xmaxerrs, -Xmaxwarns\n\n\u8981\u5728\u9879\u76EE\u7684\u4E00\u90E8\u5206\u4E0A\u8FD0\u884C doclint, \u8BF7\u5C06\u9879\u76EE\u4E2D\u5DF2\u7F16\u8BD1\u7684\u7C7B\n\u653E\u5728\u7C7B\u8DEF\u5F84 (\u6216\u5F15\u5BFC\u7C7B\u8DEF\u5F84) \u4E0A, \u7136\u540E\u5728\u547D\u4EE4\u884C\u4E0A\u6307\u5B9A\n\u8981\u68C0\u67E5\u7684\u6E90\u6587\u4EF6\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties index bff4e9a217b..9702e684c78 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties @@ -524,9 +524,6 @@ compiler.misc.incompatible.ret.type.in.lambda=\u30E9\u30E0\u30C0\u5F0F\u306E\u62 # 0: type compiler.misc.incompatible.ret.type.in.mref=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u623B\u308A\u578B\u304C\u4E0D\u6B63\u3067\u3059\n{0} -# 0: list of type -compiler.err.incompatible.thrown.types.in.lambda=\u30E9\u30E0\u30C0\u5F0F\u3067\u30B9\u30ED\u30FC\u3055\u308C\u305F\u30BF\u30A4\u30D7{0}\u306F\u4E0D\u9069\u5408\u3067\u3059 - # 0: list of type compiler.err.incompatible.thrown.types.in.mref=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u306E\u30B9\u30ED\u30FC\u3055\u308C\u305F\u30BF\u30A4\u30D7{0}\u306F\u4E0D\u9069\u5408\u3067\u3059 @@ -642,12 +639,18 @@ compiler.err.repeated.modifier=\u4FEE\u98FE\u5B50\u304C\u7E70\u308A\u8FD4\u3055\ # 0: symbol, 1: set of modifier, 2: symbol compiler.err.report.access={0}\u306F{2}\u3067{1}\u30A2\u30AF\u30BB\u30B9\u3055\u308C\u307E\u3059 +# 0: symbol, 1: set of modifier, 2: symbol +compiler.misc.report.access={0}\u306F{2}\u3067{1}\u30A2\u30AF\u30BB\u30B9\u3055\u308C\u307E\u3059 + compiler.err.ret.outside.meth=\u30E1\u30BD\u30C3\u30C9\u306E\u5916\u306Ereturn\u6587\u3067\u3059 compiler.err.signature.doesnt.match.supertype=\u30B7\u30B0\u30CD\u30C1\u30E3\u304C{0}\u306B\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u4E0D\u9069\u5408\u306A\u30B9\u30FC\u30D1\u30FC\u30BF\u30A4\u30D7\u3067\u3059 compiler.err.signature.doesnt.match.intf=\u30B7\u30B0\u30CD\u30C1\u30E3\u304C{0}\u306B\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u4E0D\u9069\u5408\u306A\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u3067\u3059 +# 0: number, 1: number +compiler.err.method.invoked.with.incorrect.number.arguments=\u30E1\u30BD\u30C3\u30C9\u3092\u8D77\u52D5\u3057\u305F\u5F15\u6570\u306E\u6570\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093\u3002\u4E88\u671F\u3055\u308C\u308B\u6570\u306F{0}\u3067\u3059\u304C\u3001{1}\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F + # 0: symbol, 1: symbol, 2: symbol compiler.err.does.not.override.abstract={0}\u306Fabstract\u3067\u306A\u304F\u3001{2}\u5185\u306Eabstract\u30E1\u30BD\u30C3\u30C9{1}\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u305B\u3093 @@ -755,6 +758,9 @@ compiler.err.var.might.already.be.assigned=\u5909\u6570{0}\u306F\u3059\u3067\u30 # 0: symbol compiler.err.var.might.not.have.been.initialized=\u5909\u6570{0}\u306F\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 +# 0: symbol +compiler.err.var.not.initialized.in.default.constructor=\u5909\u6570{0}\u306F\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u30FB\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30BF\u3067\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093 + # 0: symbol compiler.err.var.might.be.assigned.in.loop=\u5909\u6570{0}\u306F\u30EB\u30FC\u30D7\u5185\u3067\u4EE3\u5165\u3055\u308C\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059 @@ -829,6 +835,14 @@ compiler.note.compressed.diags=\u4E00\u90E8\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\ compiler.note.potential.lambda.found=\u3053\u306E\u533F\u540D\u5185\u90E8\u30AF\u30E9\u30B9\u3092\u30E9\u30E0\u30C0\u5F0F\u306B\u5909\u63DB\u3067\u304D\u307E\u3059\u3002 +# 0: boolean, 1: symbol +compiler.note.lambda.stat=\u30E9\u30E0\u30C0\u5F0F\u3092\u5909\u63DB\u3057\u3066\u3044\u307E\u3059\n\u4EE3\u66FFmetafactory = {0}\n\u5408\u6210\u30E1\u30BD\u30C3\u30C9 = {1} + +# 0: boolean, 1: unused +compiler.note.mref.stat=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u3092\u5909\u63DB\u3057\u3066\u3044\u307E\u3059\n\u4EE3\u66FFmetafactory = {0}\n +# 0: boolean, 1: symbol +compiler.note.mref.stat.1=\u30E1\u30BD\u30C3\u30C9\u53C2\u7167\u3092\u5909\u63DB\u3057\u3066\u3044\u307E\u3059\n\u4EE3\u66FFmetafactory = {0}\n\u30D6\u30EA\u30C3\u30B8\u30FB\u30E1\u30BD\u30C3\u30C9 = {1} + compiler.note.note=\u6CE8\u610F: # 0: file name @@ -1015,6 +1029,14 @@ compiler.warn.static.not.qualified.by.type=static {0}\u306F\u5F0F\u3067\u306F\u3 # 0: string compiler.warn.source.no.bootclasspath=\u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30D1\u30B9\u304C-source {0}\u3068\u4E00\u7DD2\u306B\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 +# 0: string +compiler.warn.option.obsolete.source=\u30BD\u30FC\u30B9\u5024{0}\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u3066\u3001\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059 + +# 0: string +compiler.warn.option.obsolete.target=\u30BF\u30FC\u30B2\u30C3\u30C8\u5024{0}\u306F\u5EC3\u6B62\u3055\u308C\u3066\u3044\u3066\u3001\u4ECA\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u524A\u9664\u3055\u308C\u308B\u4E88\u5B9A\u3067\u3059 + +compiler.warn.option.obsolete.suppression=\u5EC3\u6B62\u3055\u308C\u305F\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u3064\u3044\u3066\u306E\u8B66\u544A\u3092\u8868\u793A\u3057\u306A\u3044\u3088\u3046\u306B\u3059\u308B\u306B\u306F\u3001-Xlint:\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002 + # 0: name, 1: number, 2: number, 3: number, 4: number compiler.warn.future.attr=\u30D0\u30FC\u30B8\u30E7\u30F3{1}.{2}\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3067\u5C0E\u5165\u3055\u308C\u305F{0}\u5C5E\u6027\u306F\u3001\u30D0\u30FC\u30B8\u30E7\u30F3{3}.{4}\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u7121\u8996\u3055\u308C\u307E\u3059 @@ -1550,7 +1572,7 @@ compiler.warn.enum.as.identifier=\u30EA\u30EA\u30FC\u30B95\u304B\u3089''enum''\u compiler.warn.assert.as.identifier=\u30EA\u30EA\u30FC\u30B91.4\u304B\u3089''assert''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u3001\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\n(''assert''\u3092\u30AD\u30FC\u30EF\u30FC\u30C9\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u306B\u306F\u3001-source 1.4\u4EE5\u964D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) -compiler.warn.underscore.as.identifier=\u8B58\u5225\u5B50\u3068\u3057\u3066''_''\u304C\u4F7F\u7528\u3055\u308C\u307E\u3057\u305F\n(\u8B58\u5225\u5B50\u3068\u3057\u3066\u306E''_''\u306E\u4F7F\u7528\u306F\u3001\u5C06\u6765\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059) +compiler.warn.underscore.as.identifier=\u8B58\u5225\u5B50\u3068\u3057\u3066''_''\u304C\u4F7F\u7528\u3055\u308C\u307E\u3057\u305F\n(\u8B58\u5225\u5B50\u3068\u3057\u3066\u306E''_''\u306E\u4F7F\u7528\u306F\u3001Java SE 8\u3088\u308A\u5F8C\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u3044\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059) compiler.err.enum.as.identifier=\u30EA\u30EA\u30FC\u30B95\u304B\u3089''enum''\u306F\u30AD\u30FC\u30EF\u30FC\u30C9\u306A\u306E\u3067\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\n(''enum''\u3092\u8B58\u5225\u5B50\u3068\u3057\u3066\u4F7F\u7528\u3059\u308B\u306B\u306F-source 1.4\u4EE5\u524D\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044) @@ -1567,7 +1589,7 @@ compiler.err.cant.annotate.static.class=\u5305\u542B\u3059\u308Bstatic\u306E\u30 # TODO 308: make a better error message # 0: unused -compiler.err.cant.annotate.nested.type=\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30BF\u30A4\u30D7\u306F\u6CE8\u91C8\u4ED8\u3051\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093 +compiler.err.cant.annotate.nested.type=static\u306E\u30CD\u30B9\u30C8\u3055\u308C\u305F\u30BF\u30A4\u30D7\u306E\u30B9\u30B3\u30FC\u30D7\u30FB\u30B3\u30F3\u30B9\u30C8\u30E9\u30AF\u30C8\u306B\u306F\u6CE8\u91C8\u4ED8\u3051\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093 # 0: type, 1: type compiler.err.incorrect.receiver.name=\u53D7\u53D6\u308A\u5074\u306E\u540D\u524D\u304C\u3001\u5305\u542B\u3059\u308B\u30AF\u30E9\u30B9\u30FB\u30BF\u30A4\u30D7\u3068\u4E00\u81F4\u3057\u307E\u305B\u3093\n\u5FC5\u9808: {0}\n\u691C\u51FA: {1} diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties index b2e76c037f4..d4f1a214cd0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties @@ -524,9 +524,6 @@ compiler.misc.incompatible.ret.type.in.lambda=lambda \u8868\u8FBE\u5F0F\u4E2D\u7 # 0: type compiler.misc.incompatible.ret.type.in.mref=\u65B9\u6CD5\u5F15\u7528\u4E2D\u7684\u8FD4\u56DE\u7C7B\u578B\u9519\u8BEF\n{0} -# 0: list of type -compiler.err.incompatible.thrown.types.in.lambda=lambda \u8868\u8FBE\u5F0F\u4E2D\u629B\u51FA\u7684\u7C7B\u578B{0}\u4E0D\u517C\u5BB9 - # 0: list of type compiler.err.incompatible.thrown.types.in.mref=\u65B9\u6CD5\u5F15\u7528\u4E2D\u629B\u51FA\u7684\u7C7B\u578B{0}\u4E0D\u517C\u5BB9 @@ -642,12 +639,18 @@ compiler.err.repeated.modifier=\u4FEE\u9970\u7B26\u91CD\u590D # 0: symbol, 1: set of modifier, 2: symbol compiler.err.report.access={0}\u53EF\u4EE5\u5728{2}\u4E2D\u8BBF\u95EE{1} +# 0: symbol, 1: set of modifier, 2: symbol +compiler.misc.report.access={0}\u53EF\u4EE5\u5728{2}\u4E2D\u8BBF\u95EE{1} + compiler.err.ret.outside.meth=\u8FD4\u56DE\u5916\u90E8\u65B9\u6CD5 compiler.err.signature.doesnt.match.supertype=\u7B7E\u540D\u4E0E{0}\u4E0D\u5339\u914D; \u4E0D\u517C\u5BB9\u7684\u8D85\u7C7B\u578B compiler.err.signature.doesnt.match.intf=\u7B7E\u540D\u4E0E{0}\u4E0D\u5339\u914D; \u4E0D\u517C\u5BB9\u7684\u63A5\u53E3 +# 0: number, 1: number +compiler.err.method.invoked.with.incorrect.number.arguments=\u4F7F\u7528\u4E0D\u6B63\u786E\u6570\u91CF\u7684\u53C2\u6570\u8C03\u7528\u4E86\u65B9\u6CD5; \u9884\u671F\u4E3A {0} \u4E2A, \u627E\u5230 {1} \u4E2A + # 0: symbol, 1: symbol, 2: symbol compiler.err.does.not.override.abstract={0}\u4E0D\u662F\u62BD\u8C61\u7684, \u5E76\u4E14\u672A\u8986\u76D6{2}\u4E2D\u7684\u62BD\u8C61\u65B9\u6CD5{1} @@ -755,6 +758,9 @@ compiler.err.var.might.already.be.assigned=\u53EF\u80FD\u5DF2\u5206\u914D\u53D8\ # 0: symbol compiler.err.var.might.not.have.been.initialized=\u53EF\u80FD\u5C1A\u672A\u521D\u59CB\u5316\u53D8\u91CF{0} +# 0: symbol +compiler.err.var.not.initialized.in.default.constructor=\u53D8\u91CF {0} \u672A\u5728\u9ED8\u8BA4\u6784\u9020\u5668\u4E2D\u521D\u59CB\u5316 + # 0: symbol compiler.err.var.might.be.assigned.in.loop=\u53EF\u80FD\u5728 loop \u4E2D\u5206\u914D\u4E86\u53D8\u91CF{0} @@ -829,6 +835,14 @@ compiler.note.compressed.diags=\u67D0\u4E9B\u6D88\u606F\u5DF2\u7ECF\u8FC7\u7B80\ compiler.note.potential.lambda.found=\u53EF\u5C06\u6B64\u533F\u540D\u5185\u90E8\u7C7B\u521B\u5EFA\u8F6C\u6362\u4E3A lambda \u8868\u8FBE\u5F0F\u3002 +# 0: boolean, 1: symbol +compiler.note.lambda.stat=\u8F6C\u6362 lambda \u8868\u8FBE\u5F0F\n\u66FF\u4EE3 metafactory = {0}\n\u5408\u6210\u65B9\u6CD5 = {1} + +# 0: boolean, 1: unused +compiler.note.mref.stat=\u8F6C\u6362\u65B9\u6CD5\u5F15\u7528\n\u66FF\u4EE3 metafactory = {0}\n +# 0: boolean, 1: symbol +compiler.note.mref.stat.1=\u8F6C\u6362\u65B9\u6CD5\u5F15\u7528\n\u66FF\u4EE3 metafactory = {0}\nbridge \u65B9\u6CD5 = {1} + compiler.note.note=\u6CE8: # 0: file name @@ -1015,6 +1029,14 @@ compiler.warn.static.not.qualified.by.type=static {0}\u5E94\u7531\u7C7B\u578B\u5 # 0: string compiler.warn.source.no.bootclasspath=\u672A\u4E0E -source {0} \u4E00\u8D77\u8BBE\u7F6E\u5F15\u5BFC\u7C7B\u8DEF\u5F84 +# 0: string +compiler.warn.option.obsolete.source=\u6E90\u503C{0}\u5DF2\u8FC7\u65F6, \u5C06\u5728\u672A\u6765\u6240\u6709\u53D1\u884C\u7248\u4E2D\u5220\u9664 + +# 0: string +compiler.warn.option.obsolete.target=\u76EE\u6807\u503C{0}\u5DF2\u8FC7\u65F6, \u5C06\u5728\u672A\u6765\u6240\u6709\u53D1\u884C\u7248\u4E2D\u5220\u9664 + +compiler.warn.option.obsolete.suppression=\u8981\u9690\u85CF\u6709\u5173\u5DF2\u8FC7\u65F6\u9009\u9879\u7684\u8B66\u544A, \u8BF7\u4F7F\u7528 -Xlint:-options\u3002 + # 0: name, 1: number, 2: number, 3: number, 4: number compiler.warn.future.attr={1}.{2} \u7248\u7C7B\u6587\u4EF6\u4E2D\u5F15\u5165\u7684 {0} \u5C5E\u6027\u5728 {3}.{4} \u7248\u7C7B\u6587\u4EF6\u4E2D\u88AB\u5FFD\u7565 @@ -1550,7 +1572,7 @@ compiler.warn.enum.as.identifier=\u4ECE\u53D1\u884C\u7248 5 \u5F00\u59CB, ''enum compiler.warn.assert.as.identifier=\u4ECE\u53D1\u884C\u7248 1.4 \u5F00\u59CB, ''assert'' \u662F\u4E00\u4E2A\u5173\u952E\u5B57, \u4F46\u4E0D\u80FD\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u8BF7\u4F7F\u7528 -source 1.4 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u5C06 ''assert'' \u7528\u4F5C\u5173\u952E\u5B57) -compiler.warn.underscore.as.identifier=''_'' \u5DF2\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u4EE5\u540E\u7684\u53D1\u884C\u7248\u53EF\u80FD\u4E0D\u652F\u6301\u5C06 ''_'' \u7528\u4F5C\u6807\u8BC6\u7B26) +compiler.warn.underscore.as.identifier=''_'' \u7528\u4F5C\u6807\u8BC6\u7B26\n(Java SE 8 \u4E4B\u540E\u7684\u53D1\u884C\u7248\u4E2D\u53EF\u80FD\u4E0D\u652F\u6301\u4F7F\u7528 ''_'' \u4F5C\u4E3A\u6807\u8BC6\u7B26) compiler.err.enum.as.identifier=\u4ECE\u53D1\u884C\u7248 5 \u5F00\u59CB, ''enum'' \u4E3A\u5173\u952E\u5B57, \u800C\u4E0D\u7528\u4F5C\u6807\u8BC6\u7B26\n(\u8BF7\u4F7F\u7528 -source 1.4 \u6216\u66F4\u4F4E\u7248\u672C\u4EE5\u5C06 ''enum'' \u7528\u4F5C\u6807\u8BC6\u7B26) @@ -1567,7 +1589,7 @@ compiler.err.cant.annotate.static.class=\u65E0\u6CD5\u5BF9\u5C01\u95ED\u9759\u60 # TODO 308: make a better error message # 0: unused -compiler.err.cant.annotate.nested.type=\u65E0\u6CD5\u5BF9\u5D4C\u5957\u7C7B\u578B\u8FDB\u884C\u6CE8\u91CA +compiler.err.cant.annotate.nested.type=\u65E0\u6CD5\u6CE8\u91CA\u7528\u4E8E\u9759\u6001\u5D4C\u5957\u7C7B\u578B\u7684\u786E\u5B9A\u4F5C\u7528\u57DF\u7ED3\u6784 # 0: type, 1: type compiler.err.incorrect.receiver.name=\u63A5\u6536\u65B9\u540D\u79F0\u4E0E\u5C01\u95ED\u7C7B\u7C7B\u578B\u4E0D\u5339\u914D\n\u9700\u8981: {0}\n\u627E\u5230: {1} diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties index 0170a70384d..2c68780c9a6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -87,8 +87,12 @@ javac.opt.arg.file= javac.opt.Xlint=\u63A8\u5968\u306E\u8B66\u544A\u3092\u6709\u52B9\u306B\u3059\u308B javac.opt.Xlint.suboptlist=\u7279\u5B9A\u306E\u8B66\u544A\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3059\u308B javac.opt.Xdoclint=javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u63A8\u5968\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u306B\u3059\u308B -javac.opt.Xdoclint.subopts = (all|[-])[/] -javac.opt.Xdoclint.custom=\n javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n \u3053\u3053\u3067\u3001\u306Faccessibility\u3001html\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3001\n \u306Fpublic\u3001protected\u3001package\u307E\u305F\u306Fprivate\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002 +# L10N: do not localize: all none +javac.opt.Xdoclint.subopts = (all|none|[-])[/] + +# L10N: do not localize: accessibility html missing reference syntax +# L10N: do not localize: public protected package private +javac.opt.Xdoclint.custom=\n javadoc\u30B3\u30E1\u30F3\u30C8\u306E\u554F\u984C\u306B\u95A2\u3059\u308B\u7279\u5B9A\u306E\u30C1\u30A7\u30C3\u30AF\u3092\u6709\u52B9\u307E\u305F\u306F\u7121\u52B9\u306B\u3057\u307E\u3059\u3002\n \u3053\u3053\u3067\u3001\u306Faccessibility\u3001html\u3001missing\u3001reference\u307E\u305F\u306Fsyntax\u306E\u3044\u305A\u308C\u304B\u3067\u3001\n \u306Fpublic\u3001protected\u3001package\u307E\u305F\u306Fprivate\u306E\u3044\u305A\u308C\u304B\u3067\u3059\u3002 javac.opt.Xstdout=\u6A19\u6E96\u51FA\u529B\u3092\u30EA\u30C0\u30A4\u30EC\u30AF\u30C8\u3059\u308B javac.opt.X=\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3059\u308B javac.opt.help=\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3059\u308B @@ -105,6 +109,7 @@ javac.err.empty.A.argument=-A\u306B\u306F\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3 javac.err.invalid.arg={0}\u306F\u7121\u52B9\u306A\u5F15\u6570\u3067\u3059 javac.err.invalid.A.key=\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3''{0}''\u306E\u30AD\u30FC\u306B\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u4E00\u9023\u306E\u8B58\u5225\u5B50\u304C\u3001\u30C9\u30C3\u30C8\u3067\u533A\u5207\u3089\u308C\u3066\u3044\u307E\u305B\u3093 javac.err.invalid.flag={0}\u306F\u7121\u52B9\u306A\u30D5\u30E9\u30B0\u3067\u3059 +javac.err.profile.bootclasspath.conflict=profile\u3068bootclasspath\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u540C\u6642\u306B\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 javac.err.invalid.profile=\u7121\u52B9\u306A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: {0} javac.err.invalid.target={0}\u306F\u7121\u52B9\u306A\u30BF\u30FC\u30B2\u30C3\u30C8\u30FB\u30EA\u30EA\u30FC\u30B9\u3067\u3059 javac.err.no.source.files=\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093 diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties index 79e497f1f87..2ad0c68edbd 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -87,8 +87,12 @@ javac.opt.arg.file=<\u6587\u4EF6\u540D> javac.opt.Xlint=\u542F\u7528\u5EFA\u8BAE\u7684\u8B66\u544A javac.opt.Xlint.suboptlist=\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u7684\u8B66\u544A javac.opt.Xdoclint=\u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u5EFA\u8BAE\u7684\u68C0\u67E5 -javac.opt.Xdoclint.subopts = (all|[-])[/] -javac.opt.Xdoclint.custom=\n \u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n \u5176\u4E2D \u4E3A\u53EF\u8BBF\u95EE\u6027, html, \u5F15\u7528\u6216\u8BED\u6CD5\u4E4B\u4E00,\n \u4E3A public, protected, package \u6216 private \u4E4B\u4E00\u3002 +# L10N: do not localize: all none +javac.opt.Xdoclint.subopts = (all|none|[-])[/] + +# L10N: do not localize: accessibility html missing reference syntax +# L10N: do not localize: public protected package private +javac.opt.Xdoclint.custom=\n \u4E3A javadoc \u6CE8\u91CA\u4E2D\u7684\u95EE\u9898\u542F\u7528\u6216\u7981\u7528\u7279\u5B9A\u68C0\u67E5,\n \u5176\u4E2D \u4E3A accessibility, html, missing, reference \u6216 syntax \u4E4B\u4E00\u3002\n \u4E3A public, protected, package \u6216 private \u4E4B\u4E00\u3002 javac.opt.Xstdout=\u91CD\u5B9A\u5411\u6807\u51C6\u8F93\u51FA javac.opt.X=\u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981 javac.opt.help=\u8F93\u51FA\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981 @@ -105,6 +109,7 @@ javac.err.empty.A.argument=-A \u9700\u8981\u4E00\u4E2A\u53C2\u6570; \u4F7F\u7528 javac.err.invalid.arg=\u65E0\u6548\u7684\u53C2\u6570: {0} javac.err.invalid.A.key=\u6CE8\u91CA\u5904\u7406\u7A0B\u5E8F\u9009\u9879 ''{0}'' \u4E2D\u7684\u5173\u952E\u5B57\u4E0D\u662F\u4EE5\u70B9\u5206\u9694\u7684\u6807\u8BC6\u7B26\u5E8F\u5217 javac.err.invalid.flag=\u65E0\u6548\u7684\u6807\u8BB0: {0} +javac.err.profile.bootclasspath.conflict=\u6982\u8981\u4FE1\u606F\u548C\u5F15\u5BFC\u7C7B\u8DEF\u5F84\u9009\u9879\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528 javac.err.invalid.profile=\u914D\u7F6E\u6587\u4EF6\u65E0\u6548: {0} javac.err.invalid.target=\u65E0\u6548\u7684\u76EE\u6807\u53D1\u884C\u7248: {0} javac.err.no.source.files=\u65E0\u6E90\u6587\u4EF6 diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties index a31ba5973da..b95a435689f 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,13 @@ main.errors=\u30A8\u30E9\u30FC{0}\u500B main.error=\u30A8\u30E9\u30FC{0}\u500B main.warnings=\u8B66\u544A{0}\u500B main.warning=\u8B66\u544A{0}\u500B -main.usage=\u4F7F\u7528\u65B9\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n-overview HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u3080\n-public public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u793A\u3059\n-protected protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n-package package/protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n-private \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n-help \u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n-doclet \u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n-docletpath doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u63A2\u3059\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n-sourcepath \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n-classpath \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n-exclude \u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B\n-subpackages \u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B\n-breakiterator BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B\n-bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30ED\u30FC\u30C0\u30FC\u306B\u3088\u308A\u30ED\u30FC\u30C9\u3055\u308C\u305F\n\t\t\t \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n-source \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n-extdirs \u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u305F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n-verbose Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n-locale en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB\n-encoding \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D\n-quiet \u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044\n-J \u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059\n-X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3059\u308B\n -main.Xusage=-Xmaxerrs \u51FA\u529B\u3059\u308B\u30A8\u30E9\u30FC\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n-Xmaxwarns \u51FA\u529B\u3059\u308B\u8B66\u544A\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n\n\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002 + +main.usage=\u4F7F\u7528\u65B9\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n -overview HTML\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6982\u8981\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u8AAD\u307F\u8FBC\u3080\n -public public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u793A\u3059\n -protected protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -package package/protected/public\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n -private \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u793A\u3059\n -help \u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u30FB\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n -doclet \u4EE3\u66FFdoclet\u3092\u4ECB\u3057\u3066\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n -docletpath doclet\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u63A2\u3059\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n -sourcepath \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n -classpath \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\n -cp \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B\r\n -exclude \u9664\u5916\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EA\u30B9\u30C8\u3092\u6307\u5B9A\u3059\u308B\n -subpackages \u518D\u5E30\u7684\u306B\u30ED\u30FC\u30C9\u3059\u308B\u30B5\u30D6\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u6307\u5B9A\u3059\u308B\n -breakiterator BreakIterator\u3067\u6700\u521D\u306E\u6587\u3092\u8A08\u7B97\u3059\u308B\n -bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30ED\u30FC\u30C0\u30FC\u306B\u3088\u308A\u30ED\u30FC\u30C9\u3055\u308C\u305F\n \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n -source \u6307\u5B9A\u3055\u308C\u305F\u30EA\u30EA\u30FC\u30B9\u3068\u30BD\u30FC\u30B9\u306E\u4E92\u63DB\u6027\u3092\u63D0\u4F9B\u3059\u308B\n -extdirs \u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u305F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B\n -verbose Javadoc\u306E\u52D5\u4F5C\u306B\u3064\u3044\u3066\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B\n -locale en_US\u3084en_US_WIN\u306A\u3069\u306E\u4F7F\u7528\u3059\u308B\u30ED\u30B1\u30FC\u30EB\n -encoding \u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u540D\n -quiet \u72B6\u614B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u306A\u3044\n -J \u3092\u5B9F\u884C\u6642\u30B7\u30B9\u30C6\u30E0\u306B\u76F4\u63A5\u6E21\u3059\n -X \u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u6982\u8981\u3092\u51FA\u529B\u3057\u7D42\u4E86\u3059\u308B\n + +main.Xusage=\ -Xmaxerrs \u51FA\u529B\u3059\u308B\u30A8\u30E9\u30FC\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n -Xmaxwarns \u51FA\u529B\u3059\u308B\u8B66\u544A\u306E\u6700\u5927\u6570\u3092\u8A2D\u5B9A\u3059\u308B\n + +main.Xusage.foot=\u3053\u308C\u3089\u306F\u975E\u6A19\u6E96\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u3042\u308A\u4E88\u544A\u306A\u3057\u306B\u5909\u66F4\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002 + main.option.already.seen={0}\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u8907\u6570\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002 main.requires_argument=\u30AA\u30D7\u30B7\u30E7\u30F3{0}\u306B\u306F\u5F15\u6570\u304C\u5FC5\u8981\u3067\u3059\u3002 main.locale_first=\u30AA\u30D7\u30B7\u30E7\u30F3-locale\u306F\u3001\u30B3\u30DE\u30F3\u30C9\u30E9\u30A4\u30F3\u306E\u6700\u521D\u306B\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties index bb16ec27d9b..591f5771a07 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,13 @@ main.errors={0} \u4E2A\u9519\u8BEF main.error={0} \u4E2A\u9519\u8BEF main.warnings={0} \u4E2A\u8B66\u544A main.warning={0} \u4E2A\u8B66\u544A -main.usage=\u7528\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n-overview \u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863\n-public \u4EC5\u663E\u793A public \u7C7B\u548C\u6210\u5458\n-protected \u663E\u793A protected/public \u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)\n-package \u663E\u793A package/protected/public \u7C7B\u548C\u6210\u5458\n-private \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458\n-help \u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA\n-doclet \u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA\n-docletpath \u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n-sourcepath \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n-classpath \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n-exclude \u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868\n-subpackages \u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305\n-breakiterator \u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5\n-bootclasspath \u8986\u76D6\u7531\u5F15\u5BFC\u7C7B\u52A0\u8F7D\u5668\u6240\u52A0\u8F7D\u7684\n\t\t\t \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n-source \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n-extdirs \u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E\n-verbose \u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u4FE1\u606F\n-locale \u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982 en_US \u6216 en_US_WIN\n-encoding \u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0\n-quiet \u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F\n-J \u76F4\u63A5\u5C06 \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\n-X \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\n -main.Xusage=-Xmaxerrs \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u9519\u8BEF\u6570\n-Xmaxwarns \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u8B66\u544A\u6570\n\n\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002 + +main.usage=\u7528\u6CD5: javadoc [options] [packagenames] [sourcefiles] [@files]\n -overview \u4ECE HTML \u6587\u4EF6\u8BFB\u53D6\u6982\u89C8\u6587\u6863\n -public \u4EC5\u663E\u793A public \u7C7B\u548C\u6210\u5458\n -protected \u663E\u793A protected/public \u7C7B\u548C\u6210\u5458 (\u9ED8\u8BA4\u503C)\n -package \u663E\u793A package/protected/public \u7C7B\u548C\u6210\u5458\n -private \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458\n -help \u663E\u793A\u547D\u4EE4\u884C\u9009\u9879\u5E76\u9000\u51FA\n -doclet \u901A\u8FC7\u66FF\u4EE3 doclet \u751F\u6210\u8F93\u51FA\n -docletpath \u6307\u5B9A\u67E5\u627E doclet \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -sourcepath \u6307\u5B9A\u67E5\u627E\u6E90\u6587\u4EF6\u7684\u4F4D\u7F6E\n -classpath \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -cp \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -exclude \u6307\u5B9A\u8981\u6392\u9664\u7684\u7A0B\u5E8F\u5305\u5217\u8868\n -subpackages \u6307\u5B9A\u8981\u9012\u5F52\u52A0\u8F7D\u7684\u5B50\u7A0B\u5E8F\u5305\n -breakiterator \u8BA1\u7B97\u5E26\u6709 BreakIterator \u7684\u7B2C\u4E00\u4E2A\u8BED\u53E5\n -bootclasspath \u8986\u76D6\u7531\u5F15\u5BFC\u7C7B\u52A0\u8F7D\u5668\u6240\u52A0\u8F7D\u7684\n \u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n -source \u63D0\u4F9B\u4E0E\u6307\u5B9A\u53D1\u884C\u7248\u7684\u6E90\u517C\u5BB9\u6027\n -extdirs \u8986\u76D6\u6240\u5B89\u88C5\u6269\u5C55\u7684\u4F4D\u7F6E\n -verbose \u8F93\u51FA\u6709\u5173 Javadoc \u6B63\u5728\u6267\u884C\u7684\u64CD\u4F5C\u7684\u4FE1\u606F\n -locale \u8981\u4F7F\u7528\u7684\u533A\u57DF\u8BBE\u7F6E, \u4F8B\u5982 en_US \u6216 en_US_WIN\n -encoding \u6E90\u6587\u4EF6\u7F16\u7801\u540D\u79F0\n -quiet \u4E0D\u663E\u793A\u72B6\u6001\u6D88\u606F\n -J \u76F4\u63A5\u5C06 \u4F20\u9012\u5230\u8FD0\u884C\u65F6\u7CFB\u7EDF\n -X \u8F93\u51FA\u975E\u6807\u51C6\u9009\u9879\u7684\u63D0\u8981\n + +main.Xusage=\ -Xmaxerrs \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u9519\u8BEF\u6570\n -Xmaxwarns \u8BBE\u7F6E\u8981\u8F93\u51FA\u7684\u6700\u5927\u8B66\u544A\u6570\n + +main.Xusage.foot=\u8FD9\u4E9B\u9009\u9879\u90FD\u662F\u975E\u6807\u51C6\u9009\u9879, \u5982\u6709\u66F4\u6539, \u6055\u4E0D\u53E6\u884C\u901A\u77E5\u3002 + main.option.already.seen={0}\u9009\u9879\u53EA\u80FD\u6307\u5B9A\u4E00\u6B21\u3002 main.requires_argument=\u9009\u9879{0}\u9700\u8981\u53C2\u6570\u3002 main.locale_first=\u5728\u547D\u4EE4\u884C\u4E2D, \u9009\u9879 -locale \u5FC5\u987B\u4E3A\u7B2C\u4E00\u4E2A\u9009\u9879\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties index 6a5e90e7836..27aa006bdc6 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ tracing.not.supported=\u8B66\u544A: \u30C8\u30EC\u30FC\u30B9\u306F\u73FE\u5728\u # # Usage message. # -usage=\u4F7F\u7528\u65B9\u6CD5: javah [options] \n\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002\n\n\t-help \u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n\t-classpath \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-d \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n\t-o \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)\n\t-jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n\t-version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n\t-verbose \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n\t-force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\n\n \u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002\n +usage=\u4F7F\u7528\u65B9\u6CD5: javah [options] \n\n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002\n\n\t-help \u30D8\u30EB\u30D7\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u3066\u7D42\u4E86\u3059\u308B\n\t-classpath \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-cp \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\r\n\t-bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9\n\t-d \u51FA\u529B\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\n\t-o \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B)\n\t-jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)\n\t-version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n\t-verbose \u8A73\u7D30\u306A\u51FA\u529B\u3092\u884C\u3046\n\t-force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080\n\n\u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002\n main.usage=\u4F7F\u7528\u65B9\u6CD5: \n javah [options] \n[options]\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059\u3002 main.opt.o=\ -o \u51FA\u529B\u30D5\u30A1\u30A4\u30EB(-d\u304B-o\u306E\u3069\u3061\u3089\u304B\u4E00\u65B9\u3092\u4F7F\u7528\u3059\u308B) @@ -60,6 +60,7 @@ main.opt.version=\ -version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C main.opt.jni=\ -jni JNI\u5F62\u5F0F\u306E\u30D8\u30C3\u30C0\u30FC\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8) main.opt.force=\ -force \u5E38\u306B\u51FA\u529B\u30D5\u30A1\u30A4\u30EB\u3092\u66F8\u304D\u8FBC\u3080 main.opt.classpath=\ -classpath \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9 +main.opt.cp=\ -cp \u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9 main.opt.bootclasspath=\ -bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u3092\u30ED\u30FC\u30C9\u3059\u308B\u30D1\u30B9 main.usage.foot=\u306F\u5B8C\u5168\u6307\u5B9A\u306E\u540D\u524D\u3067\u6307\u5B9A\u3057\u307E\u3059\n(java.lang.Object\u306A\u3069)\u3002 @@ -90,7 +91,7 @@ unknown.type.in.method.signature=\u53E4\u3044\u5F62\u5F0F\u306E\u30B9\u30BF\u30D err.prefix=\u30A8\u30E9\u30FC: err.cant.use.option.for.fm=\u6307\u5B9A\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u30FB\u30DE\u30CD\u30FC\u30B8\u30E3\u3067{0}\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 err.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC: {0} -err.ioerror=\u5165\u51FA\u529B\u30A8\u30E9\u30FC: {0} +err.ioerror=IO\u30A8\u30E9\u30FC: {0} err.missing.arg={0}\u306E\u5024\u304C\u3042\u308A\u307E\u305B\u3093 err.no.classes.specified=\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 err.unknown.option=\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0} diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties index 995b1cad499..e4565df67fd 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ tracing.not.supported=\u8B66\u544A: \u4E0D\u518D\u652F\u6301\u8DDF\u8E2A\u3002\u # # Usage message. # -usage=\u7528\u6CD5: javah [options] \n\n\u5176\u4E2D, [options] \u5305\u62EC:\n\n\t-help \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\u5E76\u9000\u51FA\n\t-classpath \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-bootclasspath \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84\n\t-d \u8F93\u51FA\u76EE\u5F55\n\t-o \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)\n\t-jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)\n\t-version \u8F93\u51FA\u7248\u672C\u4FE1\u606F\n\t-verbose \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n\t-force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6\n\n \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684,\n(\u4F8B\u5982 java.lang.Object)\u3002\n +usage=\u7528\u6CD5: javah [options] \n\n\u5176\u4E2D, [options] \u5305\u62EC:\n\n\t-help \u8F93\u51FA\u6B64\u5E2E\u52A9\u6D88\u606F\u5E76\u9000\u51FA\n\t-classpath \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-cp \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84\n\t-bootclasspath \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84\n\t-d \u8F93\u51FA\u76EE\u5F55\n\t-o \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00)\n\t-jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C)\n\t-version \u8F93\u51FA\u7248\u672C\u4FE1\u606F\n\t-verbose \u542F\u7528\u8BE6\u7EC6\u8F93\u51FA\n\t-force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6\n\n \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684,\n(\u4F8B\u5982, java.lang.Object)\u3002\n main.usage=\u7528\u6CD5: \n javah [options] \n\u5176\u4E2D, [options] \u5305\u62EC: main.opt.o=\ -o \u8F93\u51FA\u6587\u4EF6 (\u53EA\u80FD\u4F7F\u7528 -d \u6216 -o \u4E4B\u4E00) @@ -60,6 +60,7 @@ main.opt.version=\ -version \u8F93\u51FA\u7248\u672C\u4FE1\u606 main.opt.jni=\ -jni \u751F\u6210 JNI \u6837\u5F0F\u7684\u6807\u5934\u6587\u4EF6 (\u9ED8\u8BA4\u503C) main.opt.force=\ -force \u59CB\u7EC8\u5199\u5165\u8F93\u51FA\u6587\u4EF6 main.opt.classpath=\ -classpath \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84 +main.opt.cp=\ -cp \u4ECE\u4E2D\u52A0\u8F7D\u7C7B\u7684\u8DEF\u5F84 main.opt.bootclasspath=\ -bootclasspath \u4ECE\u4E2D\u52A0\u8F7D\u5F15\u5BFC\u7C7B\u7684\u8DEF\u5F84 main.usage.foot= \u662F\u4F7F\u7528\u5176\u5168\u9650\u5B9A\u540D\u79F0\u6307\u5B9A\u7684\n(\u4F8B\u5982, java.lang.Object)\u3002 diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties index e5b96053f10..72787232d52 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_ja.properties @@ -1,5 +1,5 @@ -err.prefix=\u30A8\u30E9\u30FC: +err.prefix=\u30A8\u30E9\u30FC: err.bad.constant.pool={0}\u306E\u5B9A\u6570\u30D7\u30FC\u30EB\u306E\u8AAD\u53D6\u308A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {1} err.class.not.found=\u30AF\u30E9\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0} @@ -55,6 +55,8 @@ main.opt.s=\ -s \u5185\u90E8\u30BF\u30A4\u30D7\u7F72\u540 main.opt.classpath=\ -classpath \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B +main.opt.cp=\ -cp \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B + main.opt.bootclasspath=\ -bootclasspath \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u4F4D\u7F6E\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B main.opt.constants=\ -constants \u9759\u7684final\u5B9A\u6570\u3092\u8868\u793A\u3059\u308B diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties index 97e4f5ce972..b9027ec9500 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap_zh_CN.properties @@ -1,5 +1,5 @@ -err.prefix=\u9519\u8BEF: +err.prefix=\u9519\u8BEF: err.bad.constant.pool=\u8BFB\u53D6{0}\u7684\u5E38\u91CF\u6C60\u65F6\u51FA\u9519: {1} err.class.not.found=\u627E\u4E0D\u5230\u7C7B: {0} @@ -55,6 +55,8 @@ main.opt.s=\ -s \u8F93\u51FA\u5185\u90E8\u7C7B\u578B\u7B7 main.opt.classpath=\ -classpath \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E +main.opt.cp=\ -cp \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E + main.opt.bootclasspath=\ -bootclasspath \u8986\u76D6\u5F15\u5BFC\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E main.opt.constants=\ -constants \u663E\u793A\u9759\u6001\u6700\u7EC8\u5E38\u91CF From 0ccb2841ea32b7cee8321fc6563f0d269f010d6d Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 24 Sep 2013 16:08:00 -0700 Subject: [PATCH 181/293] 8022585: VM crashes when ran with -XX:+PrintInlining Use adr_at() to access inline info structures in growableArray. Add ability to specify print inlining per method. Reviewed-by: twisti --- hotspot/src/share/vm/c1/c1_GraphBuilder.cpp | 4 ++- hotspot/src/share/vm/opto/bytecodeInfo.cpp | 10 +++--- hotspot/src/share/vm/opto/callGenerator.hpp | 3 +- hotspot/src/share/vm/opto/compile.cpp | 12 ++++--- hotspot/src/share/vm/opto/compile.hpp | 26 ++++++++------ hotspot/src/share/vm/opto/doCall.cpp | 4 +-- hotspot/src/share/vm/opto/library_call.cpp | 26 +++++++------- .../test/compiler/print/PrintInlining.java | 36 +++++++++++++++++++ 8 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 hotspot/test/compiler/print/PrintInlining.java diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index b7ea6eebb26..03d0d75fa30 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -4219,7 +4219,9 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes } } - if (!PrintInlining) return; + if (!PrintInlining && !compilation()->method()->has_option("PrintInlining")) { + return; + } CompileTask::print_inlining(callee, scope()->level(), bci(), msg); if (success && CIPrintMethodCodes) { callee->print_codes(); diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp index 45ba8d758b0..2ba7b1cf3b4 100644 --- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp +++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp @@ -123,7 +123,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, // Allows targeted inlining if(callee_method->should_inline()) { *wci_result = *(WarmCallInfo::always_hot()); - if (PrintInlining && Verbose) { + if (C->print_inlining() && Verbose) { CompileTask::print_inline_indent(inline_level()); tty->print_cr("Inlined method is hot: "); } @@ -137,7 +137,7 @@ bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, if(callee_method->interpreter_throwout_count() > InlineThrowCount && size < InlineThrowMaxSize ) { wci_result->set_profit(wci_result->profit() * 100); - if (PrintInlining && Verbose) { + if (C->print_inlining() && Verbose) { CompileTask::print_inline_indent(inline_level()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); } @@ -491,7 +491,7 @@ void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, C->log()->inline_fail(inline_msg); } } - if (PrintInlining) { + if (C->print_inlining()) { C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg); if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); if (Verbose && callee_method) { @@ -540,7 +540,7 @@ WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, #ifndef PRODUCT if (UseOldInlining && InlineWarmCalls - && (PrintOpto || PrintOptoInlining || PrintInlining)) { + && (PrintOpto || C->print_inlining())) { bool cold = wci.is_cold(); bool hot = !cold && wci.is_hot(); bool old_cold = !success; @@ -617,7 +617,7 @@ InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, J callee_method->is_compiled_lambda_form()) { max_inline_level_adjust += 1; // don't count method handle calls from java.lang.invoke implem } - if (max_inline_level_adjust != 0 && PrintInlining && (Verbose || WizardMode)) { + if (max_inline_level_adjust != 0 && C->print_inlining() && (Verbose || WizardMode)) { CompileTask::print_inline_indent(inline_level()); tty->print_cr(" \\-> discounting inline depth"); } diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp index 0f6b2d16590..a1616de4dc7 100644 --- a/hotspot/src/share/vm/opto/callGenerator.hpp +++ b/hotspot/src/share/vm/opto/callGenerator.hpp @@ -159,8 +159,9 @@ class CallGenerator : public ResourceObj { virtual void print_inlining_late(const char* msg) { ShouldNotReachHere(); } static void print_inlining(Compile* C, ciMethod* callee, int inline_level, int bci, const char* msg) { - if (PrintInlining) + if (C->print_inlining()) { C->print_inlining(callee, inline_level, bci, msg); + } } }; diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index 1c625d679b3..0fed4e06c72 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -654,7 +654,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr _inlining_progress(false), _inlining_incrementally(false), _print_inlining_list(NULL), - _print_inlining(0) { + _print_inlining_idx(0) { C = this; CompileWrapper cw(this); @@ -679,6 +679,8 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr set_print_assembly(print_opto_assembly); set_parsed_irreducible_loop(false); #endif + set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining)); + set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics")); if (ProfileTraps) { // Make sure the method being compiled gets its own MDO, @@ -710,7 +712,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr PhaseGVN gvn(node_arena(), estimated_size); set_initial_gvn(&gvn); - if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { + if (print_inlining() || print_intrinsics()) { _print_inlining_list = new (comp_arena())GrowableArray(comp_arena(), 1, 1, PrintInliningBuffer()); } { // Scope for timing the parser @@ -937,7 +939,7 @@ Compile::Compile( ciEnv* ci_env, _inlining_progress(false), _inlining_incrementally(false), _print_inlining_list(NULL), - _print_inlining(0) { + _print_inlining_idx(0) { C = this; #ifndef PRODUCT @@ -3611,7 +3613,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n } void Compile::dump_inlining() { - if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) { + if (print_inlining() || print_intrinsics()) { // Print inlining message for candidates that we couldn't inline // for lack of space or non constant receiver for (int i = 0; i < _late_inlines.length(); i++) { @@ -3635,7 +3637,7 @@ void Compile::dump_inlining() { } } for (int i = 0; i < _print_inlining_list->length(); i++) { - tty->print(_print_inlining_list->at(i).ss()->as_string()); + tty->print(_print_inlining_list->adr_at(i)->ss()->as_string()); } } } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 8d862c24125..631372efabc 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -312,6 +312,8 @@ class Compile : public Phase { bool _do_method_data_update; // True if we generate code to update MethodData*s int _AliasLevel; // Locally-adjusted version of AliasLevel flag. bool _print_assembly; // True if we should dump assembly code for this compilation + bool _print_inlining; // True if we should print inlining for this compilation + bool _print_intrinsics; // True if we should print intrinsics for this compilation #ifndef PRODUCT bool _trace_opto_output; bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing @@ -414,7 +416,7 @@ class Compile : public Phase { }; GrowableArray* _print_inlining_list; - int _print_inlining; + int _print_inlining_idx; // Only keep nodes in the expensive node list that need to be optimized void cleanup_expensive_nodes(PhaseIterGVN &igvn); @@ -426,24 +428,24 @@ class Compile : public Phase { public: outputStream* print_inlining_stream() const { - return _print_inlining_list->at(_print_inlining).ss(); + return _print_inlining_list->adr_at(_print_inlining_idx)->ss(); } void print_inlining_skip(CallGenerator* cg) { - if (PrintInlining) { - _print_inlining_list->at(_print_inlining).set_cg(cg); - _print_inlining++; - _print_inlining_list->insert_before(_print_inlining, PrintInliningBuffer()); + if (_print_inlining) { + _print_inlining_list->adr_at(_print_inlining_idx)->set_cg(cg); + _print_inlining_idx++; + _print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer()); } } void print_inlining_insert(CallGenerator* cg) { - if (PrintInlining) { + if (_print_inlining) { for (int i = 0; i < _print_inlining_list->length(); i++) { - if (_print_inlining_list->at(i).cg() == cg) { + if (_print_inlining_list->adr_at(i)->cg() == cg) { _print_inlining_list->insert_before(i+1, PrintInliningBuffer()); - _print_inlining = i+1; - _print_inlining_list->at(i).set_cg(NULL); + _print_inlining_idx = i+1; + _print_inlining_list->adr_at(i)->set_cg(NULL); return; } } @@ -572,6 +574,10 @@ class Compile : public Phase { int AliasLevel() const { return _AliasLevel; } bool print_assembly() const { return _print_assembly; } void set_print_assembly(bool z) { _print_assembly = z; } + bool print_inlining() const { return _print_inlining; } + void set_print_inlining(bool z) { _print_inlining = z; } + bool print_intrinsics() const { return _print_intrinsics; } + void set_print_intrinsics(bool z) { _print_intrinsics = z; } // check the CompilerOracle for special behaviours for this compile bool method_has_option(const char * option) { return method() != NULL && method()->has_option(option); diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index e55a01ba638..8784bbe2dc5 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -41,9 +41,9 @@ #include "runtime/sharedRuntime.hpp" void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) { - if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) { + if (TraceTypeProfile || C->print_inlining()) { outputStream* out = tty; - if (!PrintInlining) { + if (!C->print_inlining()) { if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) { method->print_short_name(); tty->cr(); diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 2bfa25fa9c2..902ed5919f3 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -543,7 +543,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { Compile* C = kit.C; int nodes = C->unique(); #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { char buf[1000]; const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); tty->print_cr("Intrinsic %s", str); @@ -554,7 +554,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { // Try to inline the intrinsic. if (kit.try_to_inline()) { - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); @@ -570,7 +570,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { } // The intrinsic bailed out - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { if (jvms->has_method()) { // Not a root compile. const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)"; @@ -592,7 +592,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { int nodes = C->unique(); #ifndef PRODUCT assert(is_predicted(), "sanity"); - if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { char buf[1000]; const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); tty->print_cr("Predicate for intrinsic %s", str); @@ -603,7 +603,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { Node* slow_ctl = kit.try_to_predicate(); if (!kit.failing()) { - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); } C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); @@ -617,7 +617,7 @@ Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) { } // The intrinsic bailed out - if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { + if (C->print_intrinsics() || C->print_inlining()) { if (jvms->has_method()) { // Not a root compile. const char* msg = "failed to generate predicate for intrinsic"; @@ -2299,7 +2299,7 @@ const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_ const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); #ifndef PRODUCT - if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { + if (C->print_intrinsics() || C->print_inlining()) { tty->print(" from base type: "); adr_type->dump(); tty->print(" sharpened value: "); tjp->dump(); } @@ -3260,7 +3260,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { if (mirror_con == NULL) return false; // cannot happen? #ifndef PRODUCT - if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { + if (C->print_intrinsics() || C->print_inlining()) { ciType* k = mirror_con->java_mirror_type(); if (k) { tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id())); @@ -3952,14 +3952,14 @@ bool LibraryCallKit::inline_native_getClass() { // caller sensitive methods. bool LibraryCallKit::inline_native_Reflection_getCallerClass() { #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); } #endif if (!jvms()->has_method()) { #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Bailing out because intrinsic was inlined at top level"); } #endif @@ -3983,7 +3983,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() { // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass). if (!m->caller_sensitive()) { #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n); } #endif @@ -3999,7 +3999,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() { set_result(makecon(TypeInstPtr::make(caller_mirror))); #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth()); tty->print_cr(" JVM state at this point:"); for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { @@ -4015,7 +4015,7 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() { } #ifndef PRODUCT - if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { + if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth()); tty->print_cr(" JVM state at this point:"); for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { diff --git a/hotspot/test/compiler/print/PrintInlining.java b/hotspot/test/compiler/print/PrintInlining.java new file mode 100644 index 00000000000..877d25e8c38 --- /dev/null +++ b/hotspot/test/compiler/print/PrintInlining.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8022585 + * @summary VM crashes when ran with -XX:+PrintInlining + * @run main/othervm -Xcomp -XX:+PrintInlining PrintInlining + * + */ + +public class PrintInlining { + public static void main(String[] args) { + System.out.println("Passed"); + } +} From 2233312946292ac77ccf9092fb50e1fc91391c34 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Tue, 24 Sep 2013 16:12:06 -0700 Subject: [PATCH 182/293] 8016328: Regression : Javadoc i18n regression caused by fix for 8012375 Reviewed-by: jjg --- .../doclets/formats/html/markup/HtmlTree.java | 43 ++++++++++++++++++- .../formats/html/markup/HtmlWriter.java | 9 +++- .../com/sun/javadoc/testHref/TestHref.java | 10 ++--- .../testJavascript/TestJavascript.java | 11 ++++- .../testLinkTaglet/TestLinkTaglet.java | 8 ++-- .../TestPrivateClasses.java | 4 +- .../javadoc/testUseOption/TestUseOption.java | 6 +-- 7 files changed, 73 insertions(+), 18 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java index dc59eb0f4a0..fb7c409c3f0 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java @@ -28,6 +28,7 @@ package com.sun.tools.doclets.formats.html.markup; import java.io.IOException; import java.io.Writer; import java.util.*; +import java.nio.charset.*; import com.sun.tools.doclets.internal.toolkit.Content; import com.sun.tools.doclets.internal.toolkit.util.*; @@ -163,6 +164,46 @@ public class HtmlTree extends Content { return s; } + /** + * A set of ASCII URI characters to be left unencoded. + */ + public static BitSet NONENCODING_CHARS = new BitSet(256); + + static { + // alphabetic characters + for (int i = 'a'; i <= 'z'; i++) { + NONENCODING_CHARS.set(i); + } + for (int i = 'A'; i <= 'Z'; i++) { + NONENCODING_CHARS.set(i); + } + // numeric characters + for (int i = '0'; i <= '9'; i++) { + NONENCODING_CHARS.set(i); + } + // Reserved characters as per RFC 3986. These are set of delimiting characters. + String noEnc = ":/?#[]@!$&'()*+,;="; + // Unreserved characters as per RFC 3986 which should not be percent encoded. + noEnc += "-._~"; + for (int i = 0; i < noEnc.length(); i++) { + NONENCODING_CHARS.set(noEnc.charAt(i)); + } + } + + private static String encodeURL(String url) { + byte[] urlBytes = url.getBytes(Charset.forName("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < urlBytes.length; i++) { + int c = urlBytes[i]; + if (NONENCODING_CHARS.get(c & 0xFF)) { + sb.append((char) c); + } else { + sb.append(String.format("%%%02X", c & 0xFF)); + } + } + return sb.toString(); + } + /** * Generates an HTML anchor tag. * @@ -172,7 +213,7 @@ public class HtmlTree extends Content { */ public static HtmlTree A(String ref, Content body) { HtmlTree htmltree = new HtmlTree(HtmlTag.A, nullCheck(body)); - htmltree.addAttr(HtmlAttr.HREF, ref); + htmltree.addAttr(HtmlAttr.HREF, encodeURL(ref)); return htmltree; } diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java index 36becd2e7ef..e1da06598a6 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java @@ -335,6 +335,12 @@ public class HtmlWriter { " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL + " targetPage = \"undefined\";" + DocletConstants.NL + " function validURL(url) {" + DocletConstants.NL + + " try {" + DocletConstants.NL + + " url = decodeURIComponent(url);" + DocletConstants.NL + + " }" + DocletConstants.NL + + " catch (error) {" + DocletConstants.NL + + " return false;" + DocletConstants.NL + + " }" + DocletConstants.NL + " var pos = url.indexOf(\".html\");" + DocletConstants.NL + " if (pos == -1 || pos != url.length - 5)" + DocletConstants.NL + " return false;" + DocletConstants.NL + @@ -346,7 +352,8 @@ public class HtmlWriter { " if ('a' <= ch && ch <= 'z' ||" + DocletConstants.NL + " 'A' <= ch && ch <= 'Z' ||" + DocletConstants.NL + " ch == '$' ||" + DocletConstants.NL + - " ch == '_') {" + DocletConstants.NL + + " ch == '_' ||" + DocletConstants.NL + + " ch.charCodeAt(0) > 127) {" + DocletConstants.NL + " allowNumber = true;" + DocletConstants.NL + " allowSep = true;" + DocletConstants.NL + " } else if ('0' <= ch && ch <= '9'" + DocletConstants.NL + diff --git a/langtools/test/com/sun/javadoc/testHref/TestHref.java b/langtools/test/com/sun/javadoc/testHref/TestHref.java index 297ddc69164..b8c4a24ca05 100644 --- a/langtools/test/com/sun/javadoc/testHref/TestHref.java +++ b/langtools/test/com/sun/javadoc/testHref/TestHref.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4663254 + * @bug 4663254 8016328 * @summary Verify that spaces do not appear in hrefs and anchors. * @author jamieh * @library ../lib/ @@ -46,11 +46,11 @@ public class TestHref extends JavadocTester { private static final String[][] TEST = { //External link. {BUG_ID + FS + "pkg" + FS + "C1.html", - "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait(long, int)\"" + "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait(long,%20int)\"" }, //Member summary table link. {BUG_ID + FS + "pkg" + FS + "C1.html", - "href=\"../pkg/C1.html#method(int, int, java.util.ArrayList)\"" + "href=\"../pkg/C1.html#method(int,%20int,%20java.util.ArrayList)\"" }, //Anchor test. {BUG_ID + FS + "pkg" + FS + "C1.html", @@ -66,11 +66,11 @@ public class TestHref extends JavadocTester { }, //{@link} test. {BUG_ID + FS + "pkg" + FS + "C2.html", - "Link: " + "Link: " }, //@see test. {BUG_ID + FS + "pkg" + FS + "C2.html", - "See Also:" + NL + "
    " + "See Also:" + NL + "
    " }, //Header does not link to the page itself. diff --git a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java index 763566a03ac..28602092110 100644 --- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java +++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4665566 4855876 7025314 8012375 8015997 + * @bug 4665566 4855876 7025314 8012375 8015997 8016328 * @summary Verify that the output has the right javascript. * @author jamieh * @library ../lib/ @@ -56,6 +56,12 @@ public class TestJavascript extends JavadocTester { " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + NL + " targetPage = \"undefined\";" + NL + " function validURL(url) {" + NL + + " try {" + NL + + " url = decodeURIComponent(url);" + NL + + " }" + NL + + " catch (error) {" + NL + + " return false;" + NL + + " }" + NL + " var pos = url.indexOf(\".html\");" + NL + " if (pos == -1 || pos != url.length - 5)" + NL + " return false;" + NL + @@ -67,7 +73,8 @@ public class TestJavascript extends JavadocTester { " if ('a' <= ch && ch <= 'z' ||" + NL + " 'A' <= ch && ch <= 'Z' ||" + NL + " ch == '$' ||" + NL + - " ch == '_') {" + NL + + " ch == '_' ||" + NL + + " ch.charCodeAt(0) > 127) {" + NL + " allowNumber = true;" + NL + " allowSep = true;" + NL + " } else if ('0' <= ch && ch <= '9'" + NL + diff --git a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java index 4720fe4d2be..ef9dd2bbb9a 100644 --- a/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java +++ b/langtools/test/com/sun/javadoc/testLinkTaglet/TestLinkTaglet.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4732864 6280605 7064544 8014636 + * @bug 4732864 6280605 7064544 8014636 8016328 * @summary Make sure that you can link from one member to another using * non-qualified name, furthermore, ensure the right one is linked. * @author jamieh @@ -49,9 +49,9 @@ public class TestLinkTaglet extends JavadocTester { "Qualified Link: C.InnerC.
    " + NL + " Unqualified Link1: C.InnerC.
    " + NL + " Unqualified Link2: C.InnerC.
    " + NL + - " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
    " + NL + - " Unqualified Link: method(C.InnerC, C.InnerC2).
    " + NL + - " Unqualified Link: method(InnerC, InnerC2).
    " + " Qualified Link: method(pkg.C.InnerC, pkg.C.InnerC2).
    " + NL + + " Unqualified Link: method(C.InnerC, C.InnerC2).
    " + NL + + " Unqualified Link: method(InnerC, InnerC2).
    " }, {BUG_ID + FS + "pkg" + FS + "C.InnerC.html", "Link to member in outer class: C.MEMBER
    " + NL + diff --git a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java index b6ae263d8a4..b7a9bc73a10 100644 --- a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java +++ b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4780441 4874845 4978816 8014017 + * @bug 4780441 4874845 4978816 8014017 8016328 * @summary Make sure that when the -private flag is not used, members * inherited from package private class are documented in the child. * @@ -177,7 +177,7 @@ public class TestPrivateClasses extends JavadocTester { // Should document that a method overrides method from private class. {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html", "
    Overrides:
    " + NL + - "
    " + + "
    " + "methodOverridenFromParent in class " + "" + "PrivateParent
    "}, diff --git a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java index 6a61e43f3b1..a1e0e970af0 100644 --- a/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java +++ b/langtools/test/com/sun/javadoc/testUseOption/TestUseOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4496290 4985072 7006178 7068595 + * @bug 4496290 4985072 7006178 7068595 8016328 * @summary A simple test to determine if -use works. * @author jamieh * @library ../lib/ @@ -60,7 +60,7 @@ public class TestUseOption extends JavadocTester { "UsedInC in <Unnamed>" }, {BUG_ID + "-3" + FS + "package-use.html", "" + - "UsedInC " + "UsedInC " } }; From f8d5db06b9ca8423b4b5982c9c9cb8b923950d24 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 25 Sep 2013 08:17:37 +0530 Subject: [PATCH 183/293] 8025325: parseFloat does not handle '.' in exponent part Reviewed-by: hannesw --- .../internal/runtime/GlobalFunctions.java | 2 +- nashorn/test/script/basic/JDK-8025325.js | 35 +++++++++++++++++++ .../test/script/basic/JDK-8025325.js.EXPECTED | 5 +++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8025325.js create mode 100644 nashorn/test/script/basic/JDK-8025325.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java index 9ddc7090b2b..c750d80e913 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java @@ -211,7 +211,7 @@ loop: switch (ch) { case '.': // dot allowed only once - if (dotSeen) { + if (exponentOffset != -1 || dotSeen) { break loop; } dotSeen = true; diff --git a/nashorn/test/script/basic/JDK-8025325.js b/nashorn/test/script/basic/JDK-8025325.js new file mode 100644 index 00000000000..63dfef9d96e --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025325.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025325: parseFloat does not handle '.' in exponent part + * + * @test + * @run + */ + +print(parseFloat("2e2.")); +print(parseFloat("2e2.3")); +print(parseFloat("2e2.fdgdf")); +print(parseFloat("2e2. gdfgdf")); +print(parseFloat("2e2. ")); diff --git a/nashorn/test/script/basic/JDK-8025325.js.EXPECTED b/nashorn/test/script/basic/JDK-8025325.js.EXPECTED new file mode 100644 index 00000000000..4ddf679a54b --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025325.js.EXPECTED @@ -0,0 +1,5 @@ +200 +200 +200 +200 +200 From ddddd1d31f770943fcf2e737a7bf5ac490be27b6 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 25 Sep 2013 09:47:24 +0200 Subject: [PATCH 184/293] 8025140: TEST_BUG: java/util/logging/Logger/getGlobal tests fail due to timeout Arbitrary timeouts in the tests @run lines where too agressive for some configurations. The tests will now run with default timeout. Reviewed-by: alanb, mchung --- .../Logger/getGlobal/TestGetGlobal.java | 24 +++++++++---------- .../Logger/getGlobal/TestGetGlobalByName.java | 24 +++++++++---------- .../getGlobal/TestGetGlobalConcurrent.java | 24 +++++++++---------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java index 4c6b39b0acd..e87e15f81fc 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobal.java @@ -29,18 +29,18 @@ import java.util.logging.Logger; * @bug 7184195 * @summary checks that java.util.logging.Logger.getGlobal().info() logs without configuration * @build TestGetGlobal testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl - * @run main/othervm/timeout=10 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal + * @run main/othervm TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobal + * @run main/othervm -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobal * @author danielfuchs */ public class TestGetGlobal { diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java index 62580a8bc3b..91968db400b 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalByName.java @@ -29,18 +29,18 @@ import java.util.logging.Logger; * @bug 7184195 * @summary checks that java.util.logging.Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).info() logs without configuration * @build TestGetGlobalByName testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl - * @run main/othervm/timeout=10 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName + * @run main/othervm TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalByName + * @run main/othervm -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalByName * @author danielfuchs */ public class TestGetGlobalByName { diff --git a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java index e3f9d1d8872..23688e1bca5 100644 --- a/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java +++ b/jdk/test/java/util/logging/Logger/getGlobal/TestGetGlobalConcurrent.java @@ -30,18 +30,18 @@ import java.util.logging.Logger; * @bug 7184195 8021003 * @summary Test that the global logger can log with no configuration when accessed from multiple threads. * @build TestGetGlobalConcurrent testgetglobal.HandlerImpl testgetglobal.LogManagerImpl1 testgetglobal.LogManagerImpl2 testgetglobal.LogManagerImpl3 testgetglobal.BadLogManagerImpl testgetglobal.DummyLogManagerImpl - * @run main/othervm/timeout=10 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent - * @run main/othervm/timeout=10 -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent - * @run main/othervm/timeout=10/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl1 TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl2 TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.LogManagerImpl3 TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.BadLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent + * @run main/othervm/policy=policy -Djava.security.manager -Djava.util.logging.manager=testgetglobal.DummyLogManagerImpl TestGetGlobalConcurrent * @author danielfuchs */ public class TestGetGlobalConcurrent { From ab5637182c30ed955197bdad674c7bd51f8b2f3a Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Wed, 25 Sep 2013 13:25:24 +0200 Subject: [PATCH 185/293] 7163191: G1: introduce a "heap spanning table" abstraction Add G1BiasedArray that is an array where each element represents a fixed-sized subdivision of the heap. Use this abstraction to refactor the HeapRegionSeq class. Reviewed-by: brutisso --- hotspot/make/excludeSrc.make | 2 +- .../vm/gc_implementation/g1/g1BiasedArray.cpp | 141 ++++++++++++++ .../vm/gc_implementation/g1/g1BiasedArray.hpp | 181 ++++++++++++++++++ .../gc_implementation/g1/g1CollectedHeap.cpp | 6 +- .../vm/gc_implementation/g1/heapRegionSeq.cpp | 49 ++--- .../vm/gc_implementation/g1/heapRegionSeq.hpp | 59 +++--- .../g1/heapRegionSeq.inline.hpp | 22 +-- .../vm/gc_implementation/g1/vmStructs_g1.hpp | 12 +- hotspot/src/share/vm/prims/jni.cpp | 4 + 9 files changed, 389 insertions(+), 87 deletions(-) create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make index c3a9b4dea0e..a95dc1b114c 100644 --- a/hotspot/make/excludeSrc.make +++ b/hotspot/make/excludeSrc.make @@ -88,7 +88,7 @@ ifeq ($(INCLUDE_ALL_GCS), false) g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \ g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp \ g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \ - heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ + g1BiasedArray.cpp heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp \ adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \ cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \ diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp new file mode 100644 index 00000000000..7f5023b422b --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/g1/g1BiasedArray.hpp" + +#ifndef PRODUCT +void G1BiasedMappedArrayBase::verify_index(idx_t index) const { + guarantee(_base != NULL, "Array not initialized"); + guarantee(index < length(), err_msg("Index out of bounds index: "SIZE_FORMAT" length: "SIZE_FORMAT, index, length())); +} + +void G1BiasedMappedArrayBase::verify_biased_index(idx_t biased_index) const { + guarantee(_biased_base != NULL, "Array not initialized"); + guarantee(biased_index >= bias() && biased_index < (bias() + length()), + err_msg("Biased index out of bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length())); +} + +void G1BiasedMappedArrayBase::verify_biased_index_inclusive_end(idx_t biased_index) const { + guarantee(_biased_base != NULL, "Array not initialized"); + guarantee(biased_index >= bias() && biased_index <= (bias() + length()), + err_msg("Biased index out of inclusive bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length())); +} + +class TestMappedArray : public G1BiasedMappedArray { +protected: + virtual int default_value() const { return 0xBAADBABE; } +public: + static void test_biasedarray() { + const size_t REGION_SIZE_IN_WORDS = 512; + const size_t NUM_REGIONS = 20; + HeapWord* fake_heap = (HeapWord*)LP64_ONLY(0xBAAA00000) NOT_LP64(0xBA000000); // Any value that is non-zero + + TestMappedArray array; + array.initialize(fake_heap, fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS, + REGION_SIZE_IN_WORDS * HeapWordSize); + // Check address calculation (bounds) + assert(array.bottom_address_mapped() == fake_heap, + err_msg("bottom mapped address should be "PTR_FORMAT", but is "PTR_FORMAT, fake_heap, array.bottom_address_mapped())); + assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be"); + + int* bottom = array.address_mapped_to(fake_heap); + assert((void*)bottom == (void*) array.base(), "must be"); + int* end = array.address_mapped_to(fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS); + assert((void*)end == (void*)(array.base() + array.length()), "must be"); + // The entire array should contain default value elements + for (int* current = bottom; current < end; current++) { + assert(*current == array.default_value(), "must be"); + } + + // Test setting values in the table + + HeapWord* region_start_address = fake_heap + REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2); + HeapWord* region_end_address = fake_heap + (REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2) + REGION_SIZE_IN_WORDS - 1); + + // Set/get by address tests: invert some value; first retrieve one + int actual_value = array.get_by_index(NUM_REGIONS / 2); + array.set_by_index(NUM_REGIONS / 2, ~actual_value); + // Get the same value by address, should correspond to the start of the "region" + int value = array.get_by_address(region_start_address); + assert(value == ~actual_value, "must be"); + // Get the same value by address, at one HeapWord before the start + value = array.get_by_address(region_start_address - 1); + assert(value == array.default_value(), "must be"); + // Get the same value by address, at the end of the "region" + value = array.get_by_address(region_end_address); + assert(value == ~actual_value, "must be"); + // Make sure the next value maps to another index + value = array.get_by_address(region_end_address + 1); + assert(value == array.default_value(), "must be"); + + // Reset the value in the array + array.set_by_address(region_start_address + (region_end_address - region_start_address) / 2, actual_value); + + // The entire array should have the default value again + for (int* current = bottom; current < end; current++) { + assert(*current == array.default_value(), "must be"); + } + + // Set/get by index tests: invert some value + idx_t index = NUM_REGIONS / 2; + actual_value = array.get_by_index(index); + array.set_by_index(index, ~actual_value); + + value = array.get_by_index(index); + assert(value == ~actual_value, "must be"); + + value = array.get_by_index(index - 1); + assert(value == array.default_value(), "must be"); + + value = array.get_by_index(index + 1); + assert(value == array.default_value(), "must be"); + + array.set_by_index(0, 0); + value = array.get_by_index(0); + assert(value == 0, "must be"); + + array.set_by_index(array.length() - 1, 0); + value = array.get_by_index(array.length() - 1); + assert(value == 0, "must be"); + + array.set_by_index(index, 0); + + // The array should have three zeros, and default values otherwise + size_t num_zeros = 0; + for (int* current = bottom; current < end; current++) { + assert(*current == array.default_value() || *current == 0, "must be"); + if (*current == 0) { + num_zeros++; + } + } + assert(num_zeros == 3, "must be"); + } +}; + +void TestG1BiasedArray_test() { + TestMappedArray::test_biasedarray(); +} + +#endif diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp new file mode 100644 index 00000000000..f80c70b4e36 --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/g1/g1BiasedArray.hpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP + +#include "utilities/debug.hpp" +#include "memory/allocation.inline.hpp" + +// Implements the common base functionality for arrays that contain provisions +// for accessing its elements using a biased index. +// The element type is defined by the instantiating the template. +class G1BiasedMappedArrayBase VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; +public: + typedef size_t idx_t; +protected: + address _base; // the real base address + size_t _length; // the length of the array + address _biased_base; // base address biased by "bias" elements + size_t _bias; // the bias, i.e. the offset biased_base is located to the right in elements + uint _shift_by; // the amount of bits to shift right when mapping to an index of the array. + +protected: + + G1BiasedMappedArrayBase() : _base(NULL), _length(0), _biased_base(NULL), + _bias(0), _shift_by(0) { } + + // Allocate a new array, generic version. + static address create_new_base_array(size_t length, size_t elem_size) { + assert(length > 0, "just checking"); + assert(elem_size > 0, "just checking"); + return NEW_C_HEAP_ARRAY(u_char, length * elem_size, mtGC); + } + + // Initialize the members of this class. The biased start address of this array + // is the bias (in elements) multiplied by the element size. + void initialize_base(address base, size_t length, size_t bias, size_t elem_size, uint shift_by) { + assert(base != NULL, "just checking"); + assert(length > 0, "just checking"); + assert(shift_by < sizeof(uintptr_t) * 8, err_msg("Shifting by %zd, larger than word size?", shift_by)); + _base = base; + _length = length; + _biased_base = base - (bias * elem_size); + _bias = bias; + _shift_by = shift_by; + } + + // Allocate and initialize this array to cover the heap addresses in the range + // of [bottom, end). + void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) { + assert(mapping_granularity_in_bytes > 0, "just checking"); + assert(is_power_of_2(mapping_granularity_in_bytes), + err_msg("mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes)); + assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0, + err_msg("bottom mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, + mapping_granularity_in_bytes, bottom)); + assert((uintptr_t)end % mapping_granularity_in_bytes == 0, + err_msg("end mapping area address must be a multiple of mapping granularity %zd, is "PTR_FORMAT, + mapping_granularity_in_bytes, end)); + size_t num_target_elems = (end - bottom) / (mapping_granularity_in_bytes / HeapWordSize); + idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes; + address base = create_new_base_array(num_target_elems, target_elem_size_in_bytes); + initialize_base(base, num_target_elems, bias, target_elem_size_in_bytes, log2_intptr(mapping_granularity_in_bytes)); + } + + size_t bias() const { return _bias; } + uint shift_by() const { return _shift_by; } + + void verify_index(idx_t index) const PRODUCT_RETURN; + void verify_biased_index(idx_t biased_index) const PRODUCT_RETURN; + void verify_biased_index_inclusive_end(idx_t biased_index) const PRODUCT_RETURN; + +public: + // Return the length of the array in elements. + size_t length() const { return _length; } +}; + +// Array that provides biased access and mapping from (valid) addresses in the +// heap into this array. +template +class G1BiasedMappedArray : public G1BiasedMappedArrayBase { +public: + typedef G1BiasedMappedArrayBase::idx_t idx_t; + + T* base() const { return (T*)G1BiasedMappedArrayBase::_base; } + // Return the element of the given array at the given index. Assume + // the index is valid. This is a convenience method that does sanity + // checking on the index. + T get_by_index(idx_t index) const { + verify_index(index); + return this->base()[index]; + } + + // Set the element of the given array at the given index to the + // given value. Assume the index is valid. This is a convenience + // method that does sanity checking on the index. + void set_by_index(idx_t index, T value) { + verify_index(index); + this->base()[index] = value; + } + + // The raw biased base pointer. + T* biased_base() const { return (T*)G1BiasedMappedArrayBase::_biased_base; } + + // Return the element of the given array that covers the given word in the + // heap. Assumes the index is valid. + T get_by_address(HeapWord* value) const { + idx_t biased_index = ((uintptr_t)value) >> this->shift_by(); + this->verify_biased_index(biased_index); + return biased_base()[biased_index]; + } + + // Set the value of the array entry that corresponds to the given array. + void set_by_address(HeapWord * address, T value) { + idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); + this->verify_biased_index(biased_index); + biased_base()[biased_index] = value; + } + +protected: + // Returns the address of the element the given address maps to + T* address_mapped_to(HeapWord* address) { + idx_t biased_index = ((uintptr_t)address) >> this->shift_by(); + this->verify_biased_index_inclusive_end(biased_index); + return biased_base() + biased_index; + } + +public: + // Return the smallest address (inclusive) in the heap that this array covers. + HeapWord* bottom_address_mapped() const { + return (HeapWord*) ((uintptr_t)this->bias() << this->shift_by()); + } + + // Return the highest address (exclusive) in the heap that this array covers. + HeapWord* end_address_mapped() const { + return (HeapWord*) ((uintptr_t)(this->bias() + this->length()) << this->shift_by()); + } + +protected: + virtual T default_value() const = 0; + // Set all elements of the given array to the given value. + void clear() { + T value = default_value(); + for (idx_t i = 0; i < length(); i++) { + set_by_index(i, value); + } + } +public: + G1BiasedMappedArray() {} + + // Allocate and initialize this array to cover the heap addresses in the range + // of [bottom, end). + void initialize(HeapWord* bottom, HeapWord* end, size_t mapping_granularity) { + G1BiasedMappedArrayBase::initialize(bottom, end, sizeof(T), mapping_granularity); + this->clear(); + } +}; + +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BIASEDARRAY_HPP diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 1d8ff8a26dc..0ecfd3ab3bb 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2069,8 +2069,10 @@ jint G1CollectedHeap::initialize() { _g1_storage.initialize(g1_rs, 0); _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0); _hrs.initialize((HeapWord*) _g1_reserved.start(), - (HeapWord*) _g1_reserved.end(), - _expansion_regions); + (HeapWord*) _g1_reserved.end()); + assert(_hrs.max_length() == _expansion_regions, + err_msg("max length: %u expansion regions: %u", + _hrs.max_length(), _expansion_regions)); // Do later initialization work for concurrent refinement. _cg1r->init(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp index dade3dfdfcf..eaa8e10f38d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp @@ -71,27 +71,16 @@ uint HeapRegionSeq::find_contiguous_from(uint from, uint num) { // Public -void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end, - uint max_length) { +void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end) { assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0, "bottom should be heap region aligned"); assert((uintptr_t) end % HeapRegion::GrainBytes == 0, "end should be heap region aligned"); - _length = 0; - _heap_bottom = bottom; - _heap_end = end; - _region_shift = HeapRegion::LogOfHRGrainBytes; _next_search_index = 0; _allocated_length = 0; - _max_length = max_length; - _regions = NEW_C_HEAP_ARRAY(HeapRegion*, max_length, mtGC); - memset(_regions, 0, (size_t) max_length * sizeof(HeapRegion*)); - _regions_biased = _regions - ((uintx) bottom >> _region_shift); - - assert(&_regions[0] == &_regions_biased[addr_to_index_biased(bottom)], - "bottom should be included in the region with index 0"); + _regions.initialize(bottom, end, HeapRegion::GrainBytes); } MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, @@ -101,15 +90,15 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, G1CollectedHeap* g1h = G1CollectedHeap::heap(); HeapWord* next_bottom = old_end; - assert(_heap_bottom <= next_bottom, "invariant"); + assert(heap_bottom() <= next_bottom, "invariant"); while (next_bottom < new_end) { - assert(next_bottom < _heap_end, "invariant"); + assert(next_bottom < heap_end(), "invariant"); uint index = length(); - assert(index < _max_length, "otherwise we cannot expand further"); + assert(index < max_length(), "otherwise we cannot expand further"); if (index == 0) { // We have not allocated any regions so far - assert(next_bottom == _heap_bottom, "invariant"); + assert(next_bottom == heap_bottom(), "invariant"); } else { // next_bottom should match the end of the last/previous region assert(next_bottom == at(index - 1)->end(), "invariant"); @@ -122,8 +111,8 @@ MemRegion HeapRegionSeq::expand_by(HeapWord* old_end, // allocation failed, we bail out and return what we have done so far return MemRegion(old_end, next_bottom); } - assert(_regions[index] == NULL, "invariant"); - _regions[index] = new_hr; + assert(_regions.get_by_index(index) == NULL, "invariant"); + _regions.set_by_index(index, new_hr); increment_allocated_length(); } // Have to increment the length first, otherwise we will get an @@ -228,26 +217,26 @@ uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) { #ifndef PRODUCT void HeapRegionSeq::verify_optional() { - guarantee(_length <= _allocated_length, + guarantee(length() <= _allocated_length, err_msg("invariant: _length: %u _allocated_length: %u", - _length, _allocated_length)); - guarantee(_allocated_length <= _max_length, + length(), _allocated_length)); + guarantee(_allocated_length <= max_length(), err_msg("invariant: _allocated_length: %u _max_length: %u", - _allocated_length, _max_length)); - guarantee(_next_search_index <= _length, + _allocated_length, max_length())); + guarantee(_next_search_index <= length(), err_msg("invariant: _next_search_index: %u _length: %u", - _next_search_index, _length)); + _next_search_index, length())); - HeapWord* prev_end = _heap_bottom; + HeapWord* prev_end = heap_bottom(); for (uint i = 0; i < _allocated_length; i += 1) { - HeapRegion* hr = _regions[i]; + HeapRegion* hr = _regions.get_by_index(i); guarantee(hr != NULL, err_msg("invariant: i: %u", i)); guarantee(hr->bottom() == prev_end, err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, i, HR_FORMAT_PARAMS(hr), prev_end)); guarantee(hr->hrs_index() == i, err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); - if (i < _length) { + if (i < length()) { // Asserts will fire if i is >= _length HeapWord* addr = hr->bottom(); guarantee(addr_to_region(addr) == hr, "sanity"); @@ -265,8 +254,8 @@ void HeapRegionSeq::verify_optional() { prev_end = hr->end(); } } - for (uint i = _allocated_length; i < _max_length; i += 1) { - guarantee(_regions[i] == NULL, err_msg("invariant i: %u", i)); + for (uint i = _allocated_length; i < max_length(); i += 1) { + guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i)); } } #endif // PRODUCT diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp index b7a58f76a7f..b0c3eb48a0b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp @@ -25,10 +25,17 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP +#include "gc_implementation/g1/g1BiasedArray.hpp" + class HeapRegion; class HeapRegionClosure; class FreeRegionList; +class G1HeapRegionTable : public G1BiasedMappedArray { + protected: + virtual HeapRegion* default_value() const { return NULL; } +}; + // This class keeps track of the region metadata (i.e., HeapRegion // instances). They are kept in the _regions array in address // order. A region's index in the array corresponds to its index in @@ -44,35 +51,21 @@ class FreeRegionList; // // We keep track of three lengths: // -// * _length (returned by length()) is the number of currently +// * _committed_length (returned by length()) is the number of currently // committed regions. // * _allocated_length (not exposed outside this class) is the // number of regions for which we have HeapRegions. -// * _max_length (returned by max_length()) is the maximum number of -// regions the heap can have. +// * max_length() returns the maximum number of regions the heap can have. // -// and maintain that: _length <= _allocated_length <= _max_length +// and maintain that: _committed_length <= _allocated_length <= max_length() class HeapRegionSeq: public CHeapObj { friend class VMStructs; - // The array that holds the HeapRegions. - HeapRegion** _regions; - - // Version of _regions biased to address 0 - HeapRegion** _regions_biased; + G1HeapRegionTable _regions; // The number of regions committed in the heap. - uint _length; - - // The address of the first reserved word in the heap. - HeapWord* _heap_bottom; - - // The address of the last reserved word in the heap - 1. - HeapWord* _heap_end; - - // The log of the region byte size. - uint _region_shift; + uint _committed_length; // A hint for which index to start searching from for humongous // allocations. @@ -81,37 +74,33 @@ class HeapRegionSeq: public CHeapObj { // The number of regions for which we have allocated HeapRegions for. uint _allocated_length; - // The maximum number of regions in the heap. - uint _max_length; - // Find a contiguous set of empty regions of length num, starting // from the given index. uint find_contiguous_from(uint from, uint num); - // Map a heap address to a biased region index. Assume that the - // address is valid. - inline uintx addr_to_index_biased(HeapWord* addr) const; - void increment_allocated_length() { - assert(_allocated_length < _max_length, "pre-condition"); + assert(_allocated_length < max_length(), "pre-condition"); _allocated_length++; } void increment_length() { - assert(_length < _max_length, "pre-condition"); - _length++; + assert(length() < max_length(), "pre-condition"); + _committed_length++; } void decrement_length() { - assert(_length > 0, "pre-condition"); - _length--; + assert(length() > 0, "pre-condition"); + _committed_length--; } + HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); } + HeapWord* heap_end() const {return _regions.end_address_mapped(); } + public: // Empty contructor, we'll initialize it with the initialize() method. - HeapRegionSeq() { } + HeapRegionSeq() : _regions(), _committed_length(0), _next_search_index(0), _allocated_length(0) { } - void initialize(HeapWord* bottom, HeapWord* end, uint max_length); + void initialize(HeapWord* bottom, HeapWord* end); // Return the HeapRegion at the given index. Assume that the index // is valid. @@ -126,10 +115,10 @@ class HeapRegionSeq: public CHeapObj { inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const; // Return the number of regions that have been committed in the heap. - uint length() const { return _length; } + uint length() const { return _committed_length; } // Return the maximum number of regions in the heap. - uint max_length() const { return _max_length; } + uint max_length() const { return (uint)_regions.length(); } // Expand the sequence to reflect that the heap has grown from // old_end to new_end. Either create new HeapRegions, or re-use diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp index e840287edc7..96588dea042 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp @@ -28,28 +28,16 @@ #include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp" -inline uintx HeapRegionSeq::addr_to_index_biased(HeapWord* addr) const { - assert(_heap_bottom <= addr && addr < _heap_end, - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT, - addr, _heap_bottom, _heap_end)); - uintx index = (uintx) addr >> _region_shift; - return index; -} - inline HeapRegion* HeapRegionSeq::addr_to_region_unsafe(HeapWord* addr) const { - assert(_heap_bottom <= addr && addr < _heap_end, - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT, - addr, _heap_bottom, _heap_end)); - uintx index_biased = addr_to_index_biased(addr); - HeapRegion* hr = _regions_biased[index_biased]; + HeapRegion* hr = _regions.get_by_address(addr); assert(hr != NULL, "invariant"); return hr; } inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { - if (addr != NULL && addr < _heap_end) { - assert(addr >= _heap_bottom, - err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, _heap_bottom)); + if (addr != NULL && addr < heap_end()) { + assert(addr >= heap_bottom(), + err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, addr, heap_bottom())); return addr_to_region_unsafe(addr); } return NULL; @@ -57,7 +45,7 @@ inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { inline HeapRegion* HeapRegionSeq::at(uint index) const { assert(index < length(), "pre-condition"); - HeapRegion* hr = _regions[index]; + HeapRegion* hr = _regions.get_by_index(index); assert(hr != NULL, "sanity"); assert(hr->hrs_index() == index, "sanity"); return hr; diff --git a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp index 736c2d75096..9268eb78ef4 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp @@ -34,8 +34,14 @@ static_field(HeapRegion, GrainBytes, size_t) \ static_field(HeapRegion, LogOfHRGrainBytes, int) \ \ - nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \ - nonstatic_field(HeapRegionSeq, _length, uint) \ + nonstatic_field(G1HeapRegionTable, _base, address) \ + nonstatic_field(G1HeapRegionTable, _length, size_t) \ + nonstatic_field(G1HeapRegionTable, _biased_base, address) \ + nonstatic_field(G1HeapRegionTable, _bias, size_t) \ + nonstatic_field(G1HeapRegionTable, _shift_by, uint) \ + \ + nonstatic_field(HeapRegionSeq, _regions, G1HeapRegionTable) \ + nonstatic_field(HeapRegionSeq, _committed_length, uint) \ \ nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \ nonstatic_field(G1CollectedHeap, _g1_committed, MemRegion) \ @@ -58,6 +64,8 @@ #define VM_TYPES_G1(declare_type, declare_toplevel_type) \ \ + declare_toplevel_type(G1HeapRegionTable) \ + \ declare_type(G1CollectedHeap, SharedHeap) \ \ declare_type(HeapRegion, ContiguousSpace) \ diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index c7886920b3e..8b3c19c5c2d 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5047,6 +5047,9 @@ void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); void TestVirtualSpace_test(); void MetaspaceAux_test(); +#if INCLUDE_ALL_GCS +void TestG1BiasedArray_test(); +#endif void execute_internal_vm_tests() { if (ExecuteInternalVMTests) { @@ -5066,6 +5069,7 @@ void execute_internal_vm_tests() { run_unit_test(VMStructs::test()); #endif #if INCLUDE_ALL_GCS + run_unit_test(TestG1BiasedArray_test()); run_unit_test(HeapRegionRemSet::test_prt()); #endif tty->print_cr("All internal VM tests passed"); From d5157be0e8445c4b4acfc787f82144a4ab7cd921 Mon Sep 17 00:00:00 2001 From: David Simms Date: Wed, 25 Sep 2013 13:58:13 +0200 Subject: [PATCH 186/293] 8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL) Execute some code at a high virtual address value, and keep mapped Reviewed-by: coleenp, zgu --- hotspot/src/os/linux/vm/os_linux.cpp | 4 ++ .../src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 43 +++++++++++++++++++ .../src/os_cpu/linux_x86/vm/os_linux_x86.hpp | 13 ++++++ 3 files changed, 60 insertions(+) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 6c794793cfe..95e04681f48 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -4839,6 +4839,10 @@ jint os::init_2(void) Linux::capture_initial_stack(JavaThread::stack_size_at_create()); +#if defined(IA32) + workaround_expand_exec_shield_cs_limit(); +#endif + Linux::libpthread_init(); if (PrintMiscellaneous && (Verbose || WizardMode)) { tty->print_cr("[HotSpot is running with %s, %s(%s)]\n", 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 8878c0ea353..9a7605e696b 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 @@ -876,3 +876,46 @@ void os::verify_stack_alignment() { #endif } #endif + + +/* + * IA32 only: execute code at a high address in case buggy NX emulation is present. I.e. avoid CS limit + * updates (JDK-8023956). + */ +void os::workaround_expand_exec_shield_cs_limit() { +#if defined(IA32) + size_t page_size = os::vm_page_size(); + /* + * Take the highest VA the OS will give us and exec + * + * Although using -(pagesz) as mmap hint works on newer kernel as you would + * think, older variants affected by this work-around don't (search forward only). + * + * On the affected distributions, we understand the memory layout to be: + * + * TASK_LIMIT= 3G, main stack base close to TASK_LIMT. + * + * A few pages south main stack will do it. + * + * If we are embedded in an app other than launcher (initial != main stack), + * we don't have much control or understanding of the address space, just let it slide. + */ + char* hint = (char*) (Linux::initial_thread_stack_bottom() - + ((StackYellowPages + StackRedPages + 1) * page_size)); + char* codebuf = os::reserve_memory(page_size, hint); + if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) { + return; // No matter, we tried, best effort. + } + if (PrintMiscellaneous && (Verbose || WizardMode)) { + tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf); + } + + // Some code to exec: the 'ret' instruction + codebuf[0] = 0xC3; + + // Call the code in the codebuf + __asm__ volatile("call *%0" : : "r"(codebuf)); + + // keep the page mapped so CS limit isn't reduced. +#endif +} diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp index 1d3fd350c68..fbca6909bb5 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.hpp @@ -36,4 +36,17 @@ // Note: Currently only used in 64 bit Windows implementations static bool register_code_area(char *low, char *high) { return true; } + /* + * Work-around for broken NX emulation using CS limit, Red Hat patch "Exec-Shield" + * (IA32 only). + * + * Map and execute at a high VA to prevent CS lazy updates race with SMP MM + * invalidation.Further code generation by the JVM will no longer cause CS limit + * updates. + * + * Affects IA32: RHEL 5 & 6, Ubuntu 10.04 (LTS), 10.10, 11.04, 11.10, 12.04. + * @see JDK-8023956 + */ + static void workaround_expand_exec_shield_cs_limit(); + #endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP From 0414dcb01d17910a5a7946b4eab779bc75790657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 25 Sep 2013 16:37:56 +0200 Subject: [PATCH 187/293] 8025434: RegExp lastIndex can exceed int range Reviewed-by: lagergren, sundar --- .../internal/objects/NativeRegExp.java | 2 +- nashorn/test/script/basic/JDK-8025434.js | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8025434.js diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java index 5a2196356fe..2c4d3324e60 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java @@ -883,7 +883,7 @@ public final class NativeRegExp extends ScriptObject { * @return last index property as int */ public int getLastIndex() { - return JSType.toInt32(lastIndex); + return JSType.toInteger(lastIndex); } /** diff --git a/nashorn/test/script/basic/JDK-8025434.js b/nashorn/test/script/basic/JDK-8025434.js new file mode 100644 index 00000000000..1d42959416d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025434.js @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025434: RegExp lastIndex can exceed int range + * + * @test + * @run + */ + +var r = /a/g; + +r.lastIndex = 0x100000000; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = 0x100000000000000; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = -0x100000000; +if (r.test("a")) { + throw new Error("Expected match"); +} + +r.lastIndex = -0x100000000000000; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = 1; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = -1; +if (r.test("a")) { + throw new Error("Expected no match"); +} + +r.lastIndex = 0; +if (!r.test("a")) { + throw new Error("Expected match"); +} From dc5131c84daeddc57579dc9217c230c30b6b279e Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Wed, 25 Sep 2013 17:23:41 +0200 Subject: [PATCH 188/293] 8025228: assert(new_entry->reserved_words() == vs_word_size) fails in nightly Reviewed-by: mgerdin, tschatzl, jmasa --- hotspot/src/share/vm/memory/metaspace.cpp | 27 +++++++++++++++++------ hotspot/src/share/vm/prims/jni.cpp | 4 ++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 8498242e848..06f3d09378a 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -1095,7 +1095,7 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) { } // Reserve the space size_t vs_byte_size = vs_word_size * BytesPerWord; - assert(vs_byte_size % os::vm_page_size() == 0, "Not aligned"); + assert(vs_byte_size % os::vm_allocation_granularity() == 0, "Not aligned"); // Allocate the meta virtual space and initialize it. VirtualSpaceNode* new_entry = new VirtualSpaceNode(vs_byte_size); @@ -1167,12 +1167,14 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size, // being used for CompressedHeaders, don't allocate a new virtualspace. if (can_grow() && MetaspaceGC::should_expand(this, word_size)) { // Get another virtual space. - size_t grow_vs_words = - MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words); + size_t allocation_aligned_expand_words = + align_size_up(aligned_expand_vs_by_words, os::vm_allocation_granularity() / BytesPerWord); + size_t grow_vs_words = + MAX2((size_t)VirtualSpaceSize, allocation_aligned_expand_words); if (grow_vs(grow_vs_words)) { // Got it. It's on the list now. Get a chunk from it. assert(current_virtual_space()->expanded_words() == 0, - "New virtuals space nodes should not have expanded"); + "New virtual space nodes should not have expanded"); size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words, page_size_words); @@ -3357,7 +3359,7 @@ void Metaspace::dump(outputStream* const out) const { #ifndef PRODUCT -class MetaspaceAuxTest : AllStatic { +class TestMetaspaceAuxTest : AllStatic { public: static void test_reserved() { size_t reserved = MetaspaceAux::reserved_bytes(); @@ -3397,14 +3399,25 @@ class MetaspaceAuxTest : AllStatic { } } + static void test_virtual_space_list_large_chunk() { + VirtualSpaceList* vs_list = new VirtualSpaceList(os::vm_allocation_granularity()); + MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag); + // A size larger than VirtualSpaceSize (256k) and add one page to make it _not_ be + // vm_allocation_granularity aligned on Windows. + size_t large_size = (size_t)(2*256*K + (os::vm_page_size()/BytesPerWord)); + large_size += (os::vm_page_size()/BytesPerWord); + vs_list->get_new_chunk(large_size, large_size, 0); + } + static void test() { test_reserved(); test_committed(); + test_virtual_space_list_large_chunk(); } }; -void MetaspaceAux_test() { - MetaspaceAuxTest::test(); +void TestMetaspaceAux_test() { + TestMetaspaceAuxTest::test(); } #endif diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index 8b3c19c5c2d..cbd7860a092 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -5046,7 +5046,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) { void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); void TestVirtualSpace_test(); -void MetaspaceAux_test(); +void TestMetaspaceAux_test(); #if INCLUDE_ALL_GCS void TestG1BiasedArray_test(); #endif @@ -5057,7 +5057,7 @@ void execute_internal_vm_tests() { run_unit_test(TestReservedSpace_test()); run_unit_test(TestReserveMemorySpecial_test()); run_unit_test(TestVirtualSpace_test()); - run_unit_test(MetaspaceAux_test()); + run_unit_test(TestMetaspaceAux_test()); run_unit_test(GlobalDefinitions::test_globals()); run_unit_test(GCTimerAllTest::all()); run_unit_test(arrayOopDesc::test_max_array_length()); From 81505a6a571d9b05adb477cce69e90a5486d2a34 Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Wed, 25 Sep 2013 17:47:22 +0200 Subject: [PATCH 189/293] 8024677: [TESTBUG] Move tests for classes in /testlibrary Moved the tests to /testlibrary_tests and updated TEST.groups Reviewed-by: dholmes, sla --- hotspot/test/TEST.groups | 1 + hotspot/test/{testlibrary => testlibrary_tests}/AssertsTest.java | 0 .../OutputAnalyzerReportingTest.java | 0 .../{testlibrary => testlibrary_tests}/OutputAnalyzerTest.java | 0 4 files changed, 1 insertion(+) rename hotspot/test/{testlibrary => testlibrary_tests}/AssertsTest.java (100%) rename hotspot/test/{testlibrary => testlibrary_tests}/OutputAnalyzerReportingTest.java (100%) rename hotspot/test/{testlibrary => testlibrary_tests}/OutputAnalyzerTest.java (100%) diff --git a/hotspot/test/TEST.groups b/hotspot/test/TEST.groups index bae5a9b3469..aa597590eef 100644 --- a/hotspot/test/TEST.groups +++ b/hotspot/test/TEST.groups @@ -193,6 +193,7 @@ compact1_minimal = \ serviceability/ \ compiler/ \ testlibrary/ \ + testlibrary_tests/ \ sanity/ \ runtime/ \ gc/ \ diff --git a/hotspot/test/testlibrary/AssertsTest.java b/hotspot/test/testlibrary_tests/AssertsTest.java similarity index 100% rename from hotspot/test/testlibrary/AssertsTest.java rename to hotspot/test/testlibrary_tests/AssertsTest.java diff --git a/hotspot/test/testlibrary/OutputAnalyzerReportingTest.java b/hotspot/test/testlibrary_tests/OutputAnalyzerReportingTest.java similarity index 100% rename from hotspot/test/testlibrary/OutputAnalyzerReportingTest.java rename to hotspot/test/testlibrary_tests/OutputAnalyzerReportingTest.java diff --git a/hotspot/test/testlibrary/OutputAnalyzerTest.java b/hotspot/test/testlibrary_tests/OutputAnalyzerTest.java similarity index 100% rename from hotspot/test/testlibrary/OutputAnalyzerTest.java rename to hotspot/test/testlibrary_tests/OutputAnalyzerTest.java From 18550f77746916eacbd07f7be4adf57d17eb7c5e Mon Sep 17 00:00:00 2001 From: Christian Tornqvist Date: Wed, 25 Sep 2013 17:47:51 +0200 Subject: [PATCH 190/293] 8024492: [TESTBUG] Test library class Platform.java needs to include methods for missing OS's and architectures Added methods for 32bit, arm, ppc, x64 and x86 Reviewed-by: zgu, hseigel, mseledtsov --- .../com/oracle/java/testlibrary/Platform.java | 100 ++++++++++++------ 1 file changed, 65 insertions(+), 35 deletions(-) diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java index 8e5d303317d..a2e5f82ad71 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java @@ -24,50 +24,80 @@ package com.oracle.java.testlibrary; public class Platform { - private static final String osName = System.getProperty("os.name"); - private static final String dataModel = System.getProperty("sun.arch.data.model"); - private static final String vmVersion = System.getProperty("java.vm.version"); - private static final String osArch = System.getProperty("os.arch"); + private static final String osName = System.getProperty("os.name"); + private static final String dataModel = System.getProperty("sun.arch.data.model"); + private static final String vmVersion = System.getProperty("java.vm.version"); + private static final String osArch = System.getProperty("os.arch"); - public static boolean is64bit() { - return dataModel.equals("64"); - } + public static boolean is32bit() { + return dataModel.equals("32"); + } - public static boolean isSolaris() { - return osName.toLowerCase().startsWith("sunos"); - } + public static boolean is64bit() { + return dataModel.equals("64"); + } - public static boolean isWindows() { - return osName.toLowerCase().startsWith("win"); - } + public static boolean isSolaris() { + return isOs("sunos"); + } - public static boolean isOSX() { - return osName.toLowerCase().startsWith("mac"); - } + public static boolean isWindows() { + return isOs("win"); + } - public static boolean isLinux() { - return osName.toLowerCase().startsWith("linux"); - } + public static boolean isOSX() { + return isOs("mac"); + } - public static String getOsName() { - return osName; - } + public static boolean isLinux() { + return isOs("linux"); + } - public static boolean isDebugBuild() { - return vmVersion.toLowerCase().contains("debug"); - } + private static boolean isOs(String osname) { + return osName.toLowerCase().startsWith(osname.toLowerCase()); + } - public static String getVMVersion() { - return vmVersion; - } + public static String getOsName() { + return osName; + } - // Returns true for sparc and sparcv9. - public static boolean isSparc() { - return osArch.toLowerCase().startsWith("sparc"); - } + public static boolean isDebugBuild() { + return vmVersion.toLowerCase().contains("debug"); + } - public static String getOsArch() { - return osArch; - } + public static String getVMVersion() { + return vmVersion; + } + + // Returns true for sparc and sparcv9. + public static boolean isSparc() { + return isArch("sparc"); + } + + public static boolean isARM() { + return isArch("arm"); + } + + public static boolean isPPC() { + return isArch("ppc"); + } + + public static boolean isX86() { + // On Linux it's 'i386', Windows 'x86' + return (isArch("i386") || isArch("x86")); + } + + public static boolean isX64() { + // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64' + return (isArch("amd64") || isArch("x86_64")); + } + + private static boolean isArch(String archname) { + return osArch.toLowerCase().startsWith(archname.toLowerCase()); + } + + public static String getOsArch() { + return osArch; + } } From 9692733c7a1e91d9007079b6bdf82585051b57b7 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 25 Sep 2013 11:07:05 -0700 Subject: [PATCH 191/293] 8025407: TypeAnnotations does not use Context Reviewed-by: jfranck --- .../sun/tools/javac/code/TypeAnnotations.java | 75 +++++++++++-------- .../com/sun/tools/javac/comp/Attr.java | 6 +- .../com/sun/tools/javac/comp/MemberEnter.java | 4 +- 3 files changed, 49 insertions(+), 36 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java index 56acb0e8eb2..677319f1db6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java @@ -31,10 +31,7 @@ import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; -import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Attribute.TypeCompound; -import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Type.AnnotatedType; import com.sun.tools.javac.code.Type.ArrayType; import com.sun.tools.javac.code.Type.CapturedType; @@ -49,7 +46,6 @@ import com.sun.tools.javac.code.Type.Visitor; import com.sun.tools.javac.code.Type.WildcardType; import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry; import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind; -import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.comp.Annotate; @@ -70,6 +66,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.Assert; +import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; @@ -83,8 +80,28 @@ import com.sun.tools.javac.util.Names; * and determine the TypeAnnotationPositions for all type annotations. */ public class TypeAnnotations { - // Class cannot be instantiated. - private TypeAnnotations() {} + protected static final Context.Key typeAnnosKey = + new Context.Key(); + + public static TypeAnnotations instance(Context context) { + TypeAnnotations instance = context.get(typeAnnosKey); + if (instance == null) + instance = new TypeAnnotations(context); + return instance; + } + + final Log log; + final Names names; + final Symtab syms; + final Annotate annotate; + + protected TypeAnnotations(Context context) { + context.put(typeAnnosKey, this); + names = Names.instance(context); + log = Log.instance(context); + syms = Symtab.instance(context); + annotate = Annotate.instance(context); + } /** * Separate type annotations from declaration annotations and @@ -95,15 +112,14 @@ public class TypeAnnotations { * adds an Annotator to the correct Annotate queue for * later processing. */ - public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names, - final Log log, final Env env, final JCClassDecl tree, final Annotate annotate) { + public void organizeTypeAnnotationsSignatures(final Env env, final JCClassDecl tree) { annotate.afterRepeated( new Annotator() { @Override public void enterAnnotation() { JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); try { - new TypeAnnotationPositions(syms, names, log, true).scan(tree); + new TypeAnnotationPositions(true).scan(tree); } finally { log.useSource(oldSource); } @@ -115,8 +131,8 @@ public class TypeAnnotations { * This version only visits types in bodies, that is, field initializers, * top-level blocks, and method bodies, and should be called from Attr. */ - public static void organizeTypeAnnotationsBodies(Symtab syms, Names names, Log log, JCClassDecl tree) { - new TypeAnnotationPositions(syms, names, log, false).scan(tree); + public void organizeTypeAnnotationsBodies(JCClassDecl tree) { + new TypeAnnotationPositions(false).scan(tree); } public enum AnnotationType { DECLARATION, TYPE, BOTH }; @@ -125,8 +141,7 @@ public class TypeAnnotations { * Determine whether an annotation is a declaration annotation, * a type annotation, or both. */ - public static AnnotationType annotationType(Symtab syms, Names names, - Attribute.Compound a, Symbol s) { + public AnnotationType annotationType(Attribute.Compound a, Symbol s) { Attribute.Compound atTarget = a.type.tsym.attribute(syms.annotationTargetType.tsym); if (atTarget == null) { @@ -215,17 +230,11 @@ public class TypeAnnotations { } - private static class TypeAnnotationPositions extends TreeScanner { + private class TypeAnnotationPositions extends TreeScanner { - private final Symtab syms; - private final Names names; - private final Log log; private final boolean sigOnly; - private TypeAnnotationPositions(Symtab syms, Names names, Log log, boolean sigOnly) { - this.syms = syms; - this.names = names; - this.log = log; + TypeAnnotationPositions(boolean sigOnly) { this.sigOnly = sigOnly; } @@ -265,7 +274,7 @@ public class TypeAnnotations { ListBuffer typeAnnos = new ListBuffer(); for (Attribute.Compound a : annotations) { - switch (annotationType(syms, names, a, sym)) { + switch (annotationType(a, sym)) { case DECLARATION: declAnnos.append(a); break; @@ -301,7 +310,7 @@ public class TypeAnnotations { } // type is non-null and annotations are added to that type - type = typeWithAnnotations(typetree, type, typeAnnotations, log); + type = typeWithAnnotations(typetree, type, typeAnnotations); if (sym.getKind() == ElementKind.METHOD) { sym.type.asMethodType().restype = type; @@ -352,8 +361,8 @@ public class TypeAnnotations { // // As a side effect the method sets the type annotation position of "annotations". // Note that it is assumed that all annotations share the same position. - private static Type typeWithAnnotations(final JCTree typetree, final Type type, - final List annotations, Log log) { + private Type typeWithAnnotations(final JCTree typetree, final Type type, + final List annotations) { // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n", // typetree, type, annotations); if (annotations.isEmpty()) { @@ -400,7 +409,7 @@ public class TypeAnnotations { arTree = arrayTypeTree(arTree.elemtype); depth = depth.append(TypePathEntry.ARRAY); } - Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log); + Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations); tomodify.elemtype = arelemType; { // All annotations share the same position; modify the first one. @@ -417,7 +426,7 @@ public class TypeAnnotations { // There is a TypeKind, but no TypeTag. JCTypeUnion tutree = (JCTypeUnion) typetree; JCExpression fst = tutree.alternatives.get(0); - Type res = typeWithAnnotations(fst, fst.type, annotations, log); + Type res = typeWithAnnotations(fst, fst.type, annotations); fst.type = res; // TODO: do we want to set res as first element in uct.alternatives? // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type; @@ -505,7 +514,7 @@ public class TypeAnnotations { } } - private static JCArrayTypeTree arrayTypeTree(JCTree typetree) { + private JCArrayTypeTree arrayTypeTree(JCTree typetree) { if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) { return (JCArrayTypeTree) typetree; } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) { @@ -532,7 +541,7 @@ public class TypeAnnotations { * @param annotations The annotations to insert. * @return A copy of type that contains the annotations. */ - private static Type typeWithAnnotations(final Type type, + private Type typeWithAnnotations(final Type type, final Type stopAt, final List annotations) { Visitor> visitor = @@ -619,7 +628,7 @@ public class TypeAnnotations { return type.accept(visitor, annotations); } - private static Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) { + private Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) { // It is safe to alias the position. return new Attribute.TypeCompound(a, p); } @@ -953,7 +962,7 @@ public class TypeAnnotations { } } - private static void locateNestedTypes(Type type, TypeAnnotationPosition p) { + private void locateNestedTypes(Type type, TypeAnnotationPosition p) { // The number of "steps" to get from the full type to the // left-most outer type. ListBuffer depth = new ListBuffer<>(); @@ -970,7 +979,7 @@ public class TypeAnnotations { } } - private static int methodParamIndex(List path, JCTree param) { + private int methodParamIndex(List path, JCTree param) { List curr = path; while (curr.head.getTag() != Tag.METHODDEF && curr.head.getTag() != Tag.LAMBDA) { @@ -1284,7 +1293,7 @@ public class TypeAnnotations { } } - private static void setTypeAnnotationPos(List annotations, + private void setTypeAnnotationPos(List annotations, TypeAnnotationPosition position) { for (JCAnnotation anno : annotations) { // attribute might be null during DeferredAttr; 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 0b4db2c059f..f9673deaa6a 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 @@ -93,6 +93,7 @@ public class Attr extends JCTree.Visitor { final Types types; final JCDiagnostic.Factory diags; final Annotate annotate; + final TypeAnnotations typeAnnotations; final DeferredLintHandler deferredLintHandler; public static Attr instance(Context context) { @@ -121,6 +122,7 @@ public class Attr extends JCTree.Visitor { types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); annotate = Annotate.instance(context); + typeAnnotations = TypeAnnotations.instance(context); deferredLintHandler = DeferredLintHandler.instance(context); Options options = Options.instance(context); @@ -2228,7 +2230,7 @@ public class Attr extends JCTree.Visitor { // empty annotations, if only declaration annotations were given. // This method will raise an error for such a type. for (JCAnnotation ai : annotations) { - if (TypeAnnotations.annotationType(syms, names, ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { + if (typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { log.error(ai.pos(), "annotation.type.not.applicable"); } } @@ -4339,7 +4341,7 @@ public class Attr extends JCTree.Visitor { } if (allowTypeAnnos) { // Correctly organize the postions of the type annotations - TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree); + typeAnnotations.organizeTypeAnnotationsBodies(tree); // Check type annotations applicability rules validateTypeAnnotations(tree); 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 634e875d5aa..fbb8c326889 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 @@ -79,6 +79,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { private final ClassReader reader; private final Todo todo; private final Annotate annotate; + private final TypeAnnotations typeAnnotations; private final Types types; private final JCDiagnostic.Factory diags; private final Source source; @@ -105,6 +106,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { reader = ClassReader.instance(context); todo = Todo.instance(context); annotate = Annotate.instance(context); + typeAnnotations = TypeAnnotations.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); source = Source.instance(context); @@ -1164,7 +1166,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } } if (allowTypeAnnos) { - TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, env, tree, annotate); + typeAnnotations.organizeTypeAnnotationsSignatures(env, tree); } } From 06564ac469c180f4cbc7fa6755fbafa1925b9149 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 25 Sep 2013 12:21:35 -0700 Subject: [PATCH 192/293] 8025411: JPRT to switch to the new Win platforms for JDK8 builds this week Reviewed-by: ksrini, katleman --- make/jprt.properties | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/make/jprt.properties b/make/jprt.properties index b7bad856278..3860e9228ba 100644 --- a/make/jprt.properties +++ b/make/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -43,8 +43,8 @@ jprt.build.targets= \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ macosx_x64_10.7-{product|fastdebug}, \ - windows_i586_5.1-{product|fastdebug}, \ - windows_x64_5.2-{product|fastdebug} + windows_i586_6.1-{product|fastdebug}, \ + windows_x64_6.1-{product|fastdebug} # User can select the test set with jprt submit "-testset name" option jprt.my.test.set=${jprt.test.set} @@ -58,8 +58,8 @@ jprt.my.test.target.set= \ linux_i586_2.6-product-{c1|c2}-TESTNAME, \ linux_x64_2.6-product-c2-TESTNAME, \ macosx_x64_10.7-product-c2-TESTNAME, \ - windows_i586_5.1-product-c1-TESTNAME, \ - windows_x64_5.2-product-c2-TESTNAME + windows_i586_6.1-product-c1-TESTNAME, \ + windows_x64_6.1-product-c2-TESTNAME # Default vm test targets (testset=default) jprt.vm.default.test.targets= \ From c5556a0948eaa352580b7d7c3c7f0b4b78b2006e Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 25 Sep 2013 12:22:44 -0700 Subject: [PATCH 193/293] 8025411: JPRT to switch to the new Win platforms for JDK8 builds this week Reviewed-by: ksrini, katleman --- corba/make/jprt.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/corba/make/jprt.properties b/corba/make/jprt.properties index 360b6b22dba..b03c53ca656 100644 --- a/corba/make/jprt.properties +++ b/corba/make/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -39,8 +39,8 @@ jprt.build.targets= \ solaris_x64_5.10-{product|fastdebug}, \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ - windows_i586_5.1-{product|fastdebug}, \ - windows_x64_5.2-{product|fastdebug} + windows_i586_6.1-{product|fastdebug}, \ + windows_x64_6.1-{product|fastdebug} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev From f07a2ff3cbdd6cc645de66b0064a00df9e21b0ec Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 25 Sep 2013 12:23:10 -0700 Subject: [PATCH 194/293] 8025411: JPRT to switch to the new Win platforms for JDK8 builds this week Reviewed-by: ksrini, katleman --- hotspot/make/jprt.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties index 5971546c6d9..f322e7024ae 100644 --- a/hotspot/make/jprt.properties +++ b/hotspot/make/jprt.properties @@ -120,13 +120,13 @@ jprt.my.macosx.x64.jdk7=macosx_x64_10.7 jprt.my.macosx.x64.jdk7u8=${jprt.my.macosx.x64.jdk7} jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}} -jprt.my.windows.i586.jdk8=windows_i586_5.1 -jprt.my.windows.i586.jdk7=windows_i586_5.1 +jprt.my.windows.i586.jdk8=windows_i586_6.1 +jprt.my.windows.i586.jdk7=windows_i586_6.1 jprt.my.windows.i586.jdk7u8=${jprt.my.windows.i586.jdk7} jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}} -jprt.my.windows.x64.jdk8=windows_x64_5.2 -jprt.my.windows.x64.jdk7=windows_x64_5.2 +jprt.my.windows.x64.jdk8=windows_x64_6.1 +jprt.my.windows.x64.jdk7=windows_x64_6.1 jprt.my.windows.x64.jdk7u8=${jprt.my.windows.x64.jdk7} jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}} From 502d1331efe784977f49edcad906dc8c2d31b00d Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 25 Sep 2013 12:23:30 -0700 Subject: [PATCH 195/293] 8025411: JPRT to switch to the new Win platforms for JDK8 builds this week Reviewed-by: ksrini, katleman --- jaxp/make/jprt.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jaxp/make/jprt.properties b/jaxp/make/jprt.properties index 360b6b22dba..b03c53ca656 100644 --- a/jaxp/make/jprt.properties +++ b/jaxp/make/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -39,8 +39,8 @@ jprt.build.targets= \ solaris_x64_5.10-{product|fastdebug}, \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ - windows_i586_5.1-{product|fastdebug}, \ - windows_x64_5.2-{product|fastdebug} + windows_i586_6.1-{product|fastdebug}, \ + windows_x64_6.1-{product|fastdebug} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev From 18726314c255e908dd4924a088b2a5f2e94bb082 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 25 Sep 2013 12:23:40 -0700 Subject: [PATCH 196/293] 8025411: JPRT to switch to the new Win platforms for JDK8 builds this week Reviewed-by: ksrini, katleman --- jaxws/make/jprt.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jaxws/make/jprt.properties b/jaxws/make/jprt.properties index 91064331043..12ce773022a 100644 --- a/jaxws/make/jprt.properties +++ b/jaxws/make/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,8 @@ jprt.build.targets= \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ macosx_x64_10.7-{product|fastdebug}, \ - windows_i586_5.1-{product|fastdebug}, \ - windows_x64_5.2-{product|fastdebug} + windows_i586_6.1-{product|fastdebug}, \ + windows_x64_6.1-{product|fastdebug} # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev From a13f76ec8c306bf8a526a12e493e5b3b7bc2a6e2 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 25 Sep 2013 12:24:05 -0700 Subject: [PATCH 197/293] 8025411: JPRT to switch to the new Win platforms for JDK8 builds this week Reviewed-by: ksrini, katleman --- jdk/make/jprt.properties | 10 ++-- jdk/makefiles/jprt.properties | 106 +++++++++++++++++----------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties index 8f7038e1f3b..eb6ff3ff2f0 100644 --- a/jdk/make/jprt.properties +++ b/jdk/make/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,8 @@ jprt.build.targets= \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ macosx_x64_10.7-{product|fastdebug}, \ - windows_i586_5.1-{product|fastdebug}, \ - windows_x64_5.2-{product|fastdebug} + windows_i586_6.1-{product|fastdebug}, \ + windows_x64_6.1-{product|fastdebug} # User can select the test set with jprt submit "-testset name" option jprt.my.test.set=${jprt.test.set} @@ -55,8 +55,8 @@ jprt.my.test.target.set= \ linux_i586_2.6-product-{c1|c2}-TESTNAME, \ linux_x64_2.6-product-c2-TESTNAME, \ macosx_x64_10.7-product-c2-TESTNAME, \ - windows_i586_5.1-product-c1-TESTNAME, \ - windows_x64_5.2-product-c2-TESTNAME + windows_i586_6.1-product-c1-TESTNAME, \ + windows_x64_6.1-product-c2-TESTNAME # Default vm test targets (testset=default) jprt.vm.default.test.targets= \ diff --git a/jdk/makefiles/jprt.properties b/jdk/makefiles/jprt.properties index a4a077226e8..1051bb34bb7 100644 --- a/jdk/makefiles/jprt.properties +++ b/jdk/makefiles/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -39,8 +39,8 @@ jprt.build.targets= \ solaris_x64_5.10-{product|fastdebug}, \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ - windows_i586_5.1-{product|fastdebug}, \ - windows_x64_5.2-{product|fastdebug} + windows_i586_6.1-{product|fastdebug}, \ + windows_x64_6.1-{product|fastdebug} # User can select the test set with jprt submit "-testset name" option jprt.my.test.set=${jprt.test.set} @@ -53,8 +53,8 @@ jprt.vm.default.test.targets= \ solaris_x64_5.10-product-c2-jvm98, \ linux_i586_2.6-product-{c1|c2}-jvm98, \ linux_x64_2.6-product-c2-jvm98, \ - windows_i586_5.1-product-c1-jvm98, \ - windows_x64_5.2-product-c2-jvm98 + windows_i586_6.1-product-c1-jvm98, \ + windows_x64_6.1-product-c2-jvm98 # Select vm testlist to use (allow for testset to be empty too) jprt.vm.all.test.targets=${jprt.vm.default.test.targets} @@ -70,8 +70,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_beans1, \ linux_i586_2.6-product-{c1|c2}-jdk_beans1, \ linux_x64_2.6-product-c2-jdk_beans1, \ - windows_i586_5.1-product-c1-jdk_beans1, \ - windows_x64_5.2-product-c2-jdk_beans1, \ + windows_i586_6.1-product-c1-jdk_beans1, \ + windows_x64_6.1-product-c2-jdk_beans1, \ \ solaris_sparc_5.10-product-c1-jdk_io, \ solaris_sparcv9_5.10-product-c2-jdk_io, \ @@ -79,8 +79,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_io, \ linux_i586_2.6-product-{c1|c2}-jdk_io, \ linux_x64_2.6-product-c2-jdk_io, \ - windows_i586_5.1-product-c1-jdk_io, \ - windows_x64_5.2-product-c2-jdk_io, \ + windows_i586_6.1-product-c1-jdk_io, \ + windows_x64_6.1-product-c2-jdk_io, \ \ solaris_sparc_5.10-product-c1-jdk_lang, \ solaris_sparcv9_5.10-product-c2-jdk_lang, \ @@ -88,8 +88,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_lang, \ linux_i586_2.6-product-{c1|c2}-jdk_lang, \ linux_x64_2.6-product-c2-jdk_lang, \ - windows_i586_5.1-product-c1-jdk_lang, \ - windows_x64_5.2-product-c2-jdk_lang, \ + windows_i586_6.1-product-c1-jdk_lang, \ + windows_x64_6.1-product-c2-jdk_lang, \ \ solaris_sparc_5.10-product-c1-jdk_math, \ solaris_sparcv9_5.10-product-c2-jdk_math, \ @@ -97,8 +97,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_math, \ linux_i586_2.6-product-{c1|c2}-jdk_math, \ linux_x64_2.6-product-c2-jdk_math, \ - windows_i586_5.1-product-c1-jdk_math, \ - windows_x64_5.2-product-c2-jdk_math, \ + windows_i586_6.1-product-c1-jdk_math, \ + windows_x64_6.1-product-c2-jdk_math, \ \ solaris_sparc_5.10-product-c1-jdk_misc, \ solaris_sparcv9_5.10-product-c2-jdk_misc, \ @@ -106,8 +106,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_misc, \ linux_i586_2.6-product-{c1|c2}-jdk_misc, \ linux_x64_2.6-product-c2-jdk_misc, \ - windows_i586_5.1-product-c1-jdk_misc, \ - windows_x64_5.2-product-c2-jdk_misc, \ + windows_i586_6.1-product-c1-jdk_misc, \ + windows_x64_6.1-product-c2-jdk_misc, \ \ solaris_sparc_5.10-product-c1-jdk_net, \ solaris_sparcv9_5.10-product-c2-jdk_net, \ @@ -115,8 +115,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_net, \ linux_i586_2.6-product-{c1|c2}-jdk_net, \ linux_x64_2.6-product-c2-jdk_net, \ - windows_i586_5.1-product-c1-jdk_net, \ - windows_x64_5.2-product-c2-jdk_net, \ + windows_i586_6.1-product-c1-jdk_net, \ + windows_x64_6.1-product-c2-jdk_net, \ \ solaris_sparc_5.10-product-c1-jdk_nio1, \ solaris_sparcv9_5.10-product-c2-jdk_nio1, \ @@ -124,8 +124,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_nio1, \ linux_i586_2.6-product-{c1|c2}-jdk_nio1, \ linux_x64_2.6-product-c2-jdk_nio1, \ - windows_i586_5.1-product-c1-jdk_nio1, \ - windows_x64_5.2-product-c2-jdk_nio1, \ + windows_i586_6.1-product-c1-jdk_nio1, \ + windows_x64_6.1-product-c2-jdk_nio1, \ \ solaris_sparc_5.10-product-c1-jdk_nio2, \ solaris_sparcv9_5.10-product-c2-jdk_nio2, \ @@ -133,8 +133,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_nio2, \ linux_i586_2.6-product-{c1|c2}-jdk_nio2, \ linux_x64_2.6-product-c2-jdk_nio2, \ - windows_i586_5.1-product-c1-jdk_nio2, \ - windows_x64_5.2-product-c2-jdk_nio2, \ + windows_i586_6.1-product-c1-jdk_nio2, \ + windows_x64_6.1-product-c2-jdk_nio2, \ \ solaris_sparc_5.10-product-c1-jdk_nio3, \ solaris_sparcv9_5.10-product-c2-jdk_nio3, \ @@ -142,8 +142,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_nio3, \ linux_i586_2.6-product-{c1|c2}-jdk_nio3, \ linux_x64_2.6-product-c2-jdk_nio3, \ - windows_i586_5.1-product-c1-jdk_nio3, \ - windows_x64_5.2-product-c2-jdk_nio3, \ + windows_i586_6.1-product-c1-jdk_nio3, \ + windows_x64_6.1-product-c2-jdk_nio3, \ \ solaris_sparc_5.10-product-c1-jdk_security1, \ solaris_sparcv9_5.10-product-c2-jdk_security1, \ @@ -151,8 +151,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_security1, \ linux_i586_2.6-product-{c1|c2}-jdk_security1, \ linux_x64_2.6-product-c2-jdk_security1, \ - windows_i586_5.1-product-c1-jdk_security1, \ - windows_x64_5.2-product-c2-jdk_security1, \ + windows_i586_6.1-product-c1-jdk_security1, \ + windows_x64_6.1-product-c2-jdk_security1, \ \ solaris_sparc_5.10-product-c1-jdk_text, \ solaris_sparcv9_5.10-product-c2-jdk_text, \ @@ -160,8 +160,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_text, \ linux_i586_2.6-product-{c1|c2}-jdk_text, \ linux_x64_2.6-product-c2-jdk_text, \ - windows_i586_5.1-product-c1-jdk_text, \ - windows_x64_5.2-product-c2-jdk_text, \ + windows_i586_6.1-product-c1-jdk_text, \ + windows_x64_6.1-product-c2-jdk_text, \ \ solaris_sparc_5.10-product-c1-jdk_tools1, \ solaris_sparcv9_5.10-product-c2-jdk_tools1, \ @@ -169,8 +169,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_tools1, \ linux_i586_2.6-product-{c1|c2}-jdk_tools1, \ linux_x64_2.6-product-c2-jdk_tools1, \ - windows_i586_5.1-product-c1-jdk_tools1, \ - windows_x64_5.2-product-c2-jdk_tools1, \ + windows_i586_6.1-product-c1-jdk_tools1, \ + windows_x64_6.1-product-c2-jdk_tools1, \ \ solaris_sparc_5.10-product-c1-jdk_util, \ solaris_sparcv9_5.10-product-c2-jdk_util, \ @@ -178,8 +178,8 @@ jprt.make.rule.default.test.targets= \ solaris_x64_5.10-product-c2-jdk_util, \ linux_i586_2.6-product-{c1|c2}-jdk_util, \ linux_x64_2.6-product-c2-jdk_util, \ - windows_i586_5.1-product-c1-jdk_util, \ - windows_x64_5.2-product-c2-jdk_util + windows_i586_6.1-product-c1-jdk_util, \ + windows_x64_6.1-product-c2-jdk_util # All jdk test targets in test/Makefile (still no fastdebug & limited c2) jprt.make.rule.all.test.targets= \ @@ -192,8 +192,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_awt, \ linux_i586_2.6-product-{c1|c2}-jdk_awt, \ linux_x64_2.6-product-c2-jdk_awt, \ - windows_i586_5.1-product-c1-jdk_awt, \ - windows_x64_5.2-product-c2-jdk_awt, \ + windows_i586_6.1-product-c1-jdk_awt, \ + windows_x64_6.1-product-c2-jdk_awt, \ \ solaris_sparc_5.10-product-c1-jdk_beans2, \ solaris_sparcv9_5.10-product-c2-jdk_beans2, \ @@ -201,8 +201,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_beans2, \ linux_i586_2.6-product-{c1|c2}-jdk_beans2, \ linux_x64_2.6-product-c2-jdk_beans2, \ - windows_i586_5.1-product-c1-jdk_beans2, \ - windows_x64_5.2-product-c2-jdk_beans2, \ + windows_i586_6.1-product-c1-jdk_beans2, \ + windows_x64_6.1-product-c2-jdk_beans2, \ \ solaris_sparc_5.10-product-c1-jdk_beans3, \ solaris_sparcv9_5.10-product-c2-jdk_beans3, \ @@ -210,8 +210,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_beans3, \ linux_i586_2.6-product-{c1|c2}-jdk_beans3, \ linux_x64_2.6-product-c2-jdk_beans3, \ - windows_i586_5.1-product-c1-jdk_beans3, \ - windows_x64_5.2-product-c2-jdk_beans3, \ + windows_i586_6.1-product-c1-jdk_beans3, \ + windows_x64_6.1-product-c2-jdk_beans3, \ \ solaris_sparc_5.10-product-c1-jdk_management1, \ solaris_sparcv9_5.10-product-c2-jdk_management1, \ @@ -219,8 +219,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_management1, \ linux_i586_2.6-product-{c1|c2}-jdk_management1, \ linux_x64_2.6-product-c2-jdk_management1, \ - windows_i586_5.1-product-c1-jdk_management1, \ - windows_x64_5.2-product-c2-jdk_management1, \ + windows_i586_6.1-product-c1-jdk_management1, \ + windows_x64_6.1-product-c2-jdk_management1, \ \ solaris_sparc_5.10-product-c1-jdk_management2, \ solaris_sparcv9_5.10-product-c2-jdk_management2, \ @@ -228,8 +228,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_management2, \ linux_i586_2.6-product-{c1|c2}-jdk_management2, \ linux_x64_2.6-product-c2-jdk_management2, \ - windows_i586_5.1-product-c1-jdk_management2, \ - windows_x64_5.2-product-c2-jdk_management2, \ + windows_i586_6.1-product-c1-jdk_management2, \ + windows_x64_6.1-product-c2-jdk_management2, \ \ solaris_sparc_5.10-product-c1-jdk_rmi, \ solaris_sparcv9_5.10-product-c2-jdk_rmi, \ @@ -237,8 +237,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_rmi, \ linux_i586_2.6-product-{c1|c2}-jdk_rmi, \ linux_x64_2.6-product-c2-jdk_rmi, \ - windows_i586_5.1-product-c1-jdk_rmi, \ - windows_x64_5.2-product-c2-jdk_rmi, \ + windows_i586_6.1-product-c1-jdk_rmi, \ + windows_x64_6.1-product-c2-jdk_rmi, \ \ solaris_sparc_5.10-product-c1-jdk_security2, \ solaris_sparcv9_5.10-product-c2-jdk_security2, \ @@ -246,8 +246,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_security2, \ linux_i586_2.6-product-{c1|c2}-jdk_security2, \ linux_x64_2.6-product-c2-jdk_security2, \ - windows_i586_5.1-product-c1-jdk_security2, \ - windows_x64_5.2-product-c2-jdk_security2, \ + windows_i586_6.1-product-c1-jdk_security2, \ + windows_x64_6.1-product-c2-jdk_security2, \ \ solaris_sparc_5.10-product-c1-jdk_security3, \ solaris_sparcv9_5.10-product-c2-jdk_security3, \ @@ -255,8 +255,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_security3, \ linux_i586_2.6-product-{c1|c2}-jdk_security3, \ linux_x64_2.6-product-c2-jdk_security3, \ - windows_i586_5.1-product-c1-jdk_security3, \ - windows_x64_5.2-product-c2-jdk_security3, \ + windows_i586_6.1-product-c1-jdk_security3, \ + windows_x64_6.1-product-c2-jdk_security3, \ \ solaris_sparc_5.10-product-c1-jdk_sound, \ solaris_sparcv9_5.10-product-c2-jdk_sound, \ @@ -264,8 +264,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_sound, \ linux_i586_2.6-product-{c1|c2}-jdk_sound, \ linux_x64_2.6-product-c2-jdk_sound, \ - windows_i586_5.1-product-c1-jdk_sound, \ - windows_x64_5.2-product-c2-jdk_sound, \ + windows_i586_6.1-product-c1-jdk_sound, \ + windows_x64_6.1-product-c2-jdk_sound, \ \ solaris_sparc_5.10-product-c1-jdk_swing, \ solaris_sparcv9_5.10-product-c2-jdk_swing, \ @@ -273,8 +273,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_swing, \ linux_i586_2.6-product-{c1|c2}-jdk_swing, \ linux_x64_2.6-product-c2-jdk_swing, \ - windows_i586_5.1-product-c1-jdk_swing, \ - windows_x64_5.2-product-c2-jdk_swing, \ + windows_i586_6.1-product-c1-jdk_swing, \ + windows_x64_6.1-product-c2-jdk_swing, \ \ solaris_sparc_5.10-product-c1-jdk_tools2, \ solaris_sparcv9_5.10-product-c2-jdk_tools2, \ @@ -282,8 +282,8 @@ jprt.make.rule.all.test.targets= \ solaris_x64_5.10-product-c2-jdk_tools2, \ linux_i586_2.6-product-{c1|c2}-jdk_tools2, \ linux_x64_2.6-product-c2-jdk_tools2, \ - windows_i586_5.1-product-c1-jdk_tools2, \ - windows_x64_5.2-product-c2-jdk_tools2 + windows_i586_6.1-product-c1-jdk_tools2, \ + windows_x64_6.1-product-c2-jdk_tools2 # JCK test targets in test/Makefile (no fastdebug & limited c2, windows broken) jprt.my.jck.test.target.set= \ From 2578c3a839ed5a2e408ceeb54e697ab955e80c4c Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Wed, 25 Sep 2013 12:24:13 -0700 Subject: [PATCH 198/293] 8025411: JPRT to switch to the new Win platforms for JDK8 builds this week Reviewed-by: ksrini, katleman --- langtools/make/jprt.properties | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/langtools/make/jprt.properties b/langtools/make/jprt.properties index c0399ed7083..734fa8cd89d 100644 --- a/langtools/make/jprt.properties +++ b/langtools/make/jprt.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,8 @@ jprt.build.targets= \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ macosx_x64_10.7-{product|fastdebug}, \ - windows_i586_5.1-{product|fastdebug}, \ - windows_x64_5.2-{product|fastdebug} + windows_i586_6.1-{product|fastdebug}, \ + windows_x64_6.1-{product|fastdebug} # Test target list (no fastdebug & limited c2 testing) jprt.my.test.target.set= \ @@ -52,8 +52,8 @@ jprt.my.test.target.set= \ linux_i586_2.6-product-{c1|c2}-TESTNAME, \ linux_x64_2.6-product-c2-TESTNAME, \ macosx_x64_10.7-product-c2-TESTNAME, \ - windows_i586_5.1-product-c1-TESTNAME, \ - windows_x64_5.2-product-c2-TESTNAME + windows_i586_6.1-product-c1-TESTNAME, \ + windows_x64_6.1-product-c2-TESTNAME # Default test targets jprt.make.rule.test.targets= \ @@ -71,8 +71,8 @@ jprt.my.test.target.set= \ linux_i586_2.6-product-{c1|c2}-TESTNAME, \ linux_x64_2.6-product-c2-TESTNAME, \ macosx_x64_10.7-product-c2-TESTNAME, \ - windows_i586_5.1-product-c1-TESTNAME, \ - windows_x64_5.2-product-c2-TESTNAME + windows_i586_6.1-product-c1-TESTNAME, \ + windows_x64_6.1-product-c2-TESTNAME # Default test targets jprt.make.rule.test.targets= \ From fd9a09c390e6affc89212522c02f91ba922b8cc1 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 25 Sep 2013 14:04:24 -0700 Subject: [PATCH 199/293] 8025412: Add legal header and comments to test/tools/doclint/tidy/util/Main.java Reviewed-by: bpatel --- .../test/tools/doclint/tidy/util/Main.java | 53 +++++++++++++++++++ .../test/tools/doclint/tidy/util/tidy.sh | 5 +- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/langtools/test/tools/doclint/tidy/util/Main.java b/langtools/test/tools/doclint/tidy/util/Main.java index 62a559b1a74..77b356f1d2e 100644 --- a/langtools/test/tools/doclint/tidy/util/Main.java +++ b/langtools/test/tools/doclint/tidy/util/Main.java @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + package tidystats; import java.io.IOException; @@ -17,6 +41,35 @@ import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * Generate statistics from the files generated by tidy.sh. + * + *

    The tidy.sh script is used to run tidy on all the HTML files + * in a directory, creating files in a new directory, and for each + * HTML file, it writes the console output from tidy into a file + * beside the fixed up file, with an additional .tidy extension. + * + *

    This program will scan a directory for *.tidy files and + * analyze the messages reported by tidy, in order to generate a + * report with statistics on the various messages that were + * reported by tidy. + * + *

    Typical usage: + *

    + * $ bash /path/to/tidy.sh /path/to/htmldir
    + * $ javac -d /path/to/classes /path/to/Main.java
    + * $ java -cp /path/to/classes tidystats.Main /path/to/htmldir.tidy
    + * 
    + * + *

    Internally, the program works by matching lines in the *.tidy + * files against a series of regular expressions that are used to + * categorize the messages. The set of regular expressions was + * empirically determined by running the program on the output from + * running tidy.sh on all the generated JDK documentation. It is + * possible that tidy may generate more/different messages on other + * doc sets, in which case, the set of regexes in the program should + * be updated. + */ public class Main { public static void main(String... args) throws IOException { new Main().run(args); diff --git a/langtools/test/tools/doclint/tidy/util/tidy.sh b/langtools/test/tools/doclint/tidy/util/tidy.sh index 711d320b3b9..eeea6606f53 100644 --- a/langtools/test/tools/doclint/tidy/util/tidy.sh +++ b/langtools/test/tools/doclint/tidy/util/tidy.sh @@ -1,6 +1,6 @@ -#!/bin/sh +#!/bin/bash # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ # # Run the "tidy" program over the files in a directory. +# The "tidy" program must be on your PATH. # # Usage: # sh tidy.sh

    From a949e946abc70e7fc3db17dce97abdd0ff620bf0 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Wed, 25 Sep 2013 22:26:42 -0700 Subject: [PATCH 200/293] 8004825: javadoc crash DocletAbortException Reviewed-by: jjg --- .../toolkit/resources/doclets.properties | 1 + .../internal/toolkit/taglets/ValueTaglet.java | 27 +++++--- .../javadoc/testValueTag/TestValueTag.java | 66 +++++++++++++++++-- .../sun/javadoc/testValueTag/pkg1/Class1.java | 27 +++++++- 4 files changed, 105 insertions(+), 16 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties index 54dff68e55b..cf21120f517 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties @@ -136,6 +136,7 @@ doclet.Deprecated=Deprecated. doclet.Groupname_already_used=In -group option, groupname already used: {0} doclet.value_tag_invalid_reference={0} (referenced by @value tag) is an unknown reference. doclet.value_tag_invalid_constant=@value tag (which references {0}) can only be used in constants. +doclet.value_tag_invalid_use=@value tag cannot be used here. doclet.dest_dir_create=Creating destination directory: "{0}" doclet.in={0} in {1} doclet.Use_Table_Summary=Use table, listing {0}, and an explanation diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java index 4d7dd74da2c..b1d6f39b8b3 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java @@ -105,7 +105,9 @@ public class ValueTaglet extends BaseInlineTaglet { } /** - * Given the name of the field, return the corresponding FieldDoc. + * Given the name of the field, return the corresponding FieldDoc. Return null + * due to invalid use of value tag if the name is null or empty string and if + * the value tag is not used on a field. * * @param config the current configuration of the doclet. * @param tag the value tag. @@ -114,10 +116,8 @@ public class ValueTaglet extends BaseInlineTaglet { * it is assumed that the field is in the current class. * * @return the corresponding FieldDoc. If the name is null or empty string, - * return field that the value tag was used in. - * - * @throws DocletAbortException if the value tag does not specify a name to - * a value field and it is not used within the comments of a valid field. + * return field that the value tag was used in. Return null if the name is null + * or empty string and if the value tag is not used on a field. */ private FieldDoc getFieldDoc(Configuration config, Tag tag, String name) { if (name == null || name.length() == 0) { @@ -125,8 +125,9 @@ public class ValueTaglet extends BaseInlineTaglet { if (tag.holder() instanceof FieldDoc) { return (FieldDoc) tag.holder(); } else { - //This should never ever happen. - throw new DocletAbortException("should not happen"); + // If the value tag does not specify a parameter which is a valid field and + // it is not used within the comments of a valid field, return null. + return null; } } StringTokenizer st = new StringTokenizer(name, "#"); @@ -165,9 +166,15 @@ public class ValueTaglet extends BaseInlineTaglet { FieldDoc field = getFieldDoc( writer.configuration(), tag, tag.text()); if (field == null) { - //Reference is unknown. - writer.getMsgRetriever().warning(tag.holder().position(), - "doclet.value_tag_invalid_reference", tag.text()); + if (tag.text().isEmpty()) { + //Invalid use of @value + writer.getMsgRetriever().warning(tag.holder().position(), + "doclet.value_tag_invalid_use"); + } else { + //Reference is unknown. + writer.getMsgRetriever().warning(tag.holder().position(), + "doclet.value_tag_invalid_reference", tag.text()); + } } else if (field.constantValue() != null) { return writer.valueTagOutput(field, field.constantValueExpression(), diff --git a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java index ba0f291dc81..1d24a52798a 100644 --- a/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java +++ b/langtools/test/com/sun/javadoc/testValueTag/TestValueTag.java @@ -23,13 +23,12 @@ /* * @test - * @bug 4764045 + * @bug 4764045 8004825 * @summary This test ensures that the value tag works in all * use cases. The explainations for each test case are written below. * @author jamieh * @library ../lib/ - * @build JavadocTester - * @build TestValueTag + * @build JavadocTester TestValueTag * @run main TestValueTag */ @@ -41,11 +40,17 @@ public class TestValueTag extends JavadocTester { //Javadoc arguments. private static final String[] ARGS = new String[] { - "-Xdoclint:none", "-d", BUG_ID, "-sourcepath", SRC_DIR, "-tag", "todo", "pkg1", "pkg2" }; + private static final String[] ARGS1 = + new String[] { + "-Xdoclint:none", + "-d", BUG_ID + "-1", "-sourcepath", SRC_DIR, "-tag", + "todo", "pkg1", "pkg2" + }; + //Input for string search tests. private static final String[][] TEST = { //Base case: using @value on a constant. @@ -91,16 +96,58 @@ public class TestValueTag extends JavadocTester { {BUG_ID + FS + "pkg1" + FS + "CustomTagUsage.html", "
    Todo:
    " + NL + "
    the value of this constant is 55.
    "}, + //Test @value errors printed dues to invalid use or when used with + //non-constant or with bad references. + {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + + " * Result: {@value TEST_12_ERROR}" + }, + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + " * Result: {@value}" + }, + {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + + " * Result: {@value NULL}" + }, + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + " * Invalid (null): {@value}" + }, + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + " * Invalid (non-constant field): {@value}" + }, + {ERROR_OUTPUT,"error: value does not refer to a constant" + NL + + " * Here is a bad value reference: {@value UnknownClass#unknownConstant}" + }, + {ERROR_OUTPUT,"error: reference not found" + NL + + " * Here is a bad value reference: {@value UnknownClass#unknownConstant}" + }, + {ERROR_OUTPUT,"error: {@value} not allowed here" + NL + + " * @todo the value of this constant is {@value}" + } + }; + private static final String[][] TEST1 = { //Test @value warning printed when used with non-constant. {WARNING_OUTPUT,"warning - @value tag (which references nonConstant) " + "can only be used in constants." }, + {WARNING_OUTPUT,"warning - @value tag (which references NULL) " + + "can only be used in constants." + }, + {WARNING_OUTPUT,"warning - @value tag (which references TEST_12_ERROR) " + + "can only be used in constants." + }, //Test warning printed for bad reference. {WARNING_OUTPUT,"warning - UnknownClass#unknownConstant (referenced by " + "@value tag) is an unknown reference." }, + //Test warning printed for invalid use of @value. + {WARNING_OUTPUT,"warning - @value tag cannot be used here." + } + }; + private static final String[][] NEGATED_TEST = { + //Base case: using @value on a constant. + {BUG_ID + FS + "pkg1" + FS + "Class1.html", + "Result: \"Test 12 " + + "generates an error message\""}, }; - private static final String[][] NEGATED_TEST = NO_TEST; /** * The entry point of the test. @@ -109,9 +156,18 @@ public class TestValueTag extends JavadocTester { public static void main(String[] args) { TestValueTag tester = new TestValueTag(); run(tester, ARGS, TEST, NEGATED_TEST); + checkForException(tester); + run(tester, ARGS1, TEST1, NO_TEST); + checkForException(tester); tester.printSummary(); } + public static void checkForException(TestValueTag tester) { + if (tester.getErrorOutput().contains("DocletAbortException")) { + throw new AssertionError("javadoc threw DocletAbortException"); + } + } + /** * {@inheritDoc} */ diff --git a/langtools/test/com/sun/javadoc/testValueTag/pkg1/Class1.java b/langtools/test/com/sun/javadoc/testValueTag/pkg1/Class1.java index 7cd1c69c70f..3b03881c7f9 100644 --- a/langtools/test/com/sun/javadoc/testValueTag/pkg1/Class1.java +++ b/langtools/test/com/sun/javadoc/testValueTag/pkg1/Class1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,16 @@ public class Class1 { public static final String TEST_10_PASSES = "Test 10 passes"; public static final String TEST_11_PASSES = "Test 11 passes"; + /** + * Invalid (non-constant field): {@value} + */ + public static String TEST_12_ERROR = "Test 12 generates an error message"; + + /** + * Invalid (null): {@value} + */ + public static final String NULL = null; + /** * Result: {@value TEST_3_PASSES} */ @@ -59,6 +69,21 @@ public class Class1 { */ public void method() {} + /** + * Result: {@value TEST_12_ERROR} + */ + public void invalidValueTag1() {} + + /** + * Result: {@value} + */ + public void invalidValueTag2() {} + + /** + * Result: {@value NULL} + */ + public void testNullConstant() {} + /** * Result: {@value pkg1.Class1#TEST_6_PASSES} */ From abc7352b43e5fbd043c49933af0e93eb6a584b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 26 Sep 2013 10:14:24 +0200 Subject: [PATCH 201/293] 8025197: String replace method fails with regexp /$/gi Reviewed-by: sundar --- .../internal/objects/NativeRegExp.java | 7 +++- nashorn/test/script/basic/JDK-8025197.js | 37 +++++++++++++++++++ .../test/script/basic/JDK-8025197.js.EXPECTED | 7 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8025197.js create mode 100644 nashorn/test/script/basic/JDK-8025197.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java index 2c4d3324e60..be4a93d0fdc 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java @@ -697,8 +697,13 @@ public final class NativeRegExp extends ScriptObject { appendReplacement(matcher, string, replacement, sb); } - // ECMA 15.5.4.10 String.prototype.match(regexp) thisIndex = matcher.end(); + if (thisIndex == string.length() && matcher.start() == matcher.end()) { + // Avoid getting empty match at end of string twice + break; + } + + // ECMA 15.5.4.10 String.prototype.match(regexp) if (thisIndex == previousLastIndex) { setLastIndex(thisIndex + 1); previousLastIndex = thisIndex + 1; diff --git a/nashorn/test/script/basic/JDK-8025197.js b/nashorn/test/script/basic/JDK-8025197.js new file mode 100644 index 00000000000..5099b673691 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025197.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025197: String replace method fails with regexp /$/gi + * + * @test + * @run + */ + +print('dog'.replace(/$/gi, 's')); +print('dog'.replace(/(?:g)$/gi, 's')); +print('dog'.replace(/(?:a)$/gi, 's')); +print('dog'.replace(/(?!g)$/gi, 's')); +print('dog'.replace(/(?!a)$/gi, 's')); +print('dog'.replace(/g?$/gi, 's')); +print('dog'.replace(/.?$/gi, 's')); diff --git a/nashorn/test/script/basic/JDK-8025197.js.EXPECTED b/nashorn/test/script/basic/JDK-8025197.js.EXPECTED new file mode 100644 index 00000000000..9f2a08f67e5 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025197.js.EXPECTED @@ -0,0 +1,7 @@ +dogs +dos +dog +dogs +dogs +doss +doss From 2e8063226ddac217a1c62fb99b68ede844c9281f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 26 Sep 2013 11:47:24 +0200 Subject: [PATCH 202/293] 8025486: RegExp constructor arguments are not evaluated in right order Reviewed-by: sundar --- .../internal/objects/NativeRegExp.java | 16 +++--- nashorn/test/script/basic/JDK-8025486.js | 55 +++++++++++++++++++ .../test/script/basic/JDK-8025486.js.EXPECTED | 3 + 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8025486.js create mode 100644 nashorn/test/script/basic/JDK-8025486.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java index be4a93d0fdc..318ca2a0edd 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java @@ -191,23 +191,21 @@ public final class NativeRegExp extends ScriptObject { public static NativeRegExp newRegExp(final Object regexp, final Object flags) { String patternString = ""; String flagString = ""; - boolean flagsDefined = false; - - if (flags != UNDEFINED) { - flagsDefined = true; - flagString = JSType.toString(flags); - } if (regexp != UNDEFINED) { if (regexp instanceof NativeRegExp) { - if (!flagsDefined) { - return (NativeRegExp)regexp; // 15.10.3.1 - undefined flags and regexp as + if (flags != UNDEFINED) { + throw typeError("regex.cant.supply.flags"); } - throw typeError("regex.cant.supply.flags"); + return (NativeRegExp)regexp; // 15.10.3.1 - undefined flags and regexp as } patternString = JSType.toString(regexp); } + if (flags != UNDEFINED) { + flagString = JSType.toString(flags); + } + return new NativeRegExp(patternString, flagString); } diff --git a/nashorn/test/script/basic/JDK-8025486.js b/nashorn/test/script/basic/JDK-8025486.js new file mode 100644 index 00000000000..8012f72383c --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025486.js @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8025486: RegExp constructor arguments are not evaluated in right order + * + * @test + * @run + */ + +new RegExp({ + toString: function() { + print("source"); + return "a"; + } +}, { + toString: function() { + print("flags"); + return "g"; + } +}); + +try { + new RegExp(/asdf/, { + toString: function() { + fail("toString should not be called"); + } + }); + fail("expected TypeError"); +} catch (e) { + if (!(e instanceof TypeError)) { + fail("expected TypeError"); + } + print(e); +} diff --git a/nashorn/test/script/basic/JDK-8025486.js.EXPECTED b/nashorn/test/script/basic/JDK-8025486.js.EXPECTED new file mode 100644 index 00000000000..cf46bd7a29d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8025486.js.EXPECTED @@ -0,0 +1,3 @@ +source +flags +TypeError: Cannot supply flags when constructing one RegExp from another From 7bf953d005ff5151bee14473c8f1869429dd2d3a Mon Sep 17 00:00:00 2001 From: Lois Foltan Date: Thu, 26 Sep 2013 10:25:02 -0400 Subject: [PATCH 203/293] 7195622: CheckUnhandledOops has limited usefulness now Enable CHECK_UNHANDLED_OOPS in fastdebug builds across all supported platforms. Reviewed-by: coleenp, hseigel, dholmes, stefank, twisti, ihse, rdurbin --- hotspot/make/bsd/makefiles/fastdebug.make | 4 +- hotspot/make/linux/makefiles/fastdebug.make | 2 +- hotspot/make/windows/makefiles/fastdebug.make | 4 +- hotspot/src/cpu/sparc/vm/frame_sparc.cpp | 4 +- hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp | 6 +- hotspot/src/cpu/x86/vm/frame_x86.cpp | 2 +- hotspot/src/cpu/x86/vm/methodHandles_x86.cpp | 4 +- hotspot/src/cpu/x86/vm/x86_32.ad | 2 +- hotspot/src/cpu/x86/vm/x86_64.ad | 4 +- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 4 +- .../share/vm/classfile/classLoaderData.cpp | 8 +-- hotspot/src/share/vm/classfile/dictionary.hpp | 4 +- .../src/share/vm/classfile/symbolTable.cpp | 2 +- hotspot/src/share/vm/code/nmethod.cpp | 6 +- hotspot/src/share/vm/compiler/oopMap.cpp | 4 +- .../concurrentMarkSweepGeneration.cpp | 6 +- .../gc_implementation/g1/concurrentMark.cpp | 2 +- .../gc_implementation/g1/g1CollectedHeap.cpp | 6 +- .../gc_implementation/g1/g1CollectedHeap.hpp | 2 +- .../vm/gc_implementation/g1/g1OopClosures.hpp | 8 +-- .../g1/g1SATBCardTableModRefBS.cpp | 4 +- .../vm/gc_implementation/g1/heapRegion.cpp | 8 +-- .../gc_implementation/g1/heapRegionRemSet.cpp | 8 +-- .../parNew/parNewGeneration.cpp | 12 ++-- .../parNew/parOopClosures.inline.hpp | 6 +- .../parallelScavenge/psPromotionManager.cpp | 2 +- .../parallelScavenge/psPromotionManager.hpp | 2 +- .../psPromotionManager.inline.hpp | 2 +- .../parallelScavenge/psScavenge.inline.hpp | 4 +- .../share/vm/interpreter/bytecodeTracer.cpp | 2 +- .../src/share/vm/interpreter/linkResolver.cpp | 2 +- .../src/share/vm/memory/heapInspection.hpp | 4 +- .../share/vm/memory/referenceProcessor.cpp | 24 ++++---- hotspot/src/share/vm/oops/constantPool.cpp | 2 +- hotspot/src/share/vm/oops/cpCache.cpp | 4 +- hotspot/src/share/vm/oops/instanceKlass.cpp | 6 +- .../src/share/vm/oops/instanceMirrorKlass.hpp | 4 +- .../src/share/vm/oops/instanceRefKlass.cpp | 14 ++--- hotspot/src/share/vm/oops/methodData.hpp | 4 +- hotspot/src/share/vm/oops/oop.inline.hpp | 2 +- hotspot/src/share/vm/oops/oopsHierarchy.hpp | 59 +++++++++++++++---- hotspot/src/share/vm/opto/machnode.cpp | 4 +- hotspot/src/share/vm/prims/jvmtiTagMap.cpp | 2 +- hotspot/src/share/vm/prims/unsafe.cpp | 8 +-- .../src/share/vm/runtime/biasedLocking.cpp | 14 ++--- .../src/share/vm/runtime/deoptimization.cpp | 8 +-- hotspot/src/share/vm/runtime/frame.cpp | 8 +-- hotspot/src/share/vm/runtime/javaCalls.cpp | 4 +- hotspot/src/share/vm/runtime/safepoint.cpp | 6 +- .../src/share/vm/runtime/sharedRuntime.cpp | 6 +- hotspot/src/share/vm/runtime/synchronizer.cpp | 14 ++--- hotspot/src/share/vm/runtime/thread.cpp | 2 +- hotspot/src/share/vm/runtime/thread.hpp | 2 +- hotspot/src/share/vm/runtime/vframeArray.cpp | 6 +- .../share/vm/services/classLoadingService.cpp | 4 +- hotspot/src/share/vm/services/heapDumper.cpp | 2 +- .../src/share/vm/services/memoryManager.cpp | 4 +- hotspot/src/share/vm/services/memoryPool.cpp | 4 +- .../share/vm/utilities/globalDefinitions.hpp | 4 +- .../vm/utilities/globalDefinitions_visCPP.hpp | 4 ++ hotspot/src/share/vm/utilities/hashtable.cpp | 6 +- hotspot/src/share/vm/utilities/taskqueue.hpp | 10 ++-- 62 files changed, 208 insertions(+), 173 deletions(-) diff --git a/hotspot/make/bsd/makefiles/fastdebug.make b/hotspot/make/bsd/makefiles/fastdebug.make index f2f5dcfb8f2..d1019f07d3f 100644 --- a/hotspot/make/bsd/makefiles/fastdebug.make +++ b/hotspot/make/bsd/makefiles/fastdebug.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -59,5 +59,5 @@ CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE) MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug VERSION = fastdebug -SYSDEFS += -DASSERT +SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS PICFLAGS = DEFAULT diff --git a/hotspot/make/linux/makefiles/fastdebug.make b/hotspot/make/linux/makefiles/fastdebug.make index abefd2b4ca0..c71e147fe4e 100644 --- a/hotspot/make/linux/makefiles/fastdebug.make +++ b/hotspot/make/linux/makefiles/fastdebug.make @@ -59,5 +59,5 @@ CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE) MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug VERSION = optimized -SYSDEFS += -DASSERT +SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS PICFLAGS = DEFAULT diff --git a/hotspot/make/windows/makefiles/fastdebug.make b/hotspot/make/windows/makefiles/fastdebug.make index a85e129cf6e..7ca41313031 100644 --- a/hotspot/make/windows/makefiles/fastdebug.make +++ b/hotspot/make/windows/makefiles/fastdebug.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ default:: $(BUILD_PCH_FILE) $(AOUT) checkAndBuildSA !include ../local.make !include compile.make -CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION) +CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION) /D "CHECK_UNHANDLED_OOPS" !include $(WorkSpace)/make/windows/makefiles/vm.make !include local.make diff --git a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp index ac9746679b3..6ce05bdfce1 100644 --- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp @@ -764,7 +764,7 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) #ifdef CC_INTERP *oop_result = istate->_oop_temp; #else - oop obj = (oop) at(interpreter_frame_oop_temp_offset); + oop obj = cast_to_oop(at(interpreter_frame_oop_temp_offset)); assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); *oop_result = obj; #endif // CC_INTERP @@ -788,7 +788,7 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) switch(type) { case T_OBJECT: case T_ARRAY: { - oop obj = (oop)*tos_addr; + oop obj = cast_to_oop(*tos_addr); assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check"); *oop_result = obj; break; diff --git a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp index 81f29d2671b..f5ac37cf6fa 100644 --- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -358,7 +358,7 @@ void NativeMovConstReg::set_data(intptr_t x) { oop_Relocation *r = iter.oop_reloc(); if (oop_addr == NULL) { oop_addr = r->oop_addr(); - *oop_addr = (oop)x; + *oop_addr = cast_to_oop(x); } else { assert(oop_addr == r->oop_addr(), "must be only one set-oop here"); } @@ -478,7 +478,7 @@ void NativeMovConstRegPatching::set_data(int x) { oop_Relocation *r = iter.oop_reloc(); if (oop_addr == NULL) { oop_addr = r->oop_addr(); - *oop_addr = (oop)x; + *oop_addr = cast_to_oop(x); } else { assert(oop_addr == r->oop_addr(), "must be only one set-oop here"); } diff --git a/hotspot/src/cpu/x86/vm/frame_x86.cpp b/hotspot/src/cpu/x86/vm/frame_x86.cpp index c2a7c8b49e3..f0de7a44e76 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.cpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp @@ -639,7 +639,7 @@ BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) #ifdef CC_INTERP obj = istate->_oop_temp; #else - obj = (oop) at(interpreter_frame_oop_temp_offset); + obj = cast_to_oop(at(interpreter_frame_oop_temp_offset)); #endif // CC_INTERP } else { oop* obj_p = (oop*)tos_addr; diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp index 30c9199436d..382fd225705 100644 --- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -475,7 +475,7 @@ void trace_method_handle_stub(const char* adaptername, const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx"; tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT, adaptername, mh_reg_name, - mh, entry_sp); + (void *)mh, entry_sp); if (Verbose) { tty->print_cr("Registers:"); diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index 316ebe2911d..da8ac9c5a39 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -351,7 +351,7 @@ void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec, int format) { #ifdef ASSERT if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) { - assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code"); + assert(cast_to_oop(d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d32)->is_scavengable()), "cannot embed scavengable oops in code"); } #endif cbuf.relocate(cbuf.insts_mark(), rspec, format); diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index ed13b3da1d1..b280ecf8159 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -529,7 +529,7 @@ void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, in if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); - assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); + assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); } #endif cbuf.relocate(cbuf.insts_mark(), rspec, format); @@ -556,7 +556,7 @@ void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec if (rspec.reloc()->type() == relocInfo::oop_type && d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); - assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), + assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), "cannot embed scavengable oops in code"); } #endif diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 080eaf67088..7667984e0a8 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -1019,7 +1019,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i n_copy->set_data((intx) (load_klass())); } else { assert(mirror() != NULL, "klass not set"); - n_copy->set_data((intx) (mirror())); + n_copy->set_data(cast_from_oop(mirror())); } if (TracePatching) { @@ -1031,7 +1031,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i assert(n_copy->data() == 0 || n_copy->data() == (intptr_t)Universe::non_oop_word(), "illegal init value"); - n_copy->set_data((intx) (appendix())); + n_copy->set_data(cast_from_oop(appendix())); if (TracePatching) { Disassembler::decode(copy_buff, copy_buff + *byte_count, tty); diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp index 1d39afd7f88..84c191e33bd 100644 --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp @@ -261,7 +261,7 @@ void ClassLoaderData::add_class(Klass* k) { k, k->external_name(), k->class_loader_data(), - k->class_loader(), + (void *)k->class_loader(), loader_name()); } } @@ -297,7 +297,7 @@ void ClassLoaderData::unload() { if (TraceClassLoaderData) { ResourceMark rm; tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this); - tty->print(" for instance "PTR_FORMAT" of %s", class_loader(), + tty->print(" for instance "PTR_FORMAT" of %s", (void *)class_loader(), loader_name()); if (is_anonymous()) { tty->print(" for anonymous class "PTR_FORMAT " ", _klasses); @@ -458,7 +458,7 @@ const char* ClassLoaderData::loader_name() { void ClassLoaderData::dump(outputStream * const out) { ResourceMark rm; out->print("ClassLoaderData CLD: "PTR_FORMAT", loader: "PTR_FORMAT", loader_klass: "PTR_FORMAT" %s {", - this, class_loader(), + this, (void *)class_loader(), class_loader() != NULL ? class_loader()->klass() : NULL, loader_name()); if (claimed()) out->print(" claimed "); if (is_unloading()) out->print(" unloading "); @@ -553,7 +553,7 @@ ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRA ResourceMark rm; tty->print("[ClassLoaderData: "); tty->print("create class loader data "PTR_FORMAT, cld); - tty->print(" for instance "PTR_FORMAT" of %s", cld->class_loader(), + tty->print(" for instance "PTR_FORMAT" of %s", (void *)cld->class_loader(), cld->loader_name()); tty->print_cr("]"); } diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp index 53629a015fd..1945803b1b4 100644 --- a/hotspot/src/share/vm/classfile/dictionary.hpp +++ b/hotspot/src/share/vm/classfile/dictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -264,7 +264,7 @@ class SymbolPropertyEntry : public HashtableEntry { } if (method_type() != NULL) { if (printed) st->print(" and "); - st->print(INTPTR_FORMAT, method_type()); + st->print(INTPTR_FORMAT, (void *)method_type()); printed = true; } st->print_cr(printed ? "" : "(empty)"); diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp index 747ca870c2b..e7d63b2a465 100644 --- a/hotspot/src/share/vm/classfile/symbolTable.cpp +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp @@ -840,7 +840,7 @@ StringTable::VerifyRetTypes StringTable::compare_entries( if (str1 == str2) { tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") " "in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]", - str1, bkt1, e_cnt1, bkt2, e_cnt2); + (void *)str1, bkt1, e_cnt1, bkt2, e_cnt2); return _verify_fail_continue; } diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index 4f8608f08a0..08596b186da 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -1965,7 +1965,7 @@ public: if (!_detected_scavenge_root) _print_nm->print_on(tty, "new scavenge root"); tty->print_cr(""PTR_FORMAT"[offset=%d] detected scavengable oop "PTR_FORMAT" (found at "PTR_FORMAT")", _print_nm, (int)((intptr_t)p - (intptr_t)_print_nm), - (intptr_t)(*p), (intptr_t)p); + (void *)(*p), (intptr_t)p); (*p)->print(); } #endif //PRODUCT @@ -2345,7 +2345,7 @@ public: _ok = false; } tty->print_cr("*** non-oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)", - (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm)); + (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm)); } virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } }; @@ -2466,7 +2466,7 @@ public: _ok = false; } tty->print_cr("*** scavengable oop "PTR_FORMAT" found at "PTR_FORMAT" (offset %d)", - (intptr_t)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm)); + (void *)(*p), (intptr_t)p, (int)((intptr_t)p - (intptr_t)_nm)); (*p)->print(); } virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp index 8e6834c710d..6179099601e 100644 --- a/hotspot/src/share/vm/compiler/oopMap.cpp +++ b/hotspot/src/share/vm/compiler/oopMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -628,7 +628,7 @@ void DerivedPointerTable::clear() { // Returns value of location as an int -intptr_t value_of_loc(oop *pointer) { return (intptr_t)(*pointer); } +intptr_t value_of_loc(oop *pointer) { return cast_from_oop((*pointer)); } void DerivedPointerTable::add(oop *derived_loc, oop *base_loc) { diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 2fc6edd34df..bf4ac21e346 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -9065,7 +9065,7 @@ bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) { return !stack->isEmpty(); } -#define BUSY (oop(0x1aff1aff)) +#define BUSY (cast_to_oop(0x1aff1aff)) // (MT-safe) Get a prefix of at most "num" from the list. // The overflow list is chained through the mark word of // each object in the list. We fetch the entire list, @@ -9098,7 +9098,7 @@ bool CMSCollector::par_take_from_overflow_list(size_t num, return false; } // Grab the entire list; we'll put back a suffix - oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); + oop prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list)); Thread* tid = Thread::current(); // Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was // set to ParallelGCThreads. @@ -9113,7 +9113,7 @@ bool CMSCollector::par_take_from_overflow_list(size_t num, return false; } else if (_overflow_list != BUSY) { // Try and grab the prefix - prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); + prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list)); } } // If the list was found to be empty, or we spun long diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 77f08f0d3a3..282dd722228 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -2694,7 +2694,7 @@ public: if (print_it) { _out->print_cr(" "PTR_FORMAT"%s", - o, (over_tams) ? " >" : (marked) ? " M" : ""); + (void *)o, (over_tams) ? " >" : (marked) ? " M" : ""); PrintReachableOopClosure oopCl(_out, _vo, _all); o->oop_iterate_no_header(&oopCl); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 1d8ff8a26dc..9b45fc24a6c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -4615,7 +4615,7 @@ bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); oop p = oopDesc::load_decode_heap_oop(ref); assert(_g1h->is_in_g1_reserved(p), - err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p)); return true; } @@ -4625,11 +4625,11 @@ bool G1ParScanThreadState::verify_ref(oop* ref) const { // Must be in the collection set--it's already been copied. oop p = clear_partial_array_mask(ref); assert(_g1h->obj_in_cs(p), - err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p)); } else { oop p = oopDesc::load_decode_heap_oop(ref); assert(_g1h->is_in_g1_reserved(p), - err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, (void *)p)); } return true; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 747b2326236..5482766e3d8 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -703,7 +703,7 @@ public: if (_g1_committed.contains((HeapWord*) obj)) { // no need to subtract the bottom of the heap from obj, // _in_cset_fast_test is biased - uintx index = (uintx) obj >> HeapRegion::LogOfHRGrainBytes; + uintx index = cast_from_oop(obj) >> HeapRegion::LogOfHRGrainBytes; bool ret = _in_cset_fast_test[index]; // let's make sure the result is consistent with what the slower // test returns diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp index 86dce1cb8e1..b616cb9eb4c 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,12 +91,12 @@ template inline bool has_partial_array_mask(T* ref) { } template inline T* set_partial_array_mask(T obj) { - assert(((uintptr_t)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!"); - return (T*) ((uintptr_t)obj | G1_PARTIAL_ARRAY_MASK); + assert(((uintptr_t)(void *)obj & G1_PARTIAL_ARRAY_MASK) == 0, "Information loss!"); + return (T*) ((uintptr_t)(void *)obj | G1_PARTIAL_ARRAY_MASK); } template inline oop clear_partial_array_mask(T* ref) { - return oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK); + return cast_to_oop((intptr_t)ref & ~G1_PARTIAL_ARRAY_MASK); } class G1ParScanPartialArrayClosure : public G1ParClosureSuper { diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp index 218be0c0e40..b83aa3b1c03 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,7 @@ void G1SATBCardTableLoggingModRefBS::write_ref_field_static(void* field, oop new_val) { uintptr_t field_uint = (uintptr_t)field; - uintptr_t new_val_uint = (uintptr_t)new_val; + uintptr_t new_val_uint = cast_from_oop(new_val); uintptr_t comb = field_uint ^ new_val_uint; comb = comb >> HeapRegion::LogOfHRGrainBytes; if (comb == 0) return; diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp index 726acbfcdc0..00eec548995 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -637,7 +637,7 @@ class VerifyStrongCodeRootOopClosure: public OopClosure { gclog_or_tty->print_cr("Object "PTR_FORMAT" in region " "["PTR_FORMAT", "PTR_FORMAT") is above " "top "PTR_FORMAT, - obj, _hr->bottom(), _hr->end(), _hr->top()); + (void *)obj, _hr->bottom(), _hr->end(), _hr->top()); _failures = true; return; } @@ -951,12 +951,12 @@ void HeapRegion::verify(VerifyOption vo, Klass* klass = obj->klass(); if (!klass->is_metaspace_object()) { gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " - "not metadata", klass, obj); + "not metadata", klass, (void *)obj); *failures = true; return; } else if (!klass->is_klass()) { gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " - "not a klass", klass, obj); + "not a klass", klass, (void *)obj); *failures = true; return; } else { @@ -971,7 +971,7 @@ void HeapRegion::verify(VerifyOption vo, } } } else { - gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj); + gclog_or_tty->print_cr(PTR_FORMAT" no an oop", (void *)obj); *failures = true; return; } diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp index 69eaa53c31a..68bdd760c2b 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @@ -91,8 +91,8 @@ protected: gclog_or_tty->print_cr(" PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT").", from, UseCompressedOops - ? oopDesc::load_decode_heap_oop((narrowOop*)from) - : oopDesc::load_decode_heap_oop((oop*)from)); + ? (void *)oopDesc::load_decode_heap_oop((narrowOop*)from) + : (void *)oopDesc::load_decode_heap_oop((oop*)from)); } HeapRegion* loc_hr = hr(); @@ -403,8 +403,8 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").", from, UseCompressedOops - ? oopDesc::load_decode_heap_oop((narrowOop*)from) - : oopDesc::load_decode_heap_oop((oop*)from)); + ? (void *)oopDesc::load_decode_heap_oop((narrowOop*)from) + : (void *)oopDesc::load_decode_heap_oop((oop*)from)); } int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift); diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index a1eb3130bc6..1d4ef410c34 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -1103,7 +1103,7 @@ void ParNewGeneration::waste_some_time() { } } -static const oop ClaimedForwardPtr = oop(0x4); +static const oop ClaimedForwardPtr = cast_to_oop(0x4); // Because of concurrency, there are times where an object for which // "is_forwarded()" is true contains an "interim" forwarding pointer @@ -1226,7 +1226,7 @@ oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo( if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", is_in_reserved(new_obj) ? "copying" : "tenuring", - new_obj->klass()->internal_name(), old, new_obj, new_obj->size()); + new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size()); } #endif @@ -1347,7 +1347,7 @@ oop ParNewGeneration::copy_to_survivor_space_with_undo( if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", is_in_reserved(new_obj) ? "copying" : "tenuring", - new_obj->klass()->internal_name(), old, new_obj, new_obj->size()); + new_obj->klass()->internal_name(), (void *)old, (void *)new_obj, new_obj->size()); } #endif @@ -1436,7 +1436,7 @@ bool ParNewGeneration::should_simulate_overflow() { // (although some performance comparisons would be useful since // single global lists have their own performance disadvantages // as we were made painfully aware not long ago, see 6786503). -#define BUSY (oop(0x1aff1aff)) +#define BUSY (cast_to_oop(0x1aff1aff)) void ParNewGeneration::push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state) { assert(is_in_reserved(from_space_obj), "Should be from this generation"); if (ParGCUseLocalOverflow) { @@ -1512,7 +1512,7 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan if (_overflow_list == NULL) return false; // Otherwise, there was something there; try claiming the list. - oop prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); + oop prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list)); // Trim off a prefix of at most objsFromOverflow items Thread* tid = Thread::current(); size_t spin_count = (size_t)ParallelGCThreads; @@ -1526,7 +1526,7 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan return false; } else if (_overflow_list != BUSY) { // try and grab the prefix - prefix = (oop)Atomic::xchg_ptr(BUSY, &_overflow_list); + prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list)); } } if (prefix == NULL || prefix == BUSY) { diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp index 38f61fbefd2..383a579bec9 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,7 @@ inline void ParScanClosure::do_oop_work(T* p, Space* sp = gch->space_containing(p); oop obj = oop(sp->block_start(p)); assert((HeapWord*)obj < (HeapWord*)p, "Error"); - tty->print_cr("Object: " PTR_FORMAT, obj); + tty->print_cr("Object: " PTR_FORMAT, (void *)obj); tty->print_cr("-------"); obj->print(); tty->print_cr("-----"); @@ -110,7 +110,7 @@ inline void ParScanClosure::do_oop_work(T* p, if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", "forwarded ", - new_obj->klass()->internal_name(), p, obj, new_obj, new_obj->size()); + new_obj->klass()->internal_name(), p, (void *)obj, (void *)new_obj, new_obj->size()); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp index dd3933b0009..e8a88cb3518 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp @@ -333,7 +333,7 @@ oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) { gclog_or_tty->print_cr("{%s %s 0x%x (%d)}", "promotion-failure", obj->klass()->internal_name(), - obj, obj->size()); + (void *)obj, obj->size()); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp index 6707ade2d17..69292400f33 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp @@ -126,7 +126,7 @@ class PSPromotionManager VALUE_OBJ_CLASS_SPEC { oop* mask_chunked_array_oop(oop obj) { assert(!is_oop_masked((oop*) obj), "invariant"); - oop* ret = (oop*) ((uintptr_t)obj | PS_CHUNKED_ARRAY_OOP_MASK); + oop* ret = (oop*) (cast_from_oop(obj) | PS_CHUNKED_ARRAY_OOP_MASK); assert(is_oop_masked(ret), "invariant"); return ret; } diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp index 34c935408d8..92c97e06174 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp @@ -225,7 +225,7 @@ oop PSPromotionManager::copy_to_survivor_space(oop o) { if (TraceScavenge) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring", - new_obj->klass()->internal_name(), o, new_obj, new_obj->size()); + new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size()); } #endif diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp index e67dedf98d4..0835f4f1f84 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,7 +81,7 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm, if (TraceScavenge && o->is_forwarded()) { gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", "forwarding", - new_obj->klass()->internal_name(), o, new_obj, new_obj->size()); + new_obj->klass()->internal_name(), (void *)o, (void *)new_obj, new_obj->size()); } #endif diff --git a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp index ac490ec4449..37ac6d1a6e4 100644 --- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp +++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp @@ -215,7 +215,7 @@ void print_oop(oop value, outputStream* st) { st->print_cr(" %s", buf); } } else { - st->print_cr(" " PTR_FORMAT, (intptr_t) value); + st->print_cr(" " PTR_FORMAT, (void *)value); } } diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 44ac9e0862d..3f9d0d19336 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -1384,7 +1384,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result, THREAD); if (HAS_PENDING_EXCEPTION) { if (TraceMethodHandles) { - tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION); + tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION); PENDING_EXCEPTION->print(); } if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp index 09558b0a2a9..c33ed095970 100644 --- a/hotspot/src/share/vm/memory/heapInspection.hpp +++ b/hotspot/src/share/vm/memory/heapInspection.hpp @@ -150,11 +150,11 @@ public: HEAP_INSPECTION_COLUMNS_DO(DECLARE_KLASS_SIZE_STATS_FIELD) static int count(oop x) { - return (HeapWordSize * ((x) ? (x)->size() : 0)); + return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0)); } static int count_array(objArrayOop x) { - return (HeapWordSize * ((x) ? (x)->size() : 0)); + return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0)); } template static int count(T* x) { diff --git a/hotspot/src/share/vm/memory/referenceProcessor.cpp b/hotspot/src/share/vm/memory/referenceProcessor.cpp index 1333c082c54..f5e7fadae72 100644 --- a/hotspot/src/share/vm/memory/referenceProcessor.cpp +++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp @@ -367,7 +367,7 @@ void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list, next_d = java_lang_ref_Reference::discovered(obj); if (TraceReferenceGC && PrintGCDetails) { gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, - obj, next_d); + (void *)obj, (void *)next_d); } assert(java_lang_ref_Reference::next(obj) == NULL, "Reference not active; should not be discovered"); @@ -392,7 +392,7 @@ void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list, next_d = java_lang_ref_Reference::discovered(obj); if (TraceReferenceGC && PrintGCDetails) { gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, - obj, next_d); + (void *)obj, (void *)next_d); } assert(java_lang_ref_Reference::next(obj) == NULL, "The reference should not be enqueued"); @@ -562,7 +562,7 @@ ReferenceProcessor::process_phase1(DiscoveredList& refs_list, !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) { if (TraceReferenceGC) { gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy", - iter.obj(), iter.obj()->klass()->internal_name()); + (void *)iter.obj(), iter.obj()->klass()->internal_name()); } // Remove Reference object from list iter.remove(); @@ -601,7 +601,7 @@ ReferenceProcessor::pp2_work(DiscoveredList& refs_list, if (iter.is_referent_alive()) { if (TraceReferenceGC) { gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)", - iter.obj(), iter.obj()->klass()->internal_name()); + (void *)iter.obj(), iter.obj()->klass()->internal_name()); } // The referent is reachable after all. // Remove Reference object from list. @@ -687,7 +687,7 @@ ReferenceProcessor::process_phase3(DiscoveredList& refs_list, if (TraceReferenceGC) { gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", clear_referent ? "cleared " : "", - iter.obj(), iter.obj()->klass()->internal_name()); + (void *)iter.obj(), iter.obj()->klass()->internal_name()); } assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference"); iter.next(); @@ -1003,7 +1003,7 @@ void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: " INTPTR_FORMAT " with next field: " INTPTR_FORMAT " and referent: " INTPTR_FORMAT, - iter.obj(), next, iter.referent()); + (void *)iter.obj(), (void *)next, (void *)iter.referent()); } ) // Remove Reference object from list @@ -1103,14 +1103,14 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list, if (TraceReferenceGC) { gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)", - obj, obj->klass()->internal_name()); + (void *)obj, obj->klass()->internal_name()); } } else { // If retest was non NULL, another thread beat us to it: // The reference has already been discovered... if (TraceReferenceGC) { gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", - obj, obj->klass()->internal_name()); + (void *)obj, obj->klass()->internal_name()); } } } @@ -1125,7 +1125,7 @@ void ReferenceProcessor::verify_referent(oop obj) { assert(da ? referent->is_oop() : referent->is_oop_or_null(), err_msg("Bad referent " INTPTR_FORMAT " found in Reference " INTPTR_FORMAT " during %satomic discovery ", - (intptr_t)referent, (intptr_t)obj, da ? "" : "non-")); + (void *)referent, (void *)obj, da ? "" : "non-")); } #endif @@ -1205,7 +1205,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { // The reference has already been discovered... if (TraceReferenceGC) { gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", - obj, obj->klass()->internal_name()); + (void *)obj, obj->klass()->internal_name()); } if (RefDiscoveryPolicy == ReferentBasedDiscovery) { // assumes that an object is not processed twice; @@ -1273,7 +1273,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { if (TraceReferenceGC) { gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)", - obj, obj->klass()->internal_name()); + (void *)obj, obj->klass()->internal_name()); } } assert(obj->is_oop(), "Discovered a bad reference"); @@ -1372,7 +1372,7 @@ ReferenceProcessor::preclean_discovered_reflist(DiscoveredList& refs_list, // active; we need to trace and mark its cohort. if (TraceReferenceGC) { gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)", - iter.obj(), iter.obj()->klass()->internal_name()); + (void *)iter.obj(), iter.obj()->klass()->internal_name()); } // Remove Reference object from list iter.remove(); diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp index 66493a879e1..27f1d84020e 100644 --- a/hotspot/src/share/vm/oops/constantPool.cpp +++ b/hotspot/src/share/vm/oops/constantPool.cpp @@ -1918,7 +1918,7 @@ void ConstantPool::print_on(outputStream* st) const { st->print_cr(" - holder: " INTPTR_FORMAT, pool_holder()); } st->print_cr(" - cache: " INTPTR_FORMAT, cache()); - st->print_cr(" - resolved_references: " INTPTR_FORMAT, resolved_references()); + st->print_cr(" - resolved_references: " INTPTR_FORMAT, (void *)resolved_references()); st->print_cr(" - reference_map: " INTPTR_FORMAT, reference_map()); for (int index = 1; index < length(); index++) { // Index 0 is unused diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp index 9d358955025..eabd1e059b0 100644 --- a/hotspot/src/share/vm/oops/cpCache.cpp +++ b/hotspot/src/share/vm/oops/cpCache.cpp @@ -306,8 +306,8 @@ void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool, if (TraceInvokeDynamic) { tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ", invoke_code, - (intptr_t)appendix(), (has_appendix ? "" : " (unused)"), - (intptr_t)method_type(), (has_method_type ? "" : " (unused)"), + (void *)appendix(), (has_appendix ? "" : " (unused)"), + (void *)method_type(), (has_method_type ? "" : " (unused)"), (intptr_t)adapter()); adapter->print(); if (has_appendix) appendix()->print(); diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index e56e80664f6..859c6aa3ee6 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -106,7 +106,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, len = name->utf8_length(); \ } \ HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \ - data, len, (clss)->class_loader(), thread_type); \ + data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type); \ } #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ @@ -119,7 +119,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, len = name->utf8_length(); \ } \ HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \ - data, len, (clss)->class_loader(), thread_type, wait); \ + data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type, wait); \ } #else /* USDT2 */ @@ -2303,7 +2303,7 @@ void InstanceKlass::set_source_debug_extension(char* array, int length) { } address InstanceKlass::static_field_addr(int offset) { - return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + (intptr_t)java_mirror()); + return (address)(offset + InstanceMirrorKlass::offset_of_static_fields() + cast_from_oop(java_mirror())); } diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp index 38f2dc81787..b861639ee0f 100644 --- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp +++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ class InstanceMirrorKlass: public InstanceKlass { // Static field offset is an offset into the Heap, should be converted by // based on UseCompressedOop for traversal static HeapWord* start_of_static_fields(oop obj) { - return (HeapWord*)((intptr_t)obj + offset_of_static_fields()); + return (HeapWord*)(cast_from_oop(obj) + offset_of_static_fields()); } static void init_offset_of_static_fields() { diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.cpp b/hotspot/src/share/vm/oops/instanceRefKlass.cpp index cb5f8965521..f388980adc3 100644 --- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { T heap_oop = oopDesc::load_heap_oop(referent_addr); debug_only( if(TraceReferenceGC && PrintGCDetails) { - gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj); + gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj); } ) if (!oopDesc::is_null(heap_oop)) { @@ -62,7 +62,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { ref->InstanceKlass::oop_follow_contents(obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { - gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); + gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, (void *)obj); } ) return; @@ -70,7 +70,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) { // treat referent as normal oop debug_only( if(TraceReferenceGC && PrintGCDetails) { - gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, obj); + gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, (void *)obj); } ) MarkSweep::mark_and_push(referent_addr); @@ -130,7 +130,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, T heap_oop = oopDesc::load_heap_oop(referent_addr); debug_only( if(TraceReferenceGC && PrintGCDetails) { - gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, obj); + gclog_or_tty->print_cr("InstanceRefKlass::oop_follow_contents " INTPTR_FORMAT, (void *)obj); } ) if (!oopDesc::is_null(heap_oop)) { @@ -142,7 +142,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, ref->InstanceKlass::oop_follow_contents(cm, obj); debug_only( if(TraceReferenceGC && PrintGCDetails) { - gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, obj); + gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, (void *)obj); } ) return; @@ -150,7 +150,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, // treat referent as normal oop debug_only( if(TraceReferenceGC && PrintGCDetails) { - gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, obj); + gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, (void *)obj); } ) PSParallelCompact::mark_and_push(cm, referent_addr); diff --git a/hotspot/src/share/vm/oops/methodData.hpp b/hotspot/src/share/vm/oops/methodData.hpp index 7ff9b2bbb6d..76f9b1f221a 100644 --- a/hotspot/src/share/vm/oops/methodData.hpp +++ b/hotspot/src/share/vm/oops/methodData.hpp @@ -333,10 +333,10 @@ protected: return (int)data()->cell_at(index); } void set_oop_at(int index, oop value) { - set_intptr_at(index, (intptr_t) value); + set_intptr_at(index, cast_from_oop(value)); } oop oop_at(int index) { - return (oop)intptr_at(index); + return cast_to_oop(intptr_at(index)); } void set_flag_at(int flag_number) { diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp index f1823f2e2b1..0a297483486 100644 --- a/hotspot/src/share/vm/oops/oop.inline.hpp +++ b/hotspot/src/share/vm/oops/oop.inline.hpp @@ -183,7 +183,7 @@ inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; } // in inner GC loops so these are separated. inline bool check_obj_alignment(oop obj) { - return (intptr_t)obj % MinObjAlignmentInBytes == 0; + return cast_from_oop(obj) % MinObjAlignmentInBytes == 0; } inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) { diff --git a/hotspot/src/share/vm/oops/oopsHierarchy.hpp b/hotspot/src/share/vm/oops/oopsHierarchy.hpp index ccf7a5f99e2..ef0d2ed2bba 100644 --- a/hotspot/src/share/vm/oops/oopsHierarchy.hpp +++ b/hotspot/src/share/vm/oops/oopsHierarchy.hpp @@ -55,11 +55,16 @@ typedef class typeArrayOopDesc* typeArrayOop; // to and from the underlying oopDesc pointer type. // // Because oop and its subclasses Oop are class types, arbitrary -// conversions are not accepted by the compiler, and you may get a message -// about overloading ambiguity (between long and int is common when converting -// from a constant in 64 bit mode), or unable to convert from type to 'oop'. -// Applying a cast to one of these conversion operators first will get to the -// underlying oopDesc* type if appropriate. +// conversions are not accepted by the compiler. Applying a cast to +// an oop will cause the best matched conversion operator to be +// invoked returning the underlying oopDesc* type if appropriate. +// No copy constructors, explicit user conversions or operators of +// numerical type should be defined within the oop class. Most C++ +// compilers will issue a compile time error concerning the overloading +// ambiguity between operators of numerical and pointer types. If +// a conversion to or from an oop to a numerical type is needed, +// use the inline template methods, cast_*_oop, defined below. +// // Converting NULL to oop to Handle implicit is no longer accepted by the // compiler because there are too many steps in the conversion. Use Handle() // instead, which generates less code anyway. @@ -83,12 +88,9 @@ public: void raw_set_obj(const void* p) { _o = (oopDesc*)p; } oop() { set_obj(NULL); } + oop(const oop& o) { set_obj(o.obj()); } oop(const volatile oop& o) { set_obj(o.obj()); } oop(const void* p) { set_obj(p); } - oop(intptr_t i) { set_obj((void *)i); } -#ifdef _LP64 - oop(int i) { set_obj((void *)i); } -#endif ~oop() { if (CheckUnhandledOops) unregister_oop(); } @@ -101,8 +103,6 @@ public: bool operator==(void *p) const { return obj() == p; } bool operator!=(const volatile oop o) const { return obj() != o.obj(); } bool operator!=(void *p) const { return obj() != p; } - bool operator==(intptr_t p) const { return obj() == (oopDesc*)p; } - bool operator!=(intptr_t p) const { return obj() != (oopDesc*)p; } bool operator<(oop o) const { return obj() < o.obj(); } bool operator>(oop o) const { return obj() > o.obj(); } @@ -110,8 +110,18 @@ public: bool operator>=(oop o) const { return obj() >= o.obj(); } bool operator!() const { return !obj(); } - // Cast + // Assignment + oop& operator=(const oop& o) { _o = o.obj(); return *this; } +#ifndef SOLARIS + volatile oop& operator=(const oop& o) volatile { _o = o.obj(); return *this; } +#endif + volatile oop& operator=(const volatile oop& o) volatile { _o = o.obj(); return *this; } + + // Explict user conversions operator void* () const { return (void *)obj(); } +#ifndef SOLARIS + operator void* () const volatile { return (void *)obj(); } +#endif operator HeapWord* () const { return (HeapWord*)obj(); } operator oopDesc* () const { return obj(); } operator intptr_t* () const { return (intptr_t*)obj(); } @@ -119,7 +129,6 @@ public: operator markOop () const { return markOop(obj()); } operator address () const { return (address)obj(); } - operator intptr_t () const volatile { return (intptr_t)obj(); } // from javaCalls.cpp operator jobject () const { return (jobject)obj(); } @@ -141,12 +150,26 @@ public: class type##Oop : public oop { \ public: \ type##Oop() : oop() {} \ + type##Oop(const oop& o) : oop(o) {} \ type##Oop(const volatile oop& o) : oop(o) {} \ type##Oop(const void* p) : oop(p) {} \ operator type##OopDesc* () const { return (type##OopDesc*)obj(); } \ type##OopDesc* operator->() const { \ return (type##OopDesc*)obj(); \ } \ + type##Oop& operator=(const type##Oop& o) { \ + oop::operator=(o); \ + return *this; \ + } \ + NOT_SOLARIS( \ + volatile type##Oop& operator=(const type##Oop& o) volatile { \ + (void)const_cast(oop::operator=(o)); \ + return *this; \ + }) \ + volatile type##Oop& operator=(const volatile type##Oop& o) volatile {\ + (void)const_cast(oop::operator=(o)); \ + return *this; \ + } \ }; DEF_OOP(instance); @@ -156,6 +179,16 @@ DEF_OOP(typeArray); #endif // CHECK_UNHANDLED_OOPS +// For CHECK_UNHANDLED_OOPS, it is ambiguous C++ behavior to have the oop +// structure contain explicit user defined conversions of both numerical +// and pointer type. Define inline methods to provide the numerical conversions. +template inline oop cast_to_oop(T value) { + return (oop)(CHECK_UNHANDLED_OOPS_ONLY((void *))(value)); +} +template inline T cast_from_oop(oop o) { + return (T)(CHECK_UNHANDLED_OOPS_ONLY((void*))o); +} + // The metadata hierarchy is separate from the oop hierarchy // class MetaspaceObj diff --git a/hotspot/src/share/vm/opto/machnode.cpp b/hotspot/src/share/vm/opto/machnode.cpp index 0d6ddf9aeed..a9f00f8381c 100644 --- a/hotspot/src/share/vm/opto/machnode.cpp +++ b/hotspot/src/share/vm/opto/machnode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -341,7 +341,7 @@ const class TypePtr *MachNode::adr_type() const { return TypePtr::BOTTOM; } // %%% make offset be intptr_t - assert(!Universe::heap()->is_in_reserved((oop)offset), "must be a raw ptr"); + assert(!Universe::heap()->is_in_reserved(cast_to_oop(offset)), "must be a raw ptr"); return TypeRawPtr::BOTTOM; } diff --git a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp index eb68b4296f5..977614648d3 100644 --- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp +++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp @@ -165,7 +165,7 @@ class JvmtiTagHashmap : public CHeapObj { static unsigned int hash(oop key, int size) { // shift right to get better distribution (as these bits will be zero // with aligned addresses) - unsigned int addr = (unsigned int)((intptr_t)key); + unsigned int addr = (unsigned int)(cast_from_oop(key)); #ifdef _LP64 return (addr >> 3) % size; #else diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp index e37b0c80d20..2e432264b6e 100644 --- a/hotspot/src/share/vm/prims/unsafe.cpp +++ b/hotspot/src/share/vm/prims/unsafe.cpp @@ -292,9 +292,9 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobj volatile oop v; if (UseCompressedOops) { volatile narrowOop n = *(volatile narrowOop*) addr; - v = oopDesc::decode_heap_oop(n); + (void)const_cast(v = oopDesc::decode_heap_oop(n)); } else { - v = *(volatile oop*) addr; + (void)const_cast(v = *(volatile oop*) addr); } OrderAccess::acquire(); return JNIHandles::make_local(env, v); @@ -1222,9 +1222,9 @@ UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute, #endif /* USDT2 */ if (event.should_commit()) { oop obj = thread->current_park_blocker(); - event.set_klass(obj ? obj->klass() : NULL); + event.set_klass((obj != NULL) ? obj->klass() : NULL); event.set_timeout(time); - event.set_address(obj ? (TYPE_ADDRESS) (uintptr_t) obj : 0); + event.set_address((obj != NULL) ? (TYPE_ADDRESS) cast_from_oop(obj) : 0); event.commit(); } UNSAFE_END diff --git a/hotspot/src/share/vm/runtime/biasedLocking.cpp b/hotspot/src/share/vm/runtime/biasedLocking.cpp index f526fbcbc7f..2ac4da03f5e 100644 --- a/hotspot/src/share/vm/runtime/biasedLocking.cpp +++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,7 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_ if (TraceBiasedLocking && (Verbose || !is_bulk)) { ResourceMark rm; tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT, - (intptr_t) obj, (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread); + (void *)obj, (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread); } JavaThread* biased_thread = mark->biased_locker(); @@ -214,8 +214,8 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_ if (mon_info->owner() == obj) { if (TraceBiasedLocking && Verbose) { tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")", - (intptr_t) mon_info->owner(), - (intptr_t) obj); + (void *) mon_info->owner(), + (void *) obj); } // Assume recursive case and fix up highest lock later markOop mark = markOopDesc::encode((BasicLock*) NULL); @@ -224,8 +224,8 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_ } else { if (TraceBiasedLocking && Verbose) { tty->print_cr(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")", - (intptr_t) mon_info->owner(), - (intptr_t) obj); + (void *) mon_info->owner(), + (void *) obj); } } } @@ -326,7 +326,7 @@ static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o, tty->print_cr("* Beginning bulk revocation (kind == %s) because of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", (bulk_rebias ? "rebias" : "revoke"), - (intptr_t) o, (intptr_t) o->mark(), o->klass()->external_name()); + (void *) o, (intptr_t) o->mark(), o->klass()->external_name()); } jlong cur_time = os::javaTimeMillis(); diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp index 007bfe7aa13..0ba02448aac 100644 --- a/hotspot/src/share/vm/runtime/deoptimization.cpp +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -234,7 +234,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); if (TraceDeoptimization) { ttyLocker ttyl; - tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread); + tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, (void *)result, thread); } } bool reallocated = false; @@ -278,7 +278,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread first = false; tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); } - tty->print_cr(" object <" INTPTR_FORMAT "> locked", mi->owner()); + tty->print_cr(" object <" INTPTR_FORMAT "> locked", (void *)mi->owner()); } } } @@ -977,7 +977,7 @@ void Deoptimization::print_objects(GrowableArray* objects) { KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); Handle obj = sv->value(); - tty->print(" object <" INTPTR_FORMAT "> of type ", sv->value()()); + tty->print(" object <" INTPTR_FORMAT "> of type ", (void *)sv->value()()); k->print_value(); tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); tty->cr(); diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp index 4fae1c8fe11..e2269a34367 100644 --- a/hotspot/src/share/vm/runtime/frame.cpp +++ b/hotspot/src/share/vm/runtime/frame.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1097,7 +1097,7 @@ oop frame::retrieve_receiver(RegisterMap* reg_map) { return NULL; } oop r = *oop_adr; - assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (intptr_t) r, (intptr_t) r)); + assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (void *) r, (void *) r)); return r; } @@ -1228,9 +1228,7 @@ void frame::check_derived_oop(oop* base, oop* derived) { void frame::ZapDeadClosure::do_oop(oop* p) { if (TraceZapDeadLocals) tty->print_cr("zapping @ " INTPTR_FORMAT " containing " INTPTR_FORMAT, p, (address)*p); - // Need cast because on _LP64 the conversion to oop is ambiguous. Constant - // can be either long or int. - *p = (oop)(int)0xbabebabe; + *p = cast_to_oop(0xbabebabe); } frame::ZapDeadClosure frame::_zap_dead; diff --git a/hotspot/src/share/vm/runtime/javaCalls.cpp b/hotspot/src/share/vm/runtime/javaCalls.cpp index 1dc58e40c7b..2de958d6f0e 100644 --- a/hotspot/src/share/vm/runtime/javaCalls.cpp +++ b/hotspot/src/share/vm/runtime/javaCalls.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -430,7 +430,7 @@ intptr_t* JavaCallArguments::parameters() { for(int i = 0; i < _size; i++) { if (_is_oop[i]) { // Handle conversion - _value[i] = (intptr_t)Handle::raw_resolve((oop *)_value[i]); + _value[i] = cast_from_oop(Handle::raw_resolve((oop *)_value[i])); } } // Return argument vector diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index f3191e524de..75c80b56b54 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -745,14 +745,14 @@ void SafepointSynchronize::block(JavaThread *thread) { #endif static void print_ptrs(intptr_t oldptr, intptr_t newptr, bool wasoop) { - bool is_oop = newptr ? ((oop)newptr)->is_oop() : false; + bool is_oop = newptr ? (cast_to_oop(newptr))->is_oop() : false; tty->print_cr(PTR_FORMAT PTR_PAD " %s %c " PTR_FORMAT PTR_PAD " %s %s", oldptr, wasoop?"oop":" ", oldptr == newptr ? ' ' : '!', newptr, is_oop?"oop":" ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":" ")); } static void print_longs(jlong oldptr, jlong newptr, bool wasoop) { - bool is_oop = newptr ? ((oop)(intptr_t)newptr)->is_oop() : false; + bool is_oop = newptr ? (cast_to_oop(newptr))->is_oop() : false; tty->print_cr(PTR64_FORMAT " %s %c " PTR64_FORMAT " %s %s", oldptr, wasoop?"oop":" ", oldptr == newptr ? ' ' : '!', newptr, is_oop?"oop":" ", (wasoop && !is_oop) ? "STALE" : ((wasoop==false&&is_oop==false&&oldptr !=newptr)?"STOMP":" ")); diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index d014eda2f80..5e3aa50777e 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -577,7 +577,7 @@ oop SharedRuntime::retrieve_receiver( Symbol* sig, frame caller ) { assert(caller.is_interpreted_frame(), ""); int args_size = ArgumentSizeComputer(sig).size() + 1; assert(args_size <= caller.interpreter_frame_expression_stack_size(), "receiver must be on interpreter stack"); - oop result = (oop) *caller.interpreter_frame_tos_at(args_size - 1); + oop result = cast_to_oop(*caller.interpreter_frame_tos_at(args_size - 1)); assert(Universe::heap()->is_in(result) && result->is_oop(), "receiver must be an oop"); return result; } @@ -2872,7 +2872,7 @@ JRT_LEAF(intptr_t*, SharedRuntime::OSR_migration_begin( JavaThread *thread) ) ObjectSynchronizer::inflate_helper(kptr2->obj()); // Now the displaced header is free to move buf[i++] = (intptr_t)lock->displaced_header(); - buf[i++] = (intptr_t)kptr2->obj(); + buf[i++] = cast_from_oop(kptr2->obj()); } } assert( i - max_locals == active_monitor_count*2, "found the expected number of monitors" ); diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp index 015dd757b23..99f0d07771d 100644 --- a/hotspot/src/share/vm/runtime/synchronizer.cpp +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp @@ -154,7 +154,7 @@ int ObjectSynchronizer::gOmInUseCount = 0; static volatile intptr_t ListLock = 0 ; // protects global monitor free-list cache static volatile int MonitorFreeCount = 0 ; // # on gFreeList static volatile int MonitorPopulation = 0 ; // # Extant -- in circulation -#define CHAINMARKER ((oop)-1) +#define CHAINMARKER (cast_to_oop(-1)) // ----------------------------------------------------------------------------- // Fast Monitor Enter/Exit @@ -510,7 +510,7 @@ static markOop ReadStableMark (oop obj) { // then for each thread on the list, set the flag and unpark() the thread. // This is conceptually similar to muxAcquire-muxRelease, except that muxRelease // wakes at most one thread whereas we need to wake the entire list. - int ix = (intptr_t(obj) >> 5) & (NINFLATIONLOCKS-1) ; + int ix = (cast_from_oop(obj) >> 5) & (NINFLATIONLOCKS-1) ; int YieldThenBlock = 0 ; assert (ix >= 0 && ix < NINFLATIONLOCKS, "invariant") ; assert ((NINFLATIONLOCKS & (NINFLATIONLOCKS-1)) == 0, "invariant") ; @@ -565,7 +565,7 @@ static inline intptr_t get_next_hash(Thread * Self, oop obj) { // This variation has the property of being stable (idempotent) // between STW operations. This can be useful in some of the 1-0 // synchronization schemes. - intptr_t addrBits = intptr_t(obj) >> 3 ; + intptr_t addrBits = cast_from_oop(obj) >> 3 ; value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ; } else if (hashCode == 2) { @@ -575,7 +575,7 @@ static inline intptr_t get_next_hash(Thread * Self, oop obj) { value = ++GVars.hcSequence ; } else if (hashCode == 4) { - value = intptr_t(obj) ; + value = cast_from_oop(obj) ; } else { // Marsaglia's xor-shift scheme with thread-specific state // This is probably the best overall implementation -- we'll @@ -1321,7 +1321,7 @@ ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) { if (object->is_instance()) { ResourceMark rm; tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", - (intptr_t) object, (intptr_t) object->mark(), + (void *) object, (intptr_t) object->mark(), object->klass()->external_name()); } } @@ -1371,7 +1371,7 @@ ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) { if (object->is_instance()) { ResourceMark rm; tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", - (intptr_t) object, (intptr_t) object->mark(), + (void *) object, (intptr_t) object->mark(), object->klass()->external_name()); } } @@ -1439,7 +1439,7 @@ bool ObjectSynchronizer::deflate_monitor(ObjectMonitor* mid, oop obj, if (obj->is_instance()) { ResourceMark rm; tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", - (intptr_t) obj, (intptr_t) obj->mark(), obj->klass()->external_name()); + (void *) obj, (intptr_t) obj->mark(), obj->klass()->external_name()); } } diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index a0f0bdba713..0e4295bc698 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -1444,7 +1444,7 @@ void JavaThread::initialize() { _in_deopt_handler = 0; _doing_unsafe_access = false; _stack_guard_state = stack_guard_unused; - _exception_oop = NULL; + (void)const_cast(_exception_oop = NULL); _exception_pc = 0; _exception_handler_pc = 0; _is_method_handle_return = 0; diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 2afaf2a8f62..4d46cfadbaf 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -1278,7 +1278,7 @@ class JavaThread: public Thread { address exception_handler_pc() const { return _exception_handler_pc; } bool is_method_handle_return() const { return _is_method_handle_return == 1; } - void set_exception_oop(oop o) { _exception_oop = o; } + void set_exception_oop(oop o) { (void)const_cast(_exception_oop = o); } void set_exception_pc(address a) { _exception_pc = a; } void set_exception_handler_pc(address a) { _exception_handler_pc = a; } void set_is_method_handle_return(bool value) { _is_method_handle_return = value ? 1 : 0; } diff --git a/hotspot/src/share/vm/runtime/vframeArray.cpp b/hotspot/src/share/vm/runtime/vframeArray.cpp index 3fda9e6dc1d..b13d560375e 100644 --- a/hotspot/src/share/vm/runtime/vframeArray.cpp +++ b/hotspot/src/share/vm/runtime/vframeArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,7 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) { case T_OBJECT: assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); // preserve object type - _locals->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT )); + _locals->add( new StackValue(cast_from_oop((value->get_obj()())), T_OBJECT )); break; case T_CONFLICT: // A dead local. Will be initialized to null/zero. @@ -136,7 +136,7 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) { case T_OBJECT: assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); // preserve object type - _expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT )); + _expressions->add( new StackValue(cast_from_oop((value->get_obj()())), T_OBJECT )); break; case T_CONFLICT: // A dead stack element. Will be initialized to null/zero. diff --git a/hotspot/src/share/vm/services/classLoadingService.cpp b/hotspot/src/share/vm/services/classLoadingService.cpp index b06890808ab..6ffa3026611 100644 --- a/hotspot/src/share/vm/services/classLoadingService.cpp +++ b/hotspot/src/share/vm/services/classLoadingService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool); len = name->utf8_length(); \ } \ HS_DTRACE_PROBE4(hotspot, class__##type, \ - data, len, (clss)->class_loader(), (shared)); \ + data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), (shared)); \ } #else /* USDT2 */ diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp index fa1bf273e07..5622fad053f 100644 --- a/hotspot/src/share/vm/services/heapDumper.cpp +++ b/hotspot/src/share/vm/services/heapDumper.cpp @@ -563,7 +563,7 @@ void DumpWriter::write_u8(u8 x) { } void DumpWriter::write_objectID(oop o) { - address a = (address)((uintptr_t)o); + address a = (address)o; #ifdef _LP64 write_u8((u8)a); #else diff --git a/hotspot/src/share/vm/services/memoryManager.cpp b/hotspot/src/share/vm/services/memoryManager.cpp index d5e54f5ff15..0cfd05b78f5 100644 --- a/hotspot/src/share/vm/services/memoryManager.cpp +++ b/hotspot/src/share/vm/services/memoryManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ HS_DTRACE_PROBE_DECL8(hotspot, mem__pool__gc__end, char*, int, char*, int, MemoryManager::MemoryManager() { _num_pools = 0; - _memory_mgr_obj = NULL; + (void)const_cast(_memory_mgr_obj = NULL); } void MemoryManager::add_pool(MemoryPool* pool) { diff --git a/hotspot/src/share/vm/services/memoryPool.cpp b/hotspot/src/share/vm/services/memoryPool.cpp index cfae726cf7b..655ee68e9e3 100644 --- a/hotspot/src/share/vm/services/memoryPool.cpp +++ b/hotspot/src/share/vm/services/memoryPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ MemoryPool::MemoryPool(const char* name, _name = name; _initial_size = init_size; _max_size = max_size; - _memory_pool_obj = NULL; + (void)const_cast(_memory_pool_obj = NULL); _available_for_allocation = true; _num_managers = 0; _type = type; diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp index bbee85c8b23..8febe547491 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp @@ -967,9 +967,9 @@ const int badCodeHeapFreeVal = 0xDD; // value used to zap // (These must be implemented as #defines because C++ compilers are // not obligated to inline non-integral constants!) #define badAddress ((address)::badAddressVal) -#define badOop ((oop)::badOopVal) +#define badOop (cast_to_oop(::badOopVal)) #define badHeapWord (::badHeapWordVal) -#define badJNIHandle ((oop)::badJNIHandleVal) +#define badJNIHandle (cast_to_oop(::badJNIHandleVal)) // Default TaskQueue size is 16K (32-bit) or 128K (64-bit) #define TASKQUEUE_SIZE (NOT_LP64(1<<14) LP64_ONLY(1<<17)) diff --git a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp index d6056fcb1f0..6bccc18e9fe 100644 --- a/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp +++ b/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp @@ -189,6 +189,10 @@ const jlong max_jlong = CONST64(0x7fffffffffffffff); #pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union (needed in windows.h) #pragma warning( disable : 4511 ) // copy constructor could not be generated #pragma warning( disable : 4291 ) // no matching operator delete found; memory will not be freed if initialization thows an exception +#ifdef CHECK_UNHANDLED_OOPS +#pragma warning( disable : 4521 ) // class has multiple copy ctors of a single type +#pragma warning( disable : 4522 ) // class has multiple assignment operators of a single type +#endif // CHECK_UNHANDLED_OOPS #if _MSC_VER >= 1400 #pragma warning( disable : 4996 ) // unsafe string functions. Same as define _CRT_SECURE_NO_WARNINGS/_CRT_SECURE_NO_DEPRICATE #endif diff --git a/hotspot/src/share/vm/utilities/hashtable.cpp b/hotspot/src/share/vm/utilities/hashtable.cpp index ecb43da83b0..3e1413f618f 100644 --- a/hotspot/src/share/vm/utilities/hashtable.cpp +++ b/hotspot/src/share/vm/utilities/hashtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -356,9 +356,9 @@ template class Hashtable; template class Hashtable; template class Hashtable; template class Hashtable; -#ifdef SOLARIS +#if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS) template class Hashtable; -#endif +#endif // SOLARIS || CHECK_UNHANDLED_OOPS template class Hashtable; template class Hashtable; template class HashtableEntry; diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp index cdc119dd691..1d4e0635311 100644 --- a/hotspot/src/share/vm/utilities/taskqueue.hpp +++ b/hotspot/src/share/vm/utilities/taskqueue.hpp @@ -322,11 +322,11 @@ public: // Attempts to claim a task from the "local" end of the queue (the most // recently pushed). If successful, returns true and sets t to the task; // otherwise, returns false (the queue is empty). - inline bool pop_local(E& t); + inline bool pop_local(volatile E& t); // Like pop_local(), but uses the "global" end of the queue (the least // recently pushed). - bool pop_global(E& t); + bool pop_global(volatile E& t); // Delete any resource associated with the queue. ~GenericTaskQueue(); @@ -424,7 +424,7 @@ bool GenericTaskQueue::pop_local_slow(uint localBot, Age oldAge) { } template -bool GenericTaskQueue::pop_global(E& t) { +bool GenericTaskQueue::pop_global(volatile E& t) { Age oldAge = _age.get(); // Architectures with weak memory model require a barrier here // to guarantee that bottom is not older than age, @@ -701,7 +701,7 @@ GenericTaskQueue::push(E t) { } template inline bool -GenericTaskQueue::pop_local(E& t) { +GenericTaskQueue::pop_local(volatile E& t) { uint localBot = _bottom; // This value cannot be N-1. That can only occur as a result of // the assignment to bottom in this method. If it does, this method @@ -799,7 +799,7 @@ public: } volatile ObjArrayTask& operator =(const volatile ObjArrayTask& t) volatile { - _obj = t._obj; + (void)const_cast(_obj = t._obj); _index = t._index; return *this; } From 8b333a99143374fe1d8ee6af78ec711a59d4eefb Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:04 -0700 Subject: [PATCH 204/293] Added tag jdk8-b109 for changeset 00aead1c2023 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index fbcdb0977c0..8ee790af31a 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -230,3 +230,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108 +91f47e8da5c60de58ed195e9b57f3bf192a18f83 jdk8-b109 From b79d965bf3539fb511de2c50ed0ee625a9f5f010 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:08 -0700 Subject: [PATCH 205/293] Added tag jdk8-b109 for changeset 663d34cd5856 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 7271ad7b3fa..fac06acf758 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -230,3 +230,4 @@ d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107 a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108 +428428cf5e06163322144cfb5367e1faa86acf20 jdk8-b109 From 8f4a717c02fa0294c9b3a26bcc274a4cb880cb0e Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:15 -0700 Subject: [PATCH 206/293] Added tag jdk8-b109 for changeset fbc092143b0b --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index d218a0c962d..3363682c90b 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -379,3 +379,4 @@ aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 85072013aad46050a362d10ab78e963121c8014c jdk8-b108 566db1b0e6efca31f181456e54c8911d0192410d hs25-b51 +c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109 From 109e02b7931fefbafece4207e3fea298a4f5f71a Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:25 -0700 Subject: [PATCH 207/293] Added tag jdk8-b109 for changeset 927782ec0a1e --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f3166e9d9df..bb0b1c00ce9 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -230,3 +230,4 @@ a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104 d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106 d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107 8ade3eed63da87067a7137c111f684a821e9e531 jdk8-b108 +02bfab2aa93899e0f02584f1e85537485a196553 jdk8-b109 From eff5402043e8fe93088a0baf0ee1cead80164c4f Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:28 -0700 Subject: [PATCH 208/293] Added tag jdk8-b109 for changeset 839c7fc1db4c --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 6a23622251b..75a5d5b556a 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -230,3 +230,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98 6908370afe834ff01739e8ec992d4246c74b7e6e jdk8-b106 e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107 d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108 +df5d4d01642572e77fd3c01e4c8703ed3f6eec87 jdk8-b109 From 19c90edea241b1c8709e6a4fbc26d5159a0d32ba Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:34 -0700 Subject: [PATCH 209/293] Added tag jdk8-b109 for changeset 93c4cdf60be2 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 6eef7251ea8..1d544d7f3d3 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -230,3 +230,4 @@ f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108 +946f3fd5f8bf0ccd180c258d25e5837fa1bf004c jdk8-b109 From 58d873f65abb3099de1b395898bb1f9a723a6a08 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:55 -0700 Subject: [PATCH 210/293] Added tag jdk8-b109 for changeset 70dd6db0a869 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 2210809d462..cd1913f9ccb 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -230,3 +230,4 @@ dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104 fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106 3f274927ec1863544b8214262ab02b7de2970da6 jdk8-b107 252f872b8a2f81a416f9127e77924ca56a4578b0 jdk8-b108 +985abf1cd327169a317d4ff4f318a8162a5cd47d jdk8-b109 From a1c24bd839b09ed236de40fe824c06ac55de7a69 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 26 Sep 2013 10:43:59 -0700 Subject: [PATCH 211/293] Added tag jdk8-b109 for changeset a9c63e60bf10 --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 10aa318ed1d..f56727e2010 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -218,3 +218,4 @@ f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105 bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106 f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107 445ad3f6d3b4ba62ebc483323e1919110a304053 jdk8-b108 +6ec2f9e5ed5bd60c2900976e6a54fdcac2f37e9e jdk8-b109 From 26b536e23d36463ae9c5caa5461774576e5fe613 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 26 Sep 2013 20:07:43 +0200 Subject: [PATCH 212/293] 8025491: Javac regression test tools/javac/T8003967/DetectMutableStaticFields.java failing Making HtmlTree.NONENCODING_CHARS final Reviewed-by: jjg --- .../com/sun/tools/doclets/formats/html/markup/HtmlTree.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java index fb7c409c3f0..ce38afe7451 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java @@ -167,7 +167,7 @@ public class HtmlTree extends Content { /** * A set of ASCII URI characters to be left unencoded. */ - public static BitSet NONENCODING_CHARS = new BitSet(256); + public static final BitSet NONENCODING_CHARS = new BitSet(256); static { // alphabetic characters From f5a3e39f94224bf9a0ef6ce2a1397e139b7f17c6 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 26 Sep 2013 19:06:09 +0100 Subject: [PATCH 213/293] 8025139: javac patch for using bootstrap compiler for debugging is not working properly Reviewed-by: jjg --- langtools/make/netbeans/langtools/build.xml | 23 +++++++++---------- .../make/tools/anttasks/SelectToolTask.java | 3 ++- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/langtools/make/netbeans/langtools/build.xml b/langtools/make/netbeans/langtools/build.xml index cbb007057cc..c0b6ae26c29 100644 --- a/langtools/make/netbeans/langtools/build.xml +++ b/langtools/make/netbeans/langtools/build.xml @@ -55,18 +55,17 @@ description="Build one or all langtools tools" /> - + - - + - + - + @@ -97,9 +96,9 @@ - - - + + + @@ -145,9 +144,9 @@ - + - + @@ -237,12 +236,12 @@ - + - + diff --git a/langtools/make/tools/anttasks/SelectToolTask.java b/langtools/make/tools/anttasks/SelectToolTask.java index 5897398d173..8cad36f6059 100644 --- a/langtools/make/tools/anttasks/SelectToolTask.java +++ b/langtools/make/tools/anttasks/SelectToolTask.java @@ -87,8 +87,9 @@ public class SelectToolTask extends Task { this(toolName, false); } - ToolChoices(String toolName, boolean boostrap) { + ToolChoices(String toolName, boolean bootstrap) { this.toolName = toolName; + this.bootstrap = bootstrap; } @Override From 587ef317c61d72d6b4e37c7c7ef5b59f88c4ef87 Mon Sep 17 00:00:00 2001 From: Brent Christian Date: Thu, 26 Sep 2013 11:13:34 -0700 Subject: [PATCH 214/293] 8025173: HashMap.put() replacing an existing key can trigger a resize() Ensure that HashMap is not resized if we're just replacing a value Reviewed-by: alanb, martin --- jdk/src/share/classes/java/util/HashMap.java | 6 +- .../java/util/HashMap/ReplaceExisting.java | 101 ++++++++++++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/util/HashMap/ReplaceExisting.java diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index 16880663f24..db39a922242 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -624,8 +624,7 @@ public class HashMap extends AbstractMap final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node[] tab; Node p; int n, i; - if (size > threshold || (tab = table) == null || - (n = tab.length) == 0) + if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); @@ -659,7 +658,8 @@ public class HashMap extends AbstractMap } } ++modCount; - ++size; + if (++size > threshold) + resize(); afterNodeInsertion(evict); return null; } diff --git a/jdk/test/java/util/HashMap/ReplaceExisting.java b/jdk/test/java/util/HashMap/ReplaceExisting.java new file mode 100644 index 00000000000..81795b30b1f --- /dev/null +++ b/jdk/test/java/util/HashMap/ReplaceExisting.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8025173 + * @summary Verify that replacing the value for an existing key does not + * corrupt active iterators, in particular due to a resize() occurring and + * not updating modCount. + * @run main ReplaceExisting + */ + +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +public class ReplaceExisting { + /* Number of entries required to trigger a resize for cap=16, load=0.75*/ + private static int ENTRIES = 13; + + public static void main(String[] args) { + for (int i = 0; i <= ENTRIES; i++) { + HashMap hm = prepHashMap(); + testItr(hm, i); + } + } + + /* Prepare a HashMap that will resize on next put() */ + private static HashMap prepHashMap() { + HashMap hm = new HashMap<>(16, 0.75f); + // Add items to one more than the resize threshold + for (int i = 0; i < ENTRIES; i++) { + hm.put(i*10, i*10); + } + return hm; + } + + /* Iterate hm for elemBeforePut elements, then call put() to replace value + * for existing key. With bug 8025173, this will also cause a resize, but + * not increase the modCount. + * Finish the iteration to check for a corrupt iterator. + */ + private static void testItr(HashMap hm, int elemBeforePut) { + if (elemBeforePut > hm.size()) { + throw new IllegalArgumentException("Error in test: elemBeforePut must be <= HashMap size"); + } + // Create a copy of the keys + HashSet keys = new HashSet<>(hm.size()); + keys.addAll(hm.keySet()); + + HashSet collected = new HashSet<>(hm.size()); + + // Run itr for elemBeforePut items, collecting returned elems + Iterator itr = hm.keySet().iterator(); + for (int i = 0; i < elemBeforePut; i++) { + Integer retVal = itr.next(); + if (!collected.add(retVal)) { + throw new RuntimeException("Corrupt iterator: key " + retVal + " already encountered"); + } + } + + // Do put() to replace entry (and resize table when bug present) + if (null == hm.put(0, 100)) { + throw new RuntimeException("Error in test: expected key 0 to be in the HashMap"); + } + + // Finish itr + collecting returned elems + while(itr.hasNext()) { + Integer retVal = itr.next(); + if (!collected.add(retVal)) { + throw new RuntimeException("Corrupt iterator: key " + retVal + " already encountered"); + } + } + + // Compare returned elems to original copy of keys + if (!keys.equals(collected)) { + throw new RuntimeException("Collected keys do not match original set of keys"); + } + } +} From cd7bfac3630b2e894108938838cb1aa45d2474c9 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Thu, 26 Sep 2013 12:07:53 -0700 Subject: [PATCH 215/293] 8024545: make develop and notproduct flag values available in product builds Reviewed-by: dholmes, kvn --- .../classes/sun/jvm/hotspot/runtime/VM.java | 31 +- hotspot/src/share/vm/prims/jvm.cpp | 4 +- hotspot/src/share/vm/runtime/arguments.cpp | 26 +- hotspot/src/share/vm/runtime/arguments.hpp | 6 +- hotspot/src/share/vm/runtime/globals.cpp | 507 ++++++++++++------ hotspot/src/share/vm/runtime/globals.hpp | 185 ++++--- .../share/vm/runtime/globals_extension.hpp | 164 +++--- hotspot/src/share/vm/runtime/vmStructs.cpp | 13 +- .../src/share/vm/services/attachListener.cpp | 10 +- .../share/vm/services/classLoadingService.cpp | 4 +- .../src/share/vm/services/dtraceAttacher.cpp | 2 +- hotspot/src/share/vm/services/management.cpp | 36 +- .../src/share/vm/services/memoryService.cpp | 3 +- 13 files changed, 583 insertions(+), 408 deletions(-) diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java index 319d2430af2..8088a49993c 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -134,15 +134,13 @@ public class VM { private String type; private String name; private Address addr; - private String kind; - private int origin; + private int flags; - private Flag(String type, String name, Address addr, String kind, int origin) { + private Flag(String type, String name, Address addr, int flags) { this.type = type; this.name = name; this.addr = addr; - this.kind = kind; - this.origin = origin; + this.flags = flags; } public String getType() { @@ -157,12 +155,8 @@ public class VM { return addr; } - public String getKind() { - return kind; - } - public int getOrigin() { - return origin; + return flags & 0xF; // XXX can we get the mask bits from somewhere? } public boolean isBool() { @@ -173,8 +167,7 @@ public class VM { if (Assert.ASSERTS_ENABLED) { Assert.that(isBool(), "not a bool flag!"); } - return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned()) - != 0; + return addr.getCIntegerAt(0, boolType.getSize(), boolType.isUnsigned()) != 0; } public boolean isIntx() { @@ -843,11 +836,10 @@ public class VM { Address flagAddr = flagType.getAddressField("flags").getValue(); - AddressField typeFld = flagType.getAddressField("type"); - AddressField nameFld = flagType.getAddressField("name"); - AddressField addrFld = flagType.getAddressField("addr"); - AddressField kindFld = flagType.getAddressField("kind"); - CIntField originFld = new CIntField(flagType.getCIntegerField("origin"), 0); + AddressField typeFld = flagType.getAddressField("_type"); + AddressField nameFld = flagType.getAddressField("_name"); + AddressField addrFld = flagType.getAddressField("_addr"); + CIntField flagsFld = new CIntField(flagType.getCIntegerField("_flags"), 0); long flagSize = flagType.getSize(); // sizeof(Flag) @@ -856,9 +848,8 @@ public class VM { String type = CStringUtilities.getString(typeFld.getValue(flagAddr)); String name = CStringUtilities.getString(nameFld.getValue(flagAddr)); Address addr = addrFld.getValue(flagAddr); - String kind = CStringUtilities.getString(kindFld.getValue(flagAddr)); - int origin = (int)originFld.getValue(flagAddr); - commandLineFlags[f] = new Flag(type, name, addr, kind, origin); + int flags = (int)flagsFld.getValue(flagAddr); + commandLineFlags[f] = new Flag(type, name, addr, flags); flagAddr = flagAddr.addOffsetTo(flagSize); } diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index d7a961edfbb..2195385da25 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -4235,13 +4235,13 @@ extern "C" { JVM_LEAF(jboolean, JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get)) JVMWrapper("JVM_AccessBoolVMFlag"); - return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, INTERNAL); + return is_get ? CommandLineFlags::boolAt((char*) name, (bool*) value) : CommandLineFlags::boolAtPut((char*) name, (bool*) value, Flag::INTERNAL); JVM_END JVM_LEAF(jboolean, JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get)) JVMWrapper("JVM_AccessVMIntFlag"); intx v; - jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, INTERNAL); + jboolean result = is_get ? CommandLineFlags::intxAt((char*) name, &v) : CommandLineFlags::intxAtPut((char*) name, &v, Flag::INTERNAL); *value = (jint)v; return result; JVM_END diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 93b31f1859a..53454e55885 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -625,11 +625,11 @@ void Arguments::describe_range_error(ArgsRange errcode) { } } -static bool set_bool_flag(char* name, bool value, FlagValueOrigin origin) { +static bool set_bool_flag(char* name, bool value, Flag::Flags origin) { return CommandLineFlags::boolAtPut(name, &value, origin); } -static bool set_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin) { +static bool set_fp_numeric_flag(char* name, char* value, Flag::Flags origin) { double v; if (sscanf(value, "%lf", &v) != 1) { return false; @@ -641,7 +641,7 @@ static bool set_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin) return false; } -static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) { +static bool set_numeric_flag(char* name, char* value, Flag::Flags origin) { julong v; intx intx_v; bool is_neg = false; @@ -674,14 +674,14 @@ static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) { return false; } -static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) { +static bool set_string_flag(char* name, const char* value, Flag::Flags origin) { if (!CommandLineFlags::ccstrAtPut(name, &value, origin)) return false; // Contract: CommandLineFlags always returns a pointer that needs freeing. FREE_C_HEAP_ARRAY(char, value, mtInternal); return true; } -static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) { +static bool append_to_string_flag(char* name, const char* new_value, Flag::Flags origin) { const char* old_value = ""; if (!CommandLineFlags::ccstrAt(name, &old_value)) return false; size_t old_len = old_value != NULL ? strlen(old_value) : 0; @@ -709,7 +709,7 @@ static bool append_to_string_flag(char* name, const char* new_value, FlagValueOr return true; } -bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) { +bool Arguments::parse_argument(const char* arg, Flag::Flags origin) { // range of acceptable characters spelled out for portability reasons #define NAME_RANGE "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]" @@ -850,7 +850,7 @@ void Arguments::print_jvm_args_on(outputStream* st) { } bool Arguments::process_argument(const char* arg, - jboolean ignore_unrecognized, FlagValueOrigin origin) { + jboolean ignore_unrecognized, Flag::Flags origin) { JDK_Version since = JDK_Version(); @@ -904,7 +904,7 @@ bool Arguments::process_argument(const char* arg, jio_fprintf(defaultStream::error_stream(), "Did you mean '%s%s%s'?\n", (fuzzy_matched->is_bool()) ? "(+/-)" : "", - fuzzy_matched->name, + fuzzy_matched->_name, (fuzzy_matched->is_bool()) ? "" : "="); } } @@ -952,7 +952,7 @@ bool Arguments::process_settings_file(const char* file_name, bool should_exist, // this allows a way to include spaces in string-valued options token[pos] = '\0'; logOption(token); - result &= process_argument(token, ignore_unrecognized, CONFIG_FILE); + result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE); build_jvm_flags(token); pos = 0; in_white_space = true; @@ -970,7 +970,7 @@ bool Arguments::process_settings_file(const char* file_name, bool should_exist, } if (pos > 0) { token[pos] = '\0'; - result &= process_argument(token, ignore_unrecognized, CONFIG_FILE); + result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE); build_jvm_flags(token); } fclose(stream); @@ -2434,7 +2434,7 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) { } // Parse JavaVMInitArgs structure passed in - result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, COMMAND_LINE); + result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, Flag::COMMAND_LINE); if (result != JNI_OK) { return result; } @@ -2521,7 +2521,7 @@ bool valid_hprof_or_jdwp_agent(char *name, bool is_path) { jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, - FlagValueOrigin origin) { + Flag::Flags origin) { // Remaining part of option string const char* tail; @@ -3344,7 +3344,7 @@ jint Arguments::parse_options_environment_variable(const char* name, SysClassPat } } - return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, ENVIRON_VAR)); + return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, Flag::ENVIRON_VAR)); } return JNI_OK; } diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp index 4b2a821a5a3..d016e22f22e 100644 --- a/hotspot/src/share/vm/runtime/arguments.hpp +++ b/hotspot/src/share/vm/runtime/arguments.hpp @@ -360,15 +360,15 @@ class Arguments : AllStatic { // Argument parsing static void do_pd_flag_adjustments(); - static bool parse_argument(const char* arg, FlagValueOrigin origin); - static bool process_argument(const char* arg, jboolean ignore_unrecognized, FlagValueOrigin origin); + static bool parse_argument(const char* arg, Flag::Flags origin); + static bool process_argument(const char* arg, jboolean ignore_unrecognized, Flag::Flags origin); static void process_java_launcher_argument(const char*, void*); static void process_java_compiler_argument(char* arg); static jint parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p); static jint parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p); static jint parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p); static jint parse_vm_init_args(const JavaVMInitArgs* args); - static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, FlagValueOrigin origin); + static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, Flag::Flags origin); static jint finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required); static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type); diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp index 280e15976de..f4b3865e5d3 100644 --- a/hotspot/src/share/vm/runtime/globals.cpp +++ b/hotspot/src/share/vm/runtime/globals.cpp @@ -62,26 +62,174 @@ ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, \ MATERIALIZE_FLAGS_EXT +void Flag::check_writable() { + if (is_constant_in_binary()) { + fatal(err_msg("flag is constant: %s", _name)); + } +} + +bool Flag::is_bool() const { + return strcmp(_type, "bool") == 0; +} + +bool Flag::get_bool() const { + return *((bool*) _addr); +} + +void Flag::set_bool(bool value) { + check_writable(); + *((bool*) _addr) = value; +} + +bool Flag::is_intx() const { + return strcmp(_type, "intx") == 0; +} + +intx Flag::get_intx() const { + return *((intx*) _addr); +} + +void Flag::set_intx(intx value) { + check_writable(); + *((intx*) _addr) = value; +} + +bool Flag::is_uintx() const { + return strcmp(_type, "uintx") == 0; +} + +uintx Flag::get_uintx() const { + return *((uintx*) _addr); +} + +void Flag::set_uintx(uintx value) { + check_writable(); + *((uintx*) _addr) = value; +} + +bool Flag::is_uint64_t() const { + return strcmp(_type, "uint64_t") == 0; +} + +uint64_t Flag::get_uint64_t() const { + return *((uint64_t*) _addr); +} + +void Flag::set_uint64_t(uint64_t value) { + check_writable(); + *((uint64_t*) _addr) = value; +} + +bool Flag::is_double() const { + return strcmp(_type, "double") == 0; +} + +double Flag::get_double() const { + return *((double*) _addr); +} + +void Flag::set_double(double value) { + check_writable(); + *((double*) _addr) = value; +} + +bool Flag::is_ccstr() const { + return strcmp(_type, "ccstr") == 0 || strcmp(_type, "ccstrlist") == 0; +} + +bool Flag::ccstr_accumulates() const { + return strcmp(_type, "ccstrlist") == 0; +} + +ccstr Flag::get_ccstr() const { + return *((ccstr*) _addr); +} + +void Flag::set_ccstr(ccstr value) { + check_writable(); + *((ccstr*) _addr) = value; +} + + +Flag::Flags Flag::get_origin() { + return Flags(_flags & VALUE_ORIGIN_MASK); +} + +void Flag::set_origin(Flags origin) { + assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity"); + _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | origin); +} + +bool Flag::is_default() { + return (get_origin() == DEFAULT); +} + +bool Flag::is_ergonomic() { + return (get_origin() == ERGONOMIC); +} + +bool Flag::is_command_line() { + return (get_origin() == COMMAND_LINE); +} + +bool Flag::is_product() const { + return (_flags & KIND_PRODUCT) != 0; +} + +bool Flag::is_manageable() const { + return (_flags & KIND_MANAGEABLE) != 0; +} + +bool Flag::is_diagnostic() const { + return (_flags & KIND_DIAGNOSTIC) != 0; +} + +bool Flag::is_experimental() const { + return (_flags & KIND_EXPERIMENTAL) != 0; +} + +bool Flag::is_notproduct() const { + return (_flags & KIND_NOT_PRODUCT) != 0; +} + +bool Flag::is_develop() const { + return (_flags & KIND_DEVELOP) != 0; +} + +bool Flag::is_read_write() const { + return (_flags & KIND_READ_WRITE) != 0; +} + +bool Flag::is_commercial() const { + return (_flags & KIND_COMMERCIAL) != 0; +} + +/** + * Returns if this flag is a constant in the binary. Right now this is + * true for notproduct and develop flags in product builds. + */ +bool Flag::is_constant_in_binary() const { +#ifdef PRODUCT + return is_notproduct() || is_develop(); +#else + return false; +#endif +} + bool Flag::is_unlocker() const { - return strcmp(name, "UnlockDiagnosticVMOptions") == 0 || - strcmp(name, "UnlockExperimentalVMOptions") == 0 || + return strcmp(_name, "UnlockDiagnosticVMOptions") == 0 || + strcmp(_name, "UnlockExperimentalVMOptions") == 0 || is_unlocker_ext(); } bool Flag::is_unlocked() const { - if (strcmp(kind, "{diagnostic}") == 0 || - strcmp(kind, "{C2 diagnostic}") == 0 || - strcmp(kind, "{ARCH diagnostic}") == 0 || - strcmp(kind, "{Shark diagnostic}") == 0) { + if (is_diagnostic()) { return UnlockDiagnosticVMOptions; - } else if (strcmp(kind, "{experimental}") == 0 || - strcmp(kind, "{C2 experimental}") == 0 || - strcmp(kind, "{ARCH experimental}") == 0 || - strcmp(kind, "{Shark experimental}") == 0) { - return UnlockExperimentalVMOptions; - } else { - return is_unlocked_ext(); } + if (is_experimental()) { + return UnlockExperimentalVMOptions; + } + return is_unlocked_ext(); } // Get custom message for this locked flag, or return NULL if @@ -91,16 +239,14 @@ void Flag::get_locked_message(char* buf, int buflen) const { } bool Flag::is_writeable() const { - return strcmp(kind, "{manageable}") == 0 || - strcmp(kind, "{product rw}") == 0 || - is_writeable_ext(); + return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext(); } // All flags except "manageable" are assumed to be internal flags. // Long term, we need to define a mechanism to specify which flags // are external/stable and change this function accordingly. bool Flag::is_external() const { - return strcmp(kind, "{manageable}") == 0 || is_external_ext(); + return is_manageable() || is_external_ext(); } @@ -108,53 +254,113 @@ bool Flag::is_external() const { #define FORMAT_BUFFER_LEN 16 void Flag::print_on(outputStream* st, bool withComments) { - st->print("%9s %-40s %c= ", type, name, (origin != DEFAULT ? ':' : ' ')); - if (is_bool()) st->print("%-16s", get_bool() ? "true" : "false"); - if (is_intx()) st->print("%-16ld", get_intx()); - if (is_uintx()) st->print("%-16lu", get_uintx()); - if (is_uint64_t()) st->print("%-16lu", get_uint64_t()); - if (is_double()) st->print("%-16f", get_double()); - - if (is_ccstr()) { - const char* cp = get_ccstr(); - if (cp != NULL) { - const char* eol; - while ((eol = strchr(cp, '\n')) != NULL) { - char format_buffer[FORMAT_BUFFER_LEN]; - size_t llen = pointer_delta(eol, cp, sizeof(char)); - jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, - "%%." SIZE_FORMAT "s", llen); - st->print(format_buffer, cp); - st->cr(); - cp = eol+1; - st->print("%5s %-35s += ", "", name); - } - st->print("%-16s", cp); - } - else st->print("%-16s", ""); + // Don't print notproduct and develop flags in a product build. + if (is_constant_in_binary()) { + return; } - st->print("%-20s", kind); + + st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' ')); + + if (is_bool()) { + st->print("%-16s", get_bool() ? "true" : "false"); + } + if (is_intx()) { + st->print("%-16ld", get_intx()); + } + if (is_uintx()) { + st->print("%-16lu", get_uintx()); + } + if (is_uint64_t()) { + st->print("%-16lu", get_uint64_t()); + } + if (is_double()) { + st->print("%-16f", get_double()); + } + if (is_ccstr()) { + const char* cp = get_ccstr(); + if (cp != NULL) { + const char* eol; + while ((eol = strchr(cp, '\n')) != NULL) { + char format_buffer[FORMAT_BUFFER_LEN]; + size_t llen = pointer_delta(eol, cp, sizeof(char)); + jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, + "%%." SIZE_FORMAT "s", llen); + st->print(format_buffer, cp); + st->cr(); + cp = eol+1; + st->print("%5s %-35s += ", "", _name); + } + st->print("%-16s", cp); + } + else st->print("%-16s", ""); + } + + st->print("%-20"); + print_kind(st); + if (withComments) { #ifndef PRODUCT - st->print("%s", doc ); + st->print("%s", _doc); #endif } st->cr(); } +void Flag::print_kind(outputStream* st) { + struct Data { + int flag; + const char* name; + }; + + Data data[] = { + { KIND_C1, "C1" }, + { KIND_C2, "C2" }, + { KIND_ARCH, "ARCH" }, + { KIND_SHARK, "SHARK" }, + { KIND_PLATFORM_DEPENDENT, "pd" }, + { KIND_PRODUCT, "product" }, + { KIND_MANAGEABLE, "manageable" }, + { KIND_DIAGNOSTIC, "diagnostic" }, + { KIND_NOT_PRODUCT, "notproduct" }, + { KIND_DEVELOP, "develop" }, + { KIND_LP64_PRODUCT, "lp64_product" }, + { KIND_READ_WRITE, "rw" }, + { -1, "" } + }; + + if ((_flags & KIND_MASK) != 0) { + st->print("{"); + bool is_first = true; + + for (int i = 0; data[i].flag != -1; i++) { + Data d = data[i]; + if ((_flags & d.flag) != 0) { + if (is_first) { + is_first = false; + } else { + st->print(" "); + } + st->print(d.name); + } + } + + st->print("}"); + } +} + void Flag::print_as_flag(outputStream* st) { if (is_bool()) { - st->print("-XX:%s%s", get_bool() ? "+" : "-", name); + st->print("-XX:%s%s", get_bool() ? "+" : "-", _name); } else if (is_intx()) { - st->print("-XX:%s=" INTX_FORMAT, name, get_intx()); + st->print("-XX:%s=" INTX_FORMAT, _name, get_intx()); } else if (is_uintx()) { - st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx()); + st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx()); } else if (is_uint64_t()) { - st->print("-XX:%s=" UINT64_FORMAT, name, get_uint64_t()); + st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t()); } else if (is_double()) { - st->print("-XX:%s=%f", name, get_double()); + st->print("-XX:%s=%f", _name, get_double()); } else if (is_ccstr()) { - st->print("-XX:%s=", name); + st->print("-XX:%s=", _name); const char* cp = get_ccstr(); if (cp != NULL) { // Need to turn embedded '\n's back into separate arguments @@ -167,7 +373,7 @@ void Flag::print_as_flag(outputStream* st) { st->print("%c", *cp); break; case '\n': - st->print(" -XX:%s=", name); + st->print(" -XX:%s=", _name); break; } } @@ -180,79 +386,51 @@ void Flag::print_as_flag(outputStream* st) { // 4991491 do not "optimize out" the was_set false values: omitting them // tickles a Microsoft compiler bug causing flagTable to be malformed -#define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product}", DEFAULT }, -#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{pd product}", DEFAULT }, -#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{diagnostic}", DEFAULT }, -#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{experimental}", DEFAULT }, -#define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{manageable}", DEFAULT }, -#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product rw}", DEFAULT }, +#define NAME(name) NOT_PRODUCT(&name) PRODUCT_ONLY(&CONST_##name) -#ifdef PRODUCT - #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ - #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ - #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) -#else - #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "", DEFAULT }, - #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{pd}", DEFAULT }, - #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{notproduct}", DEFAULT }, -#endif +#define RUNTIME_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) }, +#define RUNTIME_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, +#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) }, +#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) }, +#define RUNTIME_MANAGEABLE_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) }, +#define RUNTIME_PRODUCT_RW_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_READ_WRITE) }, +#define RUNTIME_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP) }, +#define RUNTIME_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, +#define RUNTIME_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_NOT_PRODUCT) }, #ifdef _LP64 - #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{lp64_product}", DEFAULT }, +#define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_LP64_PRODUCT) }, #else - #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ +#define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ #endif // _LP64 -#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT }, -#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT }, -#define C1_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 diagnostic}", DEFAULT }, -#ifdef PRODUCT - #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ - #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ - #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) -#else - #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1}", DEFAULT }, - #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{C1 pd}", DEFAULT }, - #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT }, -#endif +#define C1_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT) }, +#define C1_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, +#define C1_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DIAGNOSTIC) }, +#define C1_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP) }, +#define C1_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, +#define C1_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_NOT_PRODUCT) }, -#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT }, -#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT }, -#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT }, -#define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 experimental}", DEFAULT }, -#ifdef PRODUCT - #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ - #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ - #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) -#else - #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2}", DEFAULT }, - #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{C2 pd}", DEFAULT }, - #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT }, -#endif +#define C2_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT) }, +#define C2_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, +#define C2_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DIAGNOSTIC) }, +#define C2_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_EXPERIMENTAL) }, +#define C2_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP) }, +#define C2_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, +#define C2_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_NOT_PRODUCT) }, -#define ARCH_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH product}", DEFAULT }, -#define ARCH_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH diagnostic}", DEFAULT }, -#define ARCH_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH experimental}", DEFAULT }, -#ifdef PRODUCT - #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ - #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) -#else - #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH}", DEFAULT }, - #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH notproduct}", DEFAULT }, -#endif +#define ARCH_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_PRODUCT) }, +#define ARCH_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DIAGNOSTIC) }, +#define ARCH_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_EXPERIMENTAL) }, +#define ARCH_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DEVELOP) }, +#define ARCH_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_NOT_PRODUCT) }, -#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT }, -#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT }, -#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT }, -#ifdef PRODUCT - #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ - #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ - #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) -#else - #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark}", DEFAULT }, - #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{Shark pd}", DEFAULT }, - #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark notproduct}", DEFAULT }, -#endif +#define SHARK_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT) }, +#define SHARK_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, +#define SHARK_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DIAGNOSTIC) }, +#define SHARK_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP) }, +#define SHARK_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, +#define SHARK_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_NOT_PRODUCT) }, static Flag flagTable[] = { RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT) @@ -285,9 +463,14 @@ inline bool str_equal(const char* s, const char* q, size_t len) { // Search the flag table for a named flag Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked) { - for (Flag* current = &flagTable[0]; current->name != NULL; current++) { - if (str_equal(current->name, name, length)) { - // Found a matching entry. Report locked flags only if allowed. + for (Flag* current = &flagTable[0]; current->_name != NULL; current++) { + if (str_equal(current->_name, name, length)) { + // Found a matching entry. + // Don't report notproduct and develop flags in product builds. + if (current->is_constant_in_binary()) { + return NULL; + } + // Report locked flags only if allowed. if (!(current->is_unlocked() || current->is_unlocker())) { if (!allow_locked) { // disable use of locked flags, e.g. diagnostic, experimental, @@ -327,8 +510,8 @@ Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) { float score; float max_score = -1; - for (Flag* current = &flagTable[0]; current->name != NULL; current++) { - score = str_similar(current->name, name, length); + for (Flag* current = &flagTable[0]; current->_name != NULL; current++) { + score = str_similar(current->_name, name, length); if (score > max_score) { max_score = score; match = current; @@ -357,25 +540,25 @@ static Flag* address_of_flag(CommandLineFlagWithType flag) { bool CommandLineFlagsEx::is_default(CommandLineFlag flag) { assert((size_t)flag < Flag::numFlags, "bad command line flag index"); Flag* f = &Flag::flags[flag]; - return (f->origin == DEFAULT); + return f->is_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); + return f->is_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); + return f->is_command_line(); } bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) { Flag* result = Flag::find_flag((char*)name, strlen(name)); if (result == NULL) return false; - *value = (result->origin == COMMAND_LINE); + *value = result->is_command_line(); return true; } @@ -387,22 +570,22 @@ bool CommandLineFlags::boolAt(char* name, size_t len, bool* value) { return true; } -bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin) { +bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_bool()) return false; bool old_value = result->get_bool(); result->set_bool(*value); *value = old_value; - result->origin = origin; + result->set_origin(origin); return true; } -void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin) { +void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) { Flag* faddr = address_of_flag(flag); guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); faddr->set_bool(value); - faddr->origin = origin; + faddr->set_origin(origin); } bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) { @@ -413,22 +596,22 @@ bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) { return true; } -bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin) { +bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_intx()) return false; intx old_value = result->get_intx(); result->set_intx(*value); *value = old_value; - result->origin = origin; + result->set_origin(origin); return true; } -void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin) { +void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) { Flag* faddr = address_of_flag(flag); guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); faddr->set_intx(value); - faddr->origin = origin; + faddr->set_origin(origin); } bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) { @@ -439,22 +622,22 @@ bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) { return true; } -bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin) { +bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_uintx()) return false; uintx old_value = result->get_uintx(); result->set_uintx(*value); *value = old_value; - result->origin = origin; + result->set_origin(origin); return true; } -void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin) { +void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) { Flag* faddr = address_of_flag(flag); guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); faddr->set_uintx(value); - faddr->origin = origin; + faddr->set_origin(origin); } bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) { @@ -465,22 +648,22 @@ bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) { return true; } -bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin) { +bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_uint64_t()) return false; uint64_t old_value = result->get_uint64_t(); result->set_uint64_t(*value); *value = old_value; - result->origin = origin; + result->set_origin(origin); return true; } -void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin) { +void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) { Flag* faddr = address_of_flag(flag); guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type"); faddr->set_uint64_t(value); - faddr->origin = origin; + faddr->set_origin(origin); } bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) { @@ -491,22 +674,22 @@ bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) { return true; } -bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin) { +bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_double()) return false; double old_value = result->get_double(); result->set_double(*value); *value = old_value; - result->origin = origin; + result->set_origin(origin); return true; } -void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin) { +void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) { Flag* faddr = address_of_flag(flag); guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); faddr->set_double(value); - faddr->origin = origin; + faddr->set_origin(origin); } bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) { @@ -519,7 +702,7 @@ bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) { // Contract: Flag will make private copy of the incoming value. // Outgoing value is always malloc-ed, and caller MUST call free. -bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin) { +bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin) { Flag* result = Flag::find_flag(name, len); if (result == NULL) return false; if (!result->is_ccstr()) return false; @@ -530,35 +713,35 @@ bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValu strcpy(new_value, *value); } result->set_ccstr(new_value); - if (result->origin == DEFAULT && old_value != NULL) { + if (result->is_default() && old_value != NULL) { // Prior value is NOT heap allocated, but was a literal constant. char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal); strcpy(old_value_to_free, old_value); old_value = old_value_to_free; } *value = old_value; - result->origin = origin; + result->set_origin(origin); return true; } // Contract: Flag will make private copy of the incoming value. -void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin) { +void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) { Flag* faddr = address_of_flag(flag); guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); ccstr old_value = faddr->get_ccstr(); char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal); strcpy(new_value, value); faddr->set_ccstr(new_value); - if (faddr->origin != DEFAULT && old_value != NULL) { + if (!faddr->is_default() && old_value != NULL) { // Prior value is heap allocated so free it. FREE_C_HEAP_ARRAY(char, old_value, mtInternal); } - faddr->origin = origin; + faddr->set_origin(origin); } extern "C" { static int compare_flags(const void* void_a, const void* void_b) { - return strcmp((*((Flag**) void_a))->name, (*((Flag**) void_b))->name); + return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name); } } @@ -567,20 +750,19 @@ void CommandLineFlags::printSetFlags(outputStream* out) { // note: this method is called before the thread structure is in place // which means resource allocation cannot be used. - // Compute size - int length= 0; - while (flagTable[length].name != NULL) length++; + // The last entry is the null entry. + const size_t length = Flag::numFlags - 1; // Sort Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); - for (int index = 0; index < length; index++) { - array[index] = &flagTable[index]; + for (size_t i = 0; i < length; i++) { + array[i] = &flagTable[i]; } qsort(array, length, sizeof(Flag*), compare_flags); // Print - for (int i = 0; i < length; i++) { - if (array[i]->origin /* naked field! */) { + for (size_t i = 0; i < length; i++) { + if (array[i]->get_origin() /* naked field! */) { array[i]->print_as_flag(out); out->print(" "); } @@ -603,20 +785,19 @@ void CommandLineFlags::printFlags(outputStream* out, bool withComments) { // note: this method is called before the thread structure is in place // which means resource allocation cannot be used. - // Compute size - int length= 0; - while (flagTable[length].name != NULL) length++; + // The last entry is the null entry. + const size_t length = Flag::numFlags - 1; // Sort Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); - for (int index = 0; index < length; index++) { - array[index] = &flagTable[index]; + for (size_t i = 0; i < length; i++) { + array[i] = &flagTable[i]; } qsort(array, length, sizeof(Flag*), compare_flags); // Print out->print_cr("[Global flags]"); - for (int i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) { if (array[i]->is_unlocked()) { array[i]->print_on(out, withComments); } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index f2cf5efabeb..9d429cd76db 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -194,29 +194,49 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G); typedef const char* ccstr; typedef const char* ccstrlist; // represents string arguments which accumulate -enum FlagValueOrigin { - DEFAULT = 0, - COMMAND_LINE = 1, - ENVIRON_VAR = 2, - CONFIG_FILE = 3, - MANAGEMENT = 4, - ERGONOMIC = 5, - ATTACH_ON_DEMAND = 6, - INTERNAL = 99 -}; - struct Flag { - const char *type; - const char *name; - void* addr; + enum Flags { + // value origin + DEFAULT = 0, + COMMAND_LINE = 1, + ENVIRON_VAR = 2, + CONFIG_FILE = 3, + MANAGEMENT = 4, + ERGONOMIC = 5, + ATTACH_ON_DEMAND = 6, + INTERNAL = 7, - NOT_PRODUCT(const char *doc;) + LAST_VALUE_ORIGIN = INTERNAL, + VALUE_ORIGIN_BITS = 4, + VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS), - const char *kind; - FlagValueOrigin origin; + // flag kind + KIND_PRODUCT = 1 << 4, + KIND_MANAGEABLE = 1 << 5, + KIND_DIAGNOSTIC = 1 << 6, + KIND_EXPERIMENTAL = 1 << 7, + KIND_NOT_PRODUCT = 1 << 8, + KIND_DEVELOP = 1 << 9, + KIND_PLATFORM_DEPENDENT = 1 << 10, + KIND_READ_WRITE = 1 << 11, + KIND_C1 = 1 << 12, + KIND_C2 = 1 << 13, + KIND_ARCH = 1 << 14, + KIND_SHARK = 1 << 15, + KIND_LP64_PRODUCT = 1 << 16, + KIND_COMMERCIAL = 1 << 17, + + KIND_MASK = ~VALUE_ORIGIN_MASK + }; + + const char* _type; + const char* _name; + void* _addr; + NOT_PRODUCT(const char* _doc;) + Flags _flags; // points to all Flags static array - static Flag *flags; + static Flag* flags; // number of flags static size_t numFlags; @@ -224,30 +244,50 @@ struct Flag { static Flag* find_flag(const char* name, size_t length, bool allow_locked = false); static Flag* fuzzy_match(const char* name, size_t length, bool allow_locked = false); - bool is_bool() const { return strcmp(type, "bool") == 0; } - bool get_bool() const { return *((bool*) addr); } - void set_bool(bool value) { *((bool*) addr) = value; } + void check_writable(); - bool is_intx() const { return strcmp(type, "intx") == 0; } - intx get_intx() const { return *((intx*) addr); } - void set_intx(intx value) { *((intx*) addr) = value; } + bool is_bool() const; + bool get_bool() const; + void set_bool(bool value); - bool is_uintx() const { return strcmp(type, "uintx") == 0; } - uintx get_uintx() const { return *((uintx*) addr); } - void set_uintx(uintx value) { *((uintx*) addr) = value; } + bool is_intx() const; + intx get_intx() const; + void set_intx(intx value); - bool is_uint64_t() const { return strcmp(type, "uint64_t") == 0; } - uint64_t get_uint64_t() const { return *((uint64_t*) addr); } - void set_uint64_t(uint64_t value) { *((uint64_t*) addr) = value; } + bool is_uintx() const; + uintx get_uintx() const; + void set_uintx(uintx value); - bool is_double() const { return strcmp(type, "double") == 0; } - double get_double() const { return *((double*) addr); } - void set_double(double value) { *((double*) addr) = value; } + bool is_uint64_t() const; + uint64_t get_uint64_t() const; + void set_uint64_t(uint64_t value); - bool is_ccstr() const { return strcmp(type, "ccstr") == 0 || strcmp(type, "ccstrlist") == 0; } - bool ccstr_accumulates() const { return strcmp(type, "ccstrlist") == 0; } - ccstr get_ccstr() const { return *((ccstr*) addr); } - void set_ccstr(ccstr value) { *((ccstr*) addr) = value; } + bool is_double() const; + double get_double() const; + void set_double(double value); + + bool is_ccstr() const; + bool ccstr_accumulates() const; + ccstr get_ccstr() const; + void set_ccstr(ccstr value); + + Flags get_origin(); + void set_origin(Flags origin); + + bool is_default(); + bool is_ergonomic(); + bool is_command_line(); + + bool is_product() const; + bool is_manageable() const; + bool is_diagnostic() const; + bool is_experimental() const; + bool is_notproduct() const; + bool is_develop() const; + bool is_read_write() const; + bool is_commercial() const; + + bool is_constant_in_binary() const; bool is_unlocker() const; bool is_unlocked() const; @@ -263,6 +303,7 @@ struct Flag { void get_locked_message_ext(char*, int) const; void print_on(outputStream* st, bool withComments = false ); + void print_kind(outputStream* st); void print_as_flag(outputStream* st); }; @@ -310,33 +351,33 @@ class CommandLineFlags { public: static bool boolAt(char* name, size_t len, bool* value); static bool boolAt(char* name, bool* value) { return boolAt(name, strlen(name), value); } - static bool boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin); - static bool boolAtPut(char* name, bool* value, FlagValueOrigin origin) { return boolAtPut(name, strlen(name), value, origin); } + static bool boolAtPut(char* name, size_t len, bool* value, Flag::Flags origin); + static bool boolAtPut(char* name, bool* value, Flag::Flags origin) { return boolAtPut(name, strlen(name), value, origin); } static bool intxAt(char* name, size_t len, intx* value); static bool intxAt(char* name, intx* value) { return intxAt(name, strlen(name), value); } - static bool intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin); - static bool intxAtPut(char* name, intx* value, FlagValueOrigin origin) { return intxAtPut(name, strlen(name), value, origin); } + static bool intxAtPut(char* name, size_t len, intx* value, Flag::Flags origin); + static bool intxAtPut(char* name, intx* value, Flag::Flags origin) { return intxAtPut(name, strlen(name), value, origin); } static bool uintxAt(char* name, size_t len, uintx* value); static bool uintxAt(char* name, uintx* value) { return uintxAt(name, strlen(name), value); } - static bool uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin); - static bool uintxAtPut(char* name, uintx* value, FlagValueOrigin origin) { return uintxAtPut(name, strlen(name), value, origin); } + static bool uintxAtPut(char* name, size_t len, uintx* value, Flag::Flags origin); + static bool uintxAtPut(char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); } static bool uint64_tAt(char* name, size_t len, uint64_t* value); static bool uint64_tAt(char* name, uint64_t* value) { return uint64_tAt(name, strlen(name), value); } - static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin); - static bool uint64_tAtPut(char* name, uint64_t* value, FlagValueOrigin origin) { return uint64_tAtPut(name, strlen(name), value, origin); } + static bool uint64_tAtPut(char* name, size_t len, uint64_t* value, Flag::Flags origin); + static bool uint64_tAtPut(char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); } static bool doubleAt(char* name, size_t len, double* value); static bool doubleAt(char* name, double* value) { return doubleAt(name, strlen(name), value); } - static bool doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin); - static bool doubleAtPut(char* name, double* value, FlagValueOrigin origin) { return doubleAtPut(name, strlen(name), value, origin); } + static bool doubleAtPut(char* name, size_t len, double* value, Flag::Flags origin); + static bool doubleAtPut(char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); } static bool ccstrAt(char* name, size_t len, ccstr* value); static bool ccstrAt(char* name, ccstr* value) { return ccstrAt(name, strlen(name), value); } - static bool ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin); - static bool ccstrAtPut(char* name, ccstr* value, FlagValueOrigin origin) { return ccstrAtPut(name, strlen(name), value, origin); } + static bool ccstrAtPut(char* name, size_t len, ccstr* value, Flag::Flags origin); + static bool ccstrAtPut(char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); } // Returns false if name is not a command line flag. static bool wasSetOnCmdline(const char* name, bool* value); @@ -3727,20 +3768,20 @@ class CommandLineFlags { */ // Interface macros -#define DECLARE_PRODUCT_FLAG(type, name, value, doc) extern "C" type name; -#define DECLARE_PD_PRODUCT_FLAG(type, name, doc) extern "C" type name; -#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc) extern "C" type name; +#define DECLARE_PRODUCT_FLAG(type, name, value, doc) extern "C" type name; +#define DECLARE_PD_PRODUCT_FLAG(type, name, doc) extern "C" type name; +#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc) extern "C" type name; #define DECLARE_EXPERIMENTAL_FLAG(type, name, value, doc) extern "C" type name; -#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc) extern "C" type name; -#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc) extern "C" type name; +#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc) extern "C" type name; +#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc) extern "C" type name; #ifdef PRODUCT -#define DECLARE_DEVELOPER_FLAG(type, name, value, doc) const type name = value; -#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc) const type name = pd_##name; -#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc) +#define DECLARE_DEVELOPER_FLAG(type, name, value, doc) extern "C" type CONST_##name; const type name = value; +#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc) extern "C" type CONST_##name; const type name = pd_##name; +#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc) extern "C" type CONST_##name; #else -#define DECLARE_DEVELOPER_FLAG(type, name, value, doc) extern "C" type name; -#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc) extern "C" type name; -#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc) extern "C" type name; +#define DECLARE_DEVELOPER_FLAG(type, name, value, doc) extern "C" type name; +#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc) extern "C" type name; +#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc) extern "C" type name; #endif // Special LP64 flags, product only needed for now. #ifdef _LP64 @@ -3750,23 +3791,23 @@ class CommandLineFlags { #endif // _LP64 // Implementation macros -#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc) type name = value; -#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc) type name = pd_##name; -#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc) type name = value; +#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc) type name = value; +#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc) type name = pd_##name; +#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc) type name = value; #define MATERIALIZE_EXPERIMENTAL_FLAG(type, name, value, doc) type name = value; -#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc) type name = value; -#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc) type name = value; +#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc) type name = value; +#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc) type name = value; #ifdef PRODUCT -#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) /* flag name is constant */ -#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc) /* flag name is constant */ -#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) +#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) type CONST_##name = value; +#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc) type CONST_##name = pd_##name; +#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) type CONST_##name = value; #else -#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) type name = value; -#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc) type name = pd_##name; -#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) type name = value; +#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc) type name = value; +#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc) type name = pd_##name; +#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc) type name = value; #endif #ifdef _LP64 -#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value; +#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value; #else #define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */ #endif // _LP64 diff --git a/hotspot/src/share/vm/runtime/globals_extension.hpp b/hotspot/src/share/vm/runtime/globals_extension.hpp index bc4fd4a74bc..ea3fc60739c 100644 --- a/hotspot/src/share/vm/runtime/globals_extension.hpp +++ b/hotspot/src/share/vm/runtime/globals_extension.hpp @@ -34,64 +34,42 @@ // Parens left off in the following for the enum decl below. #define FLAG_MEMBER(flag) Flag_##flag -#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), -#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define RUNTIME_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define RUNTIME_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), +#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), #define RUNTIME_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#ifdef PRODUCT - #define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */ - #define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc) /* flag is constant */ - #define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) -#else - #define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), - #define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), - #define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#endif +#define RUNTIME_MANAGEABLE_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define RUNTIME_PRODUCT_RW_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define RUNTIME_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define RUNTIME_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), +#define RUNTIME_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), + #ifdef _LP64 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), #else -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) /* flag is constant */ +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER(type, name, value, doc) /* flag is constant */ #endif // _LP64 -#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), -#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#ifdef PRODUCT - #define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */ - #define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc) /* flag is constant */ - #define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) -#else - #define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), - #define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), - #define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#endif +#define C1_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define C1_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), +#define C1_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define C1_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define C1_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), +#define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), -#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#ifdef PRODUCT - #define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */ - #define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc) /* flag is constant */ - #define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) -#else - #define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), - #define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), - #define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#endif +#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), +#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define C2_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define C2_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define C2_PD_DEVELOP_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name), +#define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), #define ARCH_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), #define ARCH_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), #define ARCH_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#ifdef PRODUCT - #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */ - #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) -#else - #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), - #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), -#endif +#define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), +#define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name), typedef enum { RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER) @@ -114,64 +92,42 @@ typedef enum { #define FLAG_MEMBER_WITH_TYPE(flag,type) Flag_##flag##_##type -#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), #define RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#ifdef PRODUCT - #define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */ - #define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) /* flag is constant */ - #define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) -#else - #define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), - #define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), - #define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#endif +#define RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), + +#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define C1_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#ifdef PRODUCT - #define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */ - #define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) /* flag is constant */ - #define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) -#else - #define C1_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), - #define C1_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), - #define C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#endif #ifdef _LP64 -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), #else -#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */ +#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */ #endif // _LP64 -#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), #define C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#ifdef PRODUCT - #define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */ - #define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) /* flag is constant */ - #define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) -#else - #define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), - #define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), - #define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#endif +#define C2_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C2_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), #define ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), #define ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#ifdef PRODUCT - #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */ - #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) -#else - #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), - #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), -#endif +#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), +#define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type), typedef enum { RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE, @@ -233,19 +189,19 @@ typedef enum { #define FLAG_SET_DEFAULT(name, value) ((name) = (value)) -#define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), COMMAND_LINE)) -#define FLAG_SET_ERGO(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), ERGONOMIC)) +#define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::COMMAND_LINE)) +#define FLAG_SET_ERGO(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::ERGONOMIC)) // Can't put the following in CommandLineFlags because // of a circular dependency on the enum definition. class CommandLineFlagsEx : CommandLineFlags { public: - static void boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin); - static void intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin); - static void uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin); - static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin); - static void doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin); - static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin); + static void boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin); + static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin); + static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin); + static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin); + static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin); + static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin); static bool is_default(CommandLineFlag flag); static bool is_ergo(CommandLineFlag flag); diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index 55405b27fd4..c9365cf16e2 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -1185,11 +1185,10 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; /* -XX flags */ \ /*********************/ \ \ - nonstatic_field(Flag, type, const char*) \ - nonstatic_field(Flag, name, const char*) \ - unchecked_nonstatic_field(Flag, addr, sizeof(void*)) /* NOTE: no type */ \ - nonstatic_field(Flag, kind, const char*) \ - nonstatic_field(Flag, origin, FlagValueOrigin) \ + nonstatic_field(Flag, _type, const char*) \ + nonstatic_field(Flag, _name, const char*) \ + unchecked_nonstatic_field(Flag, _addr, sizeof(void*)) /* NOTE: no type */ \ + nonstatic_field(Flag, _flags, Flag::Flags) \ static_field(Flag, flags, Flag*) \ static_field(Flag, numFlags, size_t) \ \ @@ -2074,7 +2073,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_integer_type(JavaThreadState) \ declare_integer_type(Location::Type) \ declare_integer_type(Location::Where) \ - declare_integer_type(FlagValueOrigin) \ + declare_integer_type(Flag::Flags) \ COMPILER2_PRESENT(declare_integer_type(OptoReg::Name)) \ \ declare_toplevel_type(CHeapObj) \ @@ -2082,7 +2081,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_type(Array, MetaspaceObj) \ declare_type(Array, MetaspaceObj) \ declare_type(Array, MetaspaceObj) \ - declare_type(Array, MetaspaceObj) \ + declare_type(Array, MetaspaceObj) \ \ declare_integer_type(AccessFlags) /* FIXME: wrong type (not integer) */\ declare_toplevel_type(address) /* FIXME: should this be an integer type? */\ diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp index bf002e7fa88..6fc520d4f04 100644 --- a/hotspot/src/share/vm/services/attachListener.cpp +++ b/hotspot/src/share/vm/services/attachListener.cpp @@ -245,7 +245,7 @@ static jint set_bool_flag(const char* name, AttachOperation* op, outputStream* o } value = (tmp != 0); } - bool res = CommandLineFlags::boolAtPut((char*)name, &value, ATTACH_ON_DEMAND); + bool res = CommandLineFlags::boolAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); if (! res) { out->print_cr("setting flag %s failed", name); } @@ -263,7 +263,7 @@ static jint set_intx_flag(const char* name, AttachOperation* op, outputStream* o return JNI_ERR; } } - bool res = CommandLineFlags::intxAtPut((char*)name, &value, ATTACH_ON_DEMAND); + bool res = CommandLineFlags::intxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); if (! res) { out->print_cr("setting flag %s failed", name); } @@ -282,7 +282,7 @@ static jint set_uintx_flag(const char* name, AttachOperation* op, outputStream* return JNI_ERR; } } - bool res = CommandLineFlags::uintxAtPut((char*)name, &value, ATTACH_ON_DEMAND); + bool res = CommandLineFlags::uintxAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); if (! res) { out->print_cr("setting flag %s failed", name); } @@ -301,7 +301,7 @@ static jint set_uint64_t_flag(const char* name, AttachOperation* op, outputStrea return JNI_ERR; } } - bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, ATTACH_ON_DEMAND); + bool res = CommandLineFlags::uint64_tAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); if (! res) { out->print_cr("setting flag %s failed", name); } @@ -316,7 +316,7 @@ static jint set_ccstr_flag(const char* name, AttachOperation* op, outputStream* out->print_cr("flag value must be a string"); return JNI_ERR; } - bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, ATTACH_ON_DEMAND); + bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, Flag::ATTACH_ON_DEMAND); if (res) { FREE_C_HEAP_ARRAY(char, value, mtInternal); } else { diff --git a/hotspot/src/share/vm/services/classLoadingService.cpp b/hotspot/src/share/vm/services/classLoadingService.cpp index b06890808ab..3f3289ec118 100644 --- a/hotspot/src/share/vm/services/classLoadingService.cpp +++ b/hotspot/src/share/vm/services/classLoadingService.cpp @@ -202,7 +202,7 @@ bool ClassLoadingService::set_verbose(bool verbose) { MutexLocker m(Management_lock); // verbose will be set to the previous value - bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, MANAGEMENT); + bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, Flag::MANAGEMENT); assert(succeed, "Setting TraceClassLoading flag fails"); reset_trace_class_unloading(); @@ -213,7 +213,7 @@ bool ClassLoadingService::set_verbose(bool verbose) { void ClassLoadingService::reset_trace_class_unloading() { assert(Management_lock->owned_by_self(), "Must own the Management_lock"); bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose(); - bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, MANAGEMENT); + bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, Flag::MANAGEMENT); assert(succeed, "Setting TraceClassUnLoading flag fails"); } diff --git a/hotspot/src/share/vm/services/dtraceAttacher.cpp b/hotspot/src/share/vm/services/dtraceAttacher.cpp index 9722e4eb278..e0799eac055 100644 --- a/hotspot/src/share/vm/services/dtraceAttacher.cpp +++ b/hotspot/src/share/vm/services/dtraceAttacher.cpp @@ -51,7 +51,7 @@ class VM_DeoptimizeTheWorld : public VM_Operation { static void set_bool_flag(const char* flag, bool value) { CommandLineFlags::boolAtPut((char*)flag, strlen(flag), &value, - ATTACH_ON_DEMAND); + Flag::ATTACH_ON_DEMAND); } // Enable only the "fine grained" flags. Do *not* touch diff --git a/hotspot/src/share/vm/services/management.cpp b/hotspot/src/share/vm/services/management.cpp index 5cc0cc4ffcc..9c87989601b 100644 --- a/hotspot/src/share/vm/services/management.cpp +++ b/hotspot/src/share/vm/services/management.cpp @@ -1643,9 +1643,13 @@ JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env)) int num_entries = 0; for (int i = 0; i < nFlags; i++) { Flag* flag = &Flag::flags[i]; + // Exclude notproduct and develop flags in product builds. + if (flag->is_constant_in_binary()) { + continue; + } // Exclude the locked (experimental, diagnostic) flags if (flag->is_unlocked() || flag->is_unlocker()) { - Handle s = java_lang_String::create_from_str(flag->name, CHECK_0); + Handle s = java_lang_String::create_from_str(flag->_name, CHECK_0); flags_ah->obj_at_put(num_entries, s()); num_entries++; } @@ -1669,7 +1673,7 @@ JVM_END bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, TRAPS) { Handle flag_name; if (name() == NULL) { - flag_name = java_lang_String::create_from_str(flag->name, CHECK_false); + flag_name = java_lang_String::create_from_str(flag->_name, CHECK_false); } else { flag_name = name; } @@ -1698,23 +1702,23 @@ bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, global->writeable = flag->is_writeable(); global->external = flag->is_external(); - switch (flag->origin) { - case DEFAULT: + switch (flag->get_origin()) { + case Flag::DEFAULT: global->origin = JMM_VMGLOBAL_ORIGIN_DEFAULT; break; - case COMMAND_LINE: + case Flag::COMMAND_LINE: global->origin = JMM_VMGLOBAL_ORIGIN_COMMAND_LINE; break; - case ENVIRON_VAR: + case Flag::ENVIRON_VAR: global->origin = JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR; break; - case CONFIG_FILE: + case Flag::CONFIG_FILE: global->origin = JMM_VMGLOBAL_ORIGIN_CONFIG_FILE; break; - case MANAGEMENT: + case Flag::MANAGEMENT: global->origin = JMM_VMGLOBAL_ORIGIN_MANAGEMENT; break; - case ERGONOMIC: + case Flag::ERGONOMIC: global->origin = JMM_VMGLOBAL_ORIGIN_ERGONOMIC; break; default: @@ -1781,6 +1785,10 @@ JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env, int num_entries = 0; for (int i = 0; i < nFlags && num_entries < count; i++) { Flag* flag = &Flag::flags[i]; + // Exclude notproduct and develop flags in product builds. + if (flag->is_constant_in_binary()) { + continue; + } // Exclude the locked (diagnostic, experimental) flags if ((flag->is_unlocked() || flag->is_unlocker()) && add_global_entry(env, null_h, &globals[num_entries], flag, THREAD)) { @@ -1813,23 +1821,23 @@ JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value bool succeed; if (flag->is_bool()) { bool bvalue = (new_value.z == JNI_TRUE ? true : false); - succeed = CommandLineFlags::boolAtPut(name, &bvalue, MANAGEMENT); + succeed = CommandLineFlags::boolAtPut(name, &bvalue, Flag::MANAGEMENT); } else if (flag->is_intx()) { intx ivalue = (intx)new_value.j; - succeed = CommandLineFlags::intxAtPut(name, &ivalue, MANAGEMENT); + succeed = CommandLineFlags::intxAtPut(name, &ivalue, Flag::MANAGEMENT); } else if (flag->is_uintx()) { uintx uvalue = (uintx)new_value.j; - succeed = CommandLineFlags::uintxAtPut(name, &uvalue, MANAGEMENT); + succeed = CommandLineFlags::uintxAtPut(name, &uvalue, Flag::MANAGEMENT); } else if (flag->is_uint64_t()) { uint64_t uvalue = (uint64_t)new_value.j; - succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, MANAGEMENT); + succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, Flag::MANAGEMENT); } else if (flag->is_ccstr()) { oop str = JNIHandles::resolve_external_guard(new_value.l); if (str == NULL) { THROW(vmSymbols::java_lang_NullPointerException()); } ccstr svalue = java_lang_String::as_utf8_string(str); - succeed = CommandLineFlags::ccstrAtPut(name, &svalue, MANAGEMENT); + succeed = CommandLineFlags::ccstrAtPut(name, &svalue, Flag::MANAGEMENT); } assert(succeed, "Setting flag should succeed"); JVM_END diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp index 6508cd2086a..46553ba0acd 100644 --- a/hotspot/src/share/vm/services/memoryService.cpp +++ b/hotspot/src/share/vm/services/memoryService.cpp @@ -515,7 +515,7 @@ void MemoryService::oops_do(OopClosure* f) { bool MemoryService::set_verbose(bool verbose) { MutexLocker m(Management_lock); // verbose will be set to the previous value - bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, MANAGEMENT); + bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, Flag::MANAGEMENT); assert(succeed, "Setting PrintGC flag fails"); ClassLoadingService::reset_trace_class_unloading(); @@ -618,4 +618,3 @@ TraceMemoryManagerStats::~TraceMemoryManagerStats() { MemoryService::gc_end(_fullGC, _recordPostGCUsage, _recordAccumulatedGCTime, _recordGCEndTime, _countCollection, _cause); } - From 66672ae1e2f53036948f6e004b1a39800f479358 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Thu, 26 Sep 2013 13:33:02 -0700 Subject: [PATCH 216/293] Added tag hs25-b52 for changeset 54bdf1f141cb --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 3363682c90b..3432d8a4113 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -380,3 +380,4 @@ a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 85072013aad46050a362d10ab78e963121c8014c jdk8-b108 566db1b0e6efca31f181456e54c8911d0192410d hs25-b51 c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109 +58043478c26d4e8bf48700acea5f97aba8b417d4 hs25-b52 From a47169e435b77afda1b2d2dcca67bc82f47b23f1 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Thu, 26 Sep 2013 13:41:34 -0700 Subject: [PATCH 217/293] 8025536: new hotspot build - hs25-b53 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index dc0872c1db3..0786193ff6f 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=52 +HS_BUILD_NUMBER=53 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 From e60e01be017511ef36ce4cead08d7194616969ad Mon Sep 17 00:00:00 2001 From: Sonali Goel Date: Thu, 26 Sep 2013 15:04:15 -0700 Subject: [PATCH 218/293] 8011738: Write test to check for bootstrap attributes for lambda expressions in class file Reviewed-by: mcimadamore --- .../test/tools/javac/lambda/ByteCodeTest.java | 647 ++++++++++++++++++ 1 file changed, 647 insertions(+) create mode 100644 langtools/test/tools/javac/lambda/ByteCodeTest.java diff --git a/langtools/test/tools/javac/lambda/ByteCodeTest.java b/langtools/test/tools/javac/lambda/ByteCodeTest.java new file mode 100644 index 00000000000..792c00d6529 --- /dev/null +++ b/langtools/test/tools/javac/lambda/ByteCodeTest.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8011738 + * @author sogoel + * @summary Code translation test for Lambda expressions, method references + * @run main ByteCodeTest + */ + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.BootstrapMethods_attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.ConstantPool.*; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +public class ByteCodeTest { + + static boolean IS_DEBUG = false; + public static void main(String[] args) { + File classFile = null; + int err = 0; + boolean verifyResult = false; + for(TestCases tc : TestCases.values()) { + classFile = getCompiledFile(tc.name(), tc.srcCode); + if(classFile == null) { // either testFile or classFile was not created + err++; + } else { + verifyResult = verifyClassFileAttributes(classFile, tc); + if(!verifyResult) + System.out.println("Bootstrap class file attributes did not match for " + tc.name()); + } + } + if(err > 0) + throw new RuntimeException("Found " + err + " found"); + else + System.out.println("Test passed"); + } + + private static boolean verifyClassFileAttributes(File classFile, TestCases tc) { + ClassFile c = null; + try { + c = ClassFile.read(classFile); + } catch (IOException | ConstantPoolException e) { + e.printStackTrace(); + } + ConstantPoolVisitor cpv = new ConstantPoolVisitor(c, c.constant_pool.size()); + Map hm = cpv.getBSMMap(); + + List expectedValList = tc.getExpectedArgValues(); + expectedValList.add(tc.bsmSpecifier.specifier); + if(!(hm.values().containsAll(new HashSet(expectedValList)))) { + System.out.println("Values do not match"); + return false; + } + return true; + } + + private static File getCompiledFile(String fname, String srcString) { + File testFile = null, classFile = null; + boolean isTestFileCreated = true; + + try { + testFile = writeTestFile(fname+".java", srcString); + } catch(IOException ioe) { + isTestFileCreated = false; + System.err.println("fail to write" + ioe); + } + + if(isTestFileCreated) { + try { + classFile = compile(testFile); + } catch (Error err) { + System.err.println("fail compile. Source:\n" + srcString); + throw err; + } + } + return classFile; + } + + static File writeTestFile(String fname, String source) throws IOException { + File f = new File(fname); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println(source); + out.close(); + return f; + } + + static File compile(File f) { + int rc = com.sun.tools.javac.Main.compile(new String[] { + "-source", "1.8", "-g", f.getPath() }); + if (rc != 0) + throw new Error("compilation failed. rc=" + rc); + String path = f.getPath(); + return new File(path.substring(0, path.length() - 5) + ".class"); + } + + static void debugln(String str) { + if(IS_DEBUG) + System.out.println(str); + } + + enum BSMSpecifier { + SPECIFIER1("REF_invokeStatic java/lang/invoke/LambdaMetafactory metaFactory " + + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;" + + "Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)" + + "Ljava/lang/invoke/CallSite;"), + SPECIFIER2("REF_invokeStatic java/lang/invoke/LambdaMetafactory altMetaFactory " + + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;" + + "[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"); + + String specifier; + private BSMSpecifier(String specifier) { + this.specifier = specifier; + } + } + + enum TestCases { + // Single line lambda expression + TC1("class TC1 {\n" + + " public static void main(String[] args) {\n" + + " Object o = (Runnable) () -> { System.out.println(\"hi\");};\n" + + " }\n"+ + "}", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface java/lang/Runnable run ()V"); + valList.add("REF_invokeStatic TC1 lambda$0 ()V"); + valList.add("()V"); + return valList; + } + }, + + // Lambda expression in a for loop + TC2("import java.util.*;\n" + + "public class TC2 {\n" + + " void TC2_test() {\n" + + " List list = new ArrayList<>();\n" + + " list.add(\"A\");\n" + + " list.add(\"B\");\n" + + " list.stream().forEach( s -> { System.out.println(s); } );\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new TC2().TC2_test();\n" + + " }\n" + + "}", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface java/util/function/Consumer accept (Ljava/lang/Object;)V"); + valList.add("REF_invokeStatic TC2 lambda$0 (Ljava/lang/String;)V"); + valList.add("(Ljava/lang/String;)V"); + return valList; + } + }, + + // Lambda initializer + TC3("class TC3 {\n" + + " interface SAM {\n" + + " void m(int i);\n" + + " }\n" + + " SAM lambda_03 = (int pos) -> { };\n" + + "}", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface TC3$SAM m (I)V"); + valList.add("REF_invokeStatic TC3 lambda$0 (I)V"); + valList.add("(I)V"); + return valList; + } + }, + + // Array initializer + TC4("class TC4 {\n" + + " interface Block {\n" + + " void m(T t);\n" + + " }\n" + + " void test1() {\n" + + " Block[] arr1 = { t -> { }, t -> { } };\n" + + " }\n" + + "}", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface TC4$Block m (Ljava/lang/Object;)V"); + valList.add("REF_invokeStatic TC4 lambda$0 (Ljava/lang/Object;)V"); + valList.add("(Ljava/lang/Object;)V"); + valList.add("REF_invokeStatic TC4 lambda$1 (Ljava/lang/Object;)V"); + return valList; + } + }, + + //Lambda expression as a method arg + TC5("class TC5 {\n"+ + " interface MapFun { R m( T n); }\n" + + " void meth( MapFun mf ) {\n" + + " assert( mf.m(\"four\") == 4);\n" + + " }\n"+ + " void test(Integer i) {\n" + + " meth(s -> { Integer len = s.length(); return len; } );\n" + + " }\n"+ + "}", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface TC5$MapFun m (Ljava/lang/Object;)Ljava/lang/Object;"); + valList.add("REF_invokeStatic TC5 lambda$0 (Ljava/lang/String;)Ljava/lang/Integer;"); + valList.add("(Ljava/lang/String;)Ljava/lang/Integer;"); + return valList; + } + }, + + //Inner class of Lambda expression + TC6("class TC6 {\n" + + " interface MapFun { R m( T n); }\n" + + " MapFun,String> cs;\n" + + " void test() {\n" + + " cs = c -> {\n" + + " class innerClass {\n" + + " Class icc;\n" + + " innerClass(Class _c) { icc = _c; }\n" + + " String getString() { return icc.toString(); }\n" + + " }\n" + + " return new innerClass(c).getString();\n"+ + " };\n" + + " }\n" + + "}\n", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface TC6$MapFun m (Ljava/lang/Object;)Ljava/lang/Object;"); + valList.add("REF_invokeSpecial TC6 lambda$0 (Ljava/lang/Class;)Ljava/lang/String;"); + valList.add("(Ljava/lang/Class;)Ljava/lang/String;"); + return valList; + } + }, + + // Method reference + TC7("class TC7 {\n" + + " static interface SAM {\n" + + " void m(Integer i);\n" + + " }\n" + + " void m(Integer i) {}\n" + + " SAM s = this::m;\n" + + "}\n", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface TC7$SAM m (Ljava/lang/Integer;)V"); + valList.add("REF_invokeVirtual TC7 m (Ljava/lang/Integer;)V"); + valList.add("(Ljava/lang/Integer;)V"); + return valList; + } + }, + + // Constructor reference + TC8("public class TC8 {\n" + + " static interface A {Fee m();}\n" + + " static class Fee {\n" + + " private T t;\n" + + " public Fee() {}\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " A a = Fee::new; \n" + + " }\n" + + "}\n", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface TC8$A m ()LTC8$Fee;"); + valList.add("REF_newInvokeSpecial TC8$Fee ()V"); + valList.add("()LTC8$Fee;"); + return valList; + } + }, + + // Recursive lambda expression + TC9("class TC9 {\n" + + " interface Recursive { T apply(R n); };\n" + + " Recursive factorial;\n" + + " void test(Integer j) {\n" + + " factorial = i -> { return i == 0 ? 1 : i * factorial.apply( i - 1 ); };\n" + + " }\n" + + "}\n", BSMSpecifier.SPECIFIER1) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeInterface TC9$Recursive apply (Ljava/lang/Object;)Ljava/lang/Object;"); + valList.add("REF_invokeSpecial TC9 lambda$0 (Ljava/lang/Integer;)Ljava/lang/Integer;"); + valList.add("(Ljava/lang/Integer;)Ljava/lang/Integer;"); + return valList; + } + }, + + //Serializable Lambda + TC10("import java.io.Serializable;\n" + + "class TC10 {\n" + + " interface Foo { int m(); }\n" + + " public static void main(String[] args) {\n" + + " Foo f1 = (Foo & Serializable)() -> 3;\n" + + " }\n" + + "}\n", BSMSpecifier.SPECIFIER2) { + + @Override + List getExpectedArgValues() { + List valList = new ArrayList<>(); + valList.add("REF_invokeStatic java/lang/invoke/LambdaMetafactory altMetaFactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"); + valList.add("REF_invokeInterface TC10$Foo m ()I"); + valList.add("REF_invokeStatic TC10 lambda$main$3231c38a$0 ()I"); + valList.add("()I"); + valList.add("1"); + return valList; + } + }; + + String srcCode; + BSMSpecifier bsmSpecifier; + + TestCases(String src, BSMSpecifier bsmSpecifier) { + this.srcCode = src; + // By default, all test cases will have bootstrap method specifier as Lambda.MetaFactory + // For serializable lambda test cases, bootstrap method specifier changed to altMetaFactory + this.bsmSpecifier = bsmSpecifier; + } + + List getExpectedArgValues() { + return null; + } + + void setSrcCode(String src) { + srcCode = src; + } + } + + static class ConstantPoolVisitor implements ConstantPool.Visitor { + final List slist; + final ClassFile cf; + final ConstantPool cfpool; + final Map bsmMap; + + + public ConstantPoolVisitor(ClassFile cf, int size) { + slist = new ArrayList<>(size); + for (int i = 0 ; i < size; i++) { + slist.add(null); + } + this.cf = cf; + this.cfpool = cf.constant_pool; + bsmMap = readBSM(); + } + + public Map getBSMMap() { + return Collections.unmodifiableMap(bsmMap); + } + + public String visit(CPInfo c, int index) { + return c.accept(this, index); + } + + private Map readBSM() { + BootstrapMethods_attribute bsmAttr = + (BootstrapMethods_attribute) cf.getAttribute(Attribute.BootstrapMethods); + if (bsmAttr != null) { + Map out = + new HashMap<>(bsmAttr.bootstrap_method_specifiers.length); + for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsms : + bsmAttr.bootstrap_method_specifiers) { + int index = bsms.bootstrap_method_ref; + try { + String value = slist.get(index); + if (value == null) { + value = visit(cfpool.get(index), index); + debugln("[SG]: index " + index); + debugln("[SG]: value " + value); + slist.set(index, value); + out.put(index, value); + } + for (int idx : bsms.bootstrap_arguments) { + value = slist.get(idx); + if (value == null) { + value = visit(cfpool.get(idx), idx); + debugln("[SG]: idx " + idx); + debugln("[SG]: value " + value); + slist.set(idx, value); + out.put(idx, value); + } + } + } catch (InvalidIndex ex) { + ex.printStackTrace(); + } + } + return out; + } + return new HashMap<>(0); + } + + @Override + public String visitClass(CONSTANT_Class_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.name_index), c.name_index); + slist.set(p, value); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitDouble(CONSTANT_Double_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + value = Double.toString(c.value); + slist.set(p, value); + } + return value; + } + + @Override + public String visitFieldref(CONSTANT_Fieldref_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.class_index), c.class_index); + value = value.concat(" " + visit(cfpool.get(c.name_and_type_index), + c.name_and_type_index)); + slist.set(p, value); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitFloat(CONSTANT_Float_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + value = Float.toString(c.value); + slist.set(p, value); + } + return value; + } + + @Override + public String visitInteger(CONSTANT_Integer_info cnstnt, Integer p) { + + String value = slist.get(p); + if (value == null) { + value = Integer.toString(cnstnt.value); + slist.set(p, value); + } + return value; + } + + @Override + public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info c, + Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.class_index), c.class_index); + value = value.concat(" " + + visit(cfpool.get(c.name_and_type_index), + c.name_and_type_index)); + slist.set(p, value); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = bsmMap.get(c.bootstrap_method_attr_index) + " " + + visit(cfpool.get(c.name_and_type_index), c.name_and_type_index); + slist.set(p, value); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitLong(CONSTANT_Long_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + value = Long.toString(c.value); + slist.set(p, value); + } + return value; + } + + @Override + public String visitNameAndType(CONSTANT_NameAndType_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.name_index), c.name_index); + value = value.concat(" " + + visit(cfpool.get(c.type_index), c.type_index)); + slist.set(p, value); + } catch (InvalidIndex ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitMethodref(CONSTANT_Methodref_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.class_index), c.class_index); + value = value.concat(" " + + visit(cfpool.get(c.name_and_type_index), + c.name_and_type_index)); + slist.set(p, value); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitMethodHandle(CONSTANT_MethodHandle_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = c.reference_kind.name(); + value = value.concat(" " + + visit(cfpool.get(c.reference_index), c.reference_index)); + slist.set(p, value); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitMethodType(CONSTANT_MethodType_info c, Integer p) { + + String value = slist.get(p); + if (value == null) { + try { + value = visit(cfpool.get(c.descriptor_index), c.descriptor_index); + slist.set(p, value); + } catch (ConstantPoolException ex) { + ex.printStackTrace(); + } + } + return value; + } + + @Override + public String visitString(CONSTANT_String_info c, Integer p) { + + try { + String value = slist.get(p); + if (value == null) { + value = c.getString(); + slist.set(p, value); + } + return value; + } catch (ConstantPoolException ex) { + throw new RuntimeException("Fatal error", ex); + } + } + + @Override + public String visitUtf8(CONSTANT_Utf8_info cnstnt, Integer p) { + + String value = slist.get(p); + if (value == null) { + value = cnstnt.value; + slist.set(p, value); + } + return value; + } + } +} + From d0ef16f2c330f3e9b7d563b7286f2668ec0c8eb3 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Thu, 26 Sep 2013 15:06:39 -0700 Subject: [PATCH 219/293] 7092764: java.awt.font.TransformAttribute.equals(null) throws NPE Reviewed-by: jgodinez, jchen --- .../java/awt/font/TransformAttribute.java | 16 ++--- .../TransformEqualityTest.java | 60 +++++++++++++++++++ 2 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 jdk/test/java/awt/font/TransformAttribute/TransformEqualityTest.java diff --git a/jdk/src/share/classes/java/awt/font/TransformAttribute.java b/jdk/src/share/classes/java/awt/font/TransformAttribute.java index f66da12041d..6156b4df7f3 100644 --- a/jdk/src/share/classes/java/awt/font/TransformAttribute.java +++ b/jdk/src/share/classes/java/awt/font/TransformAttribute.java @@ -141,14 +141,16 @@ public final class TransformAttribute implements Serializable { * @since 1.6 */ public boolean equals(Object rhs) { - try { - TransformAttribute that = (TransformAttribute)rhs; - if (transform == null) { - return that.transform == null; + if (rhs != null) { + try { + TransformAttribute that = (TransformAttribute)rhs; + if (transform == null) { + return that.transform == null; + } + return transform.equals(that.transform); + } + catch (ClassCastException e) { } - return transform.equals(that.transform); - } - catch (ClassCastException e) { } return false; } diff --git a/jdk/test/java/awt/font/TransformAttribute/TransformEqualityTest.java b/jdk/test/java/awt/font/TransformAttribute/TransformEqualityTest.java new file mode 100644 index 00000000000..5cbc9078796 --- /dev/null +++ b/jdk/test/java/awt/font/TransformAttribute/TransformEqualityTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary test equals method + * @bug 7092764 + */ + +import java.awt.font.TransformAttribute; +import java.awt.geom.AffineTransform; + +public class TransformEqualityTest { + + public static void main(String[] args) { + AffineTransform tx1 = new AffineTransform(1, 0, 1, 1, 0, 0); + AffineTransform tx2 = new AffineTransform(1, 0, 1, 1, 0, 0); + AffineTransform tx3 = new AffineTransform(2, 0, 1, 1, 0, 0); + TransformAttribute ta1a = new TransformAttribute(tx1); + TransformAttribute ta1b = new TransformAttribute(tx1); + TransformAttribute ta2 = new TransformAttribute(tx2); + TransformAttribute ta3 = new TransformAttribute(tx3); + if (ta1a.equals(null)) { + throw new RuntimeException("should not be equal to null."); + } + if (!ta1a.equals(ta1a)) { + throw new RuntimeException("(1) should be equal."); + } + if (!ta1a.equals(ta1b)) { + throw new RuntimeException("(2) should be equal."); + } + if (!ta1a.equals(ta2)) { + throw new RuntimeException("(3) should be equal."); + } + if (ta2.equals(ta3)) { + throw new RuntimeException("should be different."); + } + } +} + From 00c37e4e9e49b61fdf024ba638c7bf205d91ac5f Mon Sep 17 00:00:00 2001 From: Clemens Eisserer Date: Thu, 26 Sep 2013 16:30:38 -0700 Subject: [PATCH 220/293] 8024895: xrender MaskImage cache isn't accounting for change in alpha Reviewed-by: prr, jchen --- .../classes/sun/java2d/xr/XRMaskImage.java | 5 +- .../java/awt/image/DrawImage/EABlitTest.java | 94 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/image/DrawImage/EABlitTest.java diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRMaskImage.java b/jdk/src/solaris/classes/sun/java2d/xr/XRMaskImage.java index 7c3bb297e1a..cc062779957 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/XRMaskImage.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRMaskImage.java @@ -45,6 +45,7 @@ public class XRMaskImage { int blitMaskPicture; int lastMaskWidth = 0; int lastMaskHeight = 0; + int lastEA = -1; AffineTransform lastMaskTransform; XRCompositeManager xrMgr; @@ -82,13 +83,15 @@ public class XRMaskImage { lastMaskTransform = maskTX; } - if (lastMaskWidth != maskWidth || lastMaskHeight != maskHeight) { + int currentEA = xrMgr.getAlphaColor().getAlpha(); + if (lastMaskWidth != maskWidth || lastMaskHeight != maskHeight || lastEA != currentEA) { //Only clear mask, if previous mask area is larger than new one, otherwise simple overpaint it if (lastMaskWidth > maskWidth || lastMaskHeight > maskHeight) { con.renderRectangle(blitMaskPicture, XRUtils.PictOpClear, XRColor.NO_ALPHA, 0, 0, lastMaskWidth, lastMaskHeight); } con.renderRectangle(blitMaskPicture, XRUtils.PictOpSrc, xrMgr.getAlphaColor(), 0, 0, maskWidth, maskHeight); + lastEA = currentEA; } lastMaskWidth = maskWidth; diff --git a/jdk/test/java/awt/image/DrawImage/EABlitTest.java b/jdk/test/java/awt/image/DrawImage/EABlitTest.java new file mode 100644 index 00000000000..6240ce716d6 --- /dev/null +++ b/jdk/test/java/awt/image/DrawImage/EABlitTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.*; +import java.awt.image.*; +import java.util.*; +import javax.swing.*; + +/** + * @test + * @bug 8024895 + * @summary tests if changing extra alpha values are honored for transformed blits + * @author ceisserer + */ +public class EABlitTest extends Frame { + protected void test() { + BufferedImage srcImg = createSrcImage(); + Image dstImg = getGraphicsConfiguration().createCompatibleVolatileImage(20, 50); + + //be over-cautious and render twice to avoid BI caching issues + renderToVI(srcImg, dstImg); + renderToVI(srcImg, dstImg); + + BufferedImage validationImg = new BufferedImage(20, 50, BufferedImage.TYPE_INT_RGB); + Graphics2D valG = (Graphics2D) validationImg.getGraphics(); + valG.drawImage(dstImg, 0, 0, null); + + //Loop over all pixel, and count the different pixel values encountered. + TreeSet colorCntSet = new TreeSet<>(); + for (int x=0; x < validationImg.getWidth(); x++) { + for (int y=0; y < validationImg.getHeight(); y++) { + int rgb = validationImg.getRGB(x, y); + colorCntSet.add(rgb); + } + } + + //Check if we encountered 3 different color values in total + if (colorCntSet.size() == 3) { + System.out.println("Passed!"); + } else { + throw new RuntimeException("Test FAILED!"); + } + } + + protected void renderToVI(BufferedImage src, Image dst) { + Graphics2D g = (Graphics2D) dst.getGraphics(); + + g.setColor(Color.WHITE); + g.fillRect(0, 0, 50, 50); + g.rotate(0.5f); + g.setRenderingHint(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_QUALITY); + + g.setComposite(AlphaComposite.SrcOver.derive(1f)); + g.drawImage(src, 10, 10, null); + + g.setComposite(AlphaComposite.SrcOver.derive(0.5f)); + g.drawImage(src, 20, 20, null); + } + + protected BufferedImage createSrcImage() { + BufferedImage bi = new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB); + Graphics2D g = (Graphics2D) bi.getGraphics(); + g.setColor(Color.YELLOW); + g.fillRect(0, 0, 10, 10); + return bi; + } + + public static void main(String[] args) { + new EABlitTest().test(); + } +} From 441f1d74cf4f9d0e344d0f40d1d09f9b63c6dc00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rickard=20B=C3=A4ckman?= Date: Fri, 27 Sep 2013 08:39:19 +0200 Subject: [PATCH 221/293] 8024924: Intrinsify java.lang.Math.addExact Reviewed-by: kvn, twisti --- hotspot/src/cpu/sparc/vm/sparc.ad | 32 ++++ hotspot/src/cpu/x86/vm/x86_32.ad | 47 ++++++ hotspot/src/cpu/x86/vm/x86_64.ad | 40 +++++ hotspot/src/share/vm/adlc/adlparse.cpp | 14 +- hotspot/src/share/vm/adlc/archDesc.cpp | 2 + hotspot/src/share/vm/adlc/formssel.cpp | 22 ++- hotspot/src/share/vm/adlc/formssel.hpp | 8 +- hotspot/src/share/vm/adlc/output_h.cpp | 12 ++ hotspot/src/share/vm/classfile/vmSymbols.hpp | 5 + hotspot/src/share/vm/opto/c2_globals.hpp | 4 +- hotspot/src/share/vm/opto/classes.cpp | 1 + hotspot/src/share/vm/opto/classes.hpp | 3 + hotspot/src/share/vm/opto/ifnode.cpp | 1 + hotspot/src/share/vm/opto/lcm.cpp | 7 + hotspot/src/share/vm/opto/library_call.cpp | 53 +++++++ hotspot/src/share/vm/opto/loopTransform.cpp | 3 + hotspot/src/share/vm/opto/loopopts.cpp | 3 +- hotspot/src/share/vm/opto/matcher.cpp | 1 + hotspot/src/share/vm/opto/matcher.hpp | 3 + hotspot/src/share/vm/opto/mathexactnode.cpp | 143 ++++++++++++++++++ hotspot/src/share/vm/opto/mathexactnode.hpp | 81 ++++++++++ hotspot/src/share/vm/opto/multnode.cpp | 19 ++- hotspot/src/share/vm/opto/node.hpp | 3 + hotspot/src/share/vm/opto/subnode.cpp | 4 +- hotspot/src/share/vm/opto/subnode.hpp | 6 +- hotspot/src/share/vm/opto/type.cpp | 6 + hotspot/src/share/vm/opto/type.hpp | 1 + hotspot/src/share/vm/runtime/vmStructs.cpp | 4 + .../intrinsics/mathexact/CondTest.java | 59 ++++++++ .../intrinsics/mathexact/ConstantTest.java | 47 ++++++ .../intrinsics/mathexact/LoadTest.java | 55 +++++++ .../mathexact/LoopDependentTest.java | 48 ++++++ .../intrinsics/mathexact/NonConstantTest.java | 48 ++++++ .../compiler/intrinsics/mathexact/Verify.java | 68 +++++++++ 34 files changed, 830 insertions(+), 23 deletions(-) create mode 100644 hotspot/src/share/vm/opto/mathexactnode.cpp create mode 100644 hotspot/src/share/vm/opto/mathexactnode.hpp create mode 100644 hotspot/test/compiler/intrinsics/mathexact/CondTest.java create mode 100644 hotspot/test/compiler/intrinsics/mathexact/ConstantTest.java create mode 100644 hotspot/test/compiler/intrinsics/mathexact/LoadTest.java create mode 100644 hotspot/test/compiler/intrinsics/mathexact/LoopDependentTest.java create mode 100644 hotspot/test/compiler/intrinsics/mathexact/NonConstantTest.java create mode 100644 hotspot/test/compiler/intrinsics/mathexact/Verify.java diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad index 58c113a0c1a..06235820bb8 100644 --- a/hotspot/src/cpu/sparc/vm/sparc.ad +++ b/hotspot/src/cpu/sparc/vm/sparc.ad @@ -2018,6 +2018,15 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() { return L7_REGP_mask(); } +const RegMask Matcher::mathExactI_result_proj_mask() { + return G1_REGI_mask(); +} + +const RegMask Matcher::mathExactI_flags_proj_mask() { + return INT_FLAGS_mask(); +} + + %} @@ -4245,12 +4254,16 @@ operand cmpOp() %{ greater_equal(0xB); less_equal(0x2); greater(0xA); + overflow(0x7); + no_overflow(0xF); %} %} // Comparison Op, unsigned operand cmpOpU() %{ match(Bool); + predicate(n->as_Bool()->_test._test != BoolTest::overflow && + n->as_Bool()->_test._test != BoolTest::no_overflow); format %{ "u" %} interface(COND_INTER) %{ @@ -4260,12 +4273,16 @@ operand cmpOpU() %{ greater_equal(0xD); less_equal(0x4); greater(0xC); + overflow(0x7); + no_overflow(0xF); %} %} // Comparison Op, pointer (same as unsigned) operand cmpOpP() %{ match(Bool); + predicate(n->as_Bool()->_test._test != BoolTest::overflow && + n->as_Bool()->_test._test != BoolTest::no_overflow); format %{ "p" %} interface(COND_INTER) %{ @@ -4275,12 +4292,16 @@ operand cmpOpP() %{ greater_equal(0xD); less_equal(0x4); greater(0xC); + overflow(0x7); + no_overflow(0xF); %} %} // Comparison Op, branch-register encoding operand cmpOp_reg() %{ match(Bool); + predicate(n->as_Bool()->_test._test != BoolTest::overflow && + n->as_Bool()->_test._test != BoolTest::no_overflow); format %{ "" %} interface(COND_INTER) %{ @@ -4290,12 +4311,16 @@ operand cmpOp_reg() %{ greater_equal(0x7); less_equal (0x2); greater (0x6); + overflow(0x7); // not supported + no_overflow(0xF); // not supported %} %} // Comparison Code, floating, unordered same as less operand cmpOpF() %{ match(Bool); + predicate(n->as_Bool()->_test._test != BoolTest::overflow && + n->as_Bool()->_test._test != BoolTest::no_overflow); format %{ "fl" %} interface(COND_INTER) %{ @@ -4305,12 +4330,17 @@ operand cmpOpF() %{ greater_equal(0xB); less_equal(0xE); greater(0x6); + + overflow(0x7); // not supported + no_overflow(0xF); // not supported %} %} // Used by long compare operand cmpOp_commute() %{ match(Bool); + predicate(n->as_Bool()->_test._test != BoolTest::overflow && + n->as_Bool()->_test._test != BoolTest::no_overflow); format %{ "" %} interface(COND_INTER) %{ @@ -4320,6 +4350,8 @@ operand cmpOp_commute() %{ greater_equal(0x2); less_equal(0xB); greater(0x3); + overflow(0x7); + no_overflow(0xF); %} %} diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad index 316ebe2911d..659d4e70faa 100644 --- a/hotspot/src/cpu/x86/vm/x86_32.ad +++ b/hotspot/src/cpu/x86/vm/x86_32.ad @@ -1534,6 +1534,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() { return EBP_REG_mask(); } +const RegMask Matcher::mathExactI_result_proj_mask() { + return EAX_REG_mask(); +} + +const RegMask Matcher::mathExactI_flags_proj_mask() { + return INT_FLAGS_mask(); +} + // Returns true if the high 32 bits of the value is known to be zero. bool is_operand_hi32_zero(Node* n) { int opc = n->Opcode(); @@ -4922,6 +4930,8 @@ operand cmpOp() %{ greater_equal(0xD, "ge"); less_equal(0xE, "le"); greater(0xF, "g"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -4939,6 +4949,8 @@ operand cmpOpU() %{ greater_equal(0x3, "nb"); less_equal(0x6, "be"); greater(0x7, "nbe"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -4957,6 +4969,8 @@ operand cmpOpUCF() %{ greater_equal(0x3, "nb"); less_equal(0x6, "be"); greater(0x7, "nbe"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -4974,6 +4988,8 @@ operand cmpOpUCF2() %{ greater_equal(0x3, "nb"); less_equal(0x6, "be"); greater(0x7, "nbe"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -4981,6 +4997,8 @@ operand cmpOpUCF2() %{ operand cmpOp_fcmov() %{ match(Bool); + predicate(n->as_Bool()->_test._test != BoolTest::overflow && + n->as_Bool()->_test._test != BoolTest::no_overflow); format %{ "" %} interface(COND_INTER) %{ equal (0x0C8); @@ -4989,6 +5007,8 @@ operand cmpOp_fcmov() %{ greater_equal(0x1C0); less_equal (0x0D0); greater (0x1D0); + overflow(0x0, "o"); // not really supported by the instruction + no_overflow(0x1, "no"); // not really supported by the instruction %} %} @@ -5004,6 +5024,8 @@ operand cmpOp_commute() %{ greater_equal(0xE, "le"); less_equal(0xD, "ge"); greater(0xC, "l"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -7496,6 +7518,31 @@ instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{ //----------Arithmetic Instructions-------------------------------------------- //----------Addition Instructions---------------------------------------------- + +instruct addExactI_rReg(eAXRegI dst, rRegI src, eFlagsReg cr) +%{ + match(AddExactI dst src); + effect(DEF cr); + + format %{ "ADD $dst, $src\t# addExact int" %} + ins_encode %{ + __ addl($dst$$Register, $src$$Register); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct addExactI_rReg_imm(eAXRegI dst, immI src, eFlagsReg cr) +%{ + match(AddExactI dst src); + effect(DEF cr); + + format %{ "ADD $dst, $src\t# addExact int" %} + ins_encode %{ + __ addl($dst$$Register, $src$$constant); + %} + ins_pipe(ialu_reg_reg); +%} + // Integer Addition Instructions instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ match(Set dst (AddI dst src)); diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad index ed13b3da1d1..abfd0f68125 100644 --- a/hotspot/src/cpu/x86/vm/x86_64.ad +++ b/hotspot/src/cpu/x86/vm/x86_64.ad @@ -1649,6 +1649,14 @@ const RegMask Matcher::method_handle_invoke_SP_save_mask() { return PTR_RBP_REG_mask(); } +const RegMask Matcher::mathExactI_result_proj_mask() { + return INT_RAX_REG_mask(); +} + +const RegMask Matcher::mathExactI_flags_proj_mask() { + return INT_FLAGS_mask(); +} + %} //----------ENCODING BLOCK----------------------------------------------------- @@ -4133,6 +4141,8 @@ operand cmpOp() greater_equal(0xD, "ge"); less_equal(0xE, "le"); greater(0xF, "g"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -4151,6 +4161,8 @@ operand cmpOpU() greater_equal(0x3, "nb"); less_equal(0x6, "be"); greater(0x7, "nbe"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -4170,6 +4182,8 @@ operand cmpOpUCF() %{ greater_equal(0x3, "nb"); less_equal(0x6, "be"); greater(0x7, "nbe"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -4187,6 +4201,8 @@ operand cmpOpUCF2() %{ greater_equal(0x3, "nb"); less_equal(0x6, "be"); greater(0x7, "nbe"); + overflow(0x0, "o"); + no_overflow(0x1, "no"); %} %} @@ -6922,6 +6938,30 @@ instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ //----------Arithmetic Instructions-------------------------------------------- //----------Addition Instructions---------------------------------------------- +instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) +%{ + match(AddExactI dst src); + effect(DEF cr); + + format %{ "addl $dst, $src\t# addExact int" %} + ins_encode %{ + __ addl($dst$$Register, $src$$Register); + %} + ins_pipe(ialu_reg_reg); +%} + +instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) +%{ + match(AddExactI dst src); + effect(DEF cr); + + format %{ "addl $dst, $src\t# addExact int" %} + ins_encode %{ + __ addl($dst$$Register, $src$$constant); + %} + ins_pipe(ialu_reg_reg); +%} + instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) %{ match(Set dst (AddI dst src)); diff --git a/hotspot/src/share/vm/adlc/adlparse.cpp b/hotspot/src/share/vm/adlc/adlparse.cpp index 04fb735c38c..8704c68da69 100644 --- a/hotspot/src/share/vm/adlc/adlparse.cpp +++ b/hotspot/src/share/vm/adlc/adlparse.cpp @@ -3395,12 +3395,16 @@ Interface *ADLParser::cond_interface_parse(void) { char *greater_equal; char *less_equal; char *greater; + char *overflow; + char *no_overflow; const char *equal_format = "eq"; const char *not_equal_format = "ne"; const char *less_format = "lt"; const char *greater_equal_format = "ge"; const char *less_equal_format = "le"; const char *greater_format = "gt"; + const char *overflow_format = "o"; + const char *no_overflow_format = "no"; if (_curchar != '%') { parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n"); @@ -3437,6 +3441,12 @@ Interface *ADLParser::cond_interface_parse(void) { else if ( strcmp(field,"greater") == 0 ) { greater = interface_field_parse(&greater_format); } + else if ( strcmp(field,"overflow") == 0 ) { + overflow = interface_field_parse(&overflow_format); + } + else if ( strcmp(field,"no_overflow") == 0 ) { + no_overflow = interface_field_parse(&no_overflow_format); + } else { parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n"); return NULL; @@ -3455,7 +3465,9 @@ Interface *ADLParser::cond_interface_parse(void) { less, less_format, greater_equal, greater_equal_format, less_equal, less_equal_format, - greater, greater_format); + greater, greater_format, + overflow, overflow_format, + no_overflow, no_overflow_format); return inter; } diff --git a/hotspot/src/share/vm/adlc/archDesc.cpp b/hotspot/src/share/vm/adlc/archDesc.cpp index 412a728228a..9447af252fc 100644 --- a/hotspot/src/share/vm/adlc/archDesc.cpp +++ b/hotspot/src/share/vm/adlc/archDesc.cpp @@ -1192,6 +1192,8 @@ void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) { || strcmp(idealName,"CmpF") == 0 || strcmp(idealName,"FastLock") == 0 || strcmp(idealName,"FastUnlock") == 0 + || strcmp(idealName,"AddExactI") == 0 + || strcmp(idealName,"FlagsProj") == 0 || strcmp(idealName,"Bool") == 0 || strcmp(idealName,"Binary") == 0 ) { // Removed ConI from the must_clone list. CPUs that cannot use diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp index 3d4a562e432..f3048a1e5df 100644 --- a/hotspot/src/share/vm/adlc/formssel.cpp +++ b/hotspot/src/share/vm/adlc/formssel.cpp @@ -2757,14 +2757,18 @@ CondInterface::CondInterface(const char* equal, const char* equal_format const char* less, const char* less_format, const char* greater_equal, const char* greater_equal_format, const char* less_equal, const char* less_equal_format, - const char* greater, const char* greater_format) + const char* greater, const char* greater_format, + const char* overflow, const char* overflow_format, + const char* no_overflow, const char* no_overflow_format) : Interface("COND_INTER"), _equal(equal), _equal_format(equal_format), _not_equal(not_equal), _not_equal_format(not_equal_format), _less(less), _less_format(less_format), _greater_equal(greater_equal), _greater_equal_format(greater_equal_format), _less_equal(less_equal), _less_equal_format(less_equal_format), - _greater(greater), _greater_format(greater_format) { + _greater(greater), _greater_format(greater_format), + _overflow(overflow), _overflow_format(overflow_format), + _no_overflow(no_overflow), _no_overflow_format(no_overflow_format) { } CondInterface::~CondInterface() { // not owner of any character arrays @@ -2777,12 +2781,14 @@ void CondInterface::dump() { // Write info to output files void CondInterface::output(FILE *fp) { Interface::output(fp); - if ( _equal != NULL ) fprintf(fp," equal == %s\n", _equal); - if ( _not_equal != NULL ) fprintf(fp," not_equal == %s\n", _not_equal); - if ( _less != NULL ) fprintf(fp," less == %s\n", _less); - if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal); - if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal); - if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater); + if ( _equal != NULL ) fprintf(fp," equal == %s\n", _equal); + if ( _not_equal != NULL ) fprintf(fp," not_equal == %s\n", _not_equal); + if ( _less != NULL ) fprintf(fp," less == %s\n", _less); + if ( _greater_equal != NULL ) fprintf(fp," greater_equal == %s\n", _greater_equal); + if ( _less_equal != NULL ) fprintf(fp," less_equal == %s\n", _less_equal); + if ( _greater != NULL ) fprintf(fp," greater == %s\n", _greater); + if ( _overflow != NULL ) fprintf(fp," overflow == %s\n", _overflow); + if ( _no_overflow != NULL ) fprintf(fp," no_overflow == %s\n", _no_overflow); // fprintf(fp,"\n"); } diff --git a/hotspot/src/share/vm/adlc/formssel.hpp b/hotspot/src/share/vm/adlc/formssel.hpp index fa3e9ff8f48..3bc22b8e269 100644 --- a/hotspot/src/share/vm/adlc/formssel.hpp +++ b/hotspot/src/share/vm/adlc/formssel.hpp @@ -798,12 +798,16 @@ public: const char *_greater_equal; const char *_less_equal; const char *_greater; + const char *_overflow; + const char *_no_overflow; const char *_equal_format; const char *_not_equal_format; const char *_less_format; const char *_greater_equal_format; const char *_less_equal_format; const char *_greater_format; + const char *_overflow_format; + const char *_no_overflow_format; // Public Methods CondInterface(const char* equal, const char* equal_format, @@ -811,7 +815,9 @@ public: const char* less, const char* less_format, const char* greater_equal, const char* greater_equal_format, const char* less_equal, const char* less_equal_format, - const char* greater, const char* greater_format); + const char* greater, const char* greater_format, + const char* overflow, const char* overflow_format, + const char* no_overflow, const char* no_overflow_format); ~CondInterface(); void dump(); diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp index 3fdaf39e8f1..0b01d06dc31 100644 --- a/hotspot/src/share/vm/adlc/output_h.cpp +++ b/hotspot/src/share/vm/adlc/output_h.cpp @@ -388,6 +388,8 @@ static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) { fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format); fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format); fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format); + fprintf(fp, " else if( _c%d == BoolTest::overflow ) st->print(\"%s\");\n",i,cond->_overflow_format); + fprintf(fp, " else if( _c%d == BoolTest::no_overflow ) st->print(\"%s\");\n",i,cond->_no_overflow_format); } // Output code that dumps constant values, increment "i" if type is constant @@ -1208,6 +1210,8 @@ void ArchDesc::declareClasses(FILE *fp) { fprintf(fp," case BoolTest::ne : return not_equal();\n"); fprintf(fp," case BoolTest::le : return less_equal();\n"); fprintf(fp," case BoolTest::ge : return greater_equal();\n"); + fprintf(fp," case BoolTest::overflow : return overflow();\n"); + fprintf(fp," case BoolTest::no_overflow: return no_overflow();\n"); fprintf(fp," default : ShouldNotReachHere(); return 0;\n"); fprintf(fp," }\n"); fprintf(fp," };\n"); @@ -1373,6 +1377,14 @@ void ArchDesc::declareClasses(FILE *fp) { if( greater != NULL ) { define_oper_interface(fp, *oper, _globalNames, "greater", greater); } + const char *overflow = cInterface->_overflow; + if( overflow != NULL ) { + define_oper_interface(fp, *oper, _globalNames, "overflow", overflow); + } + const char *no_overflow = cInterface->_no_overflow; + if( no_overflow != NULL ) { + define_oper_interface(fp, *oper, _globalNames, "no_overflow", no_overflow); + } } // end Conditional Interface // Check if it is a Constant Interface else if (oper->_interface->is_ConstInterface() != NULL ) { diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index f1758f86654..941fde568bb 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -631,6 +631,10 @@ do_name(log_name,"log") do_name(log10_name,"log10") do_name(pow_name,"pow") \ do_name(exp_name,"exp") do_name(min_name,"min") do_name(max_name,"max") \ \ + do_name(addExact_name,"addExact") \ + do_name(subtractExact_name,"subtractExact") \ + do_name(multiplyExact_name,"multiplyExact") \ + \ do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \ do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \ do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \ @@ -643,6 +647,7 @@ do_intrinsic(_dexp, java_lang_Math, exp_name, double_double_signature, F_S) \ do_intrinsic(_min, java_lang_Math, min_name, int2_int_signature, F_S) \ do_intrinsic(_max, java_lang_Math, max_name, int2_int_signature, F_S) \ + do_intrinsic(_addExact, java_lang_Math, addExact_name, int2_int_signature, F_S) \ \ do_intrinsic(_floatToRawIntBits, java_lang_Float, floatToRawIntBits_name, float_int_signature, F_S) \ do_name( floatToRawIntBits_name, "floatToRawIntBits") \ diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index cf9a82092fd..c17f7758270 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -636,7 +636,9 @@ \ diagnostic(bool, OptimizeExpensiveOps, true, \ "Find best control for expensive operations") \ - + \ + product(bool, UseMathExactIntrinsics, true, \ + "Enables intrinsification of various java.lang.Math funcitons") C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG) diff --git a/hotspot/src/share/vm/opto/classes.cpp b/hotspot/src/share/vm/opto/classes.cpp index 0dbe9a7e9a7..78529511f31 100644 --- a/hotspot/src/share/vm/opto/classes.cpp +++ b/hotspot/src/share/vm/opto/classes.cpp @@ -32,6 +32,7 @@ #include "opto/loopnode.hpp" #include "opto/machnode.hpp" #include "opto/memnode.hpp" +#include "opto/mathexactnode.hpp" #include "opto/mulnode.hpp" #include "opto/multnode.hpp" #include "opto/node.hpp" diff --git a/hotspot/src/share/vm/opto/classes.hpp b/hotspot/src/share/vm/opto/classes.hpp index f97b385f422..3217c4fb492 100644 --- a/hotspot/src/share/vm/opto/classes.hpp +++ b/hotspot/src/share/vm/opto/classes.hpp @@ -29,6 +29,7 @@ macro(AbsD) macro(AbsF) macro(AbsI) macro(AddD) +macro(AddExactI) macro(AddF) macro(AddI) macro(AddL) @@ -133,6 +134,7 @@ macro(EncodePKlass) macro(ExpD) macro(FastLock) macro(FastUnlock) +macro(FlagsProj) macro(Goto) macro(Halt) macro(If) @@ -167,6 +169,7 @@ macro(Loop) macro(LoopLimit) macro(Mach) macro(MachProj) +macro(MathExact) macro(MaxI) macro(MemBarAcquire) macro(MemBarAcquireLock) diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp index 3995446485b..7400e939b98 100644 --- a/hotspot/src/share/vm/opto/ifnode.cpp +++ b/hotspot/src/share/vm/opto/ifnode.cpp @@ -76,6 +76,7 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) { if( !i1->is_Bool() ) return NULL; BoolNode *b = i1->as_Bool(); Node *cmp = b->in(1); + if( cmp->is_FlagsProj() ) return NULL; if( !cmp->is_Cmp() ) return NULL; i1 = cmp->in(1); if( i1 == NULL || !i1->is_Phi() ) return NULL; diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp index 63deec31b3f..c497abdb578 100644 --- a/hotspot/src/share/vm/opto/lcm.cpp +++ b/hotspot/src/share/vm/opto/lcm.cpp @@ -472,6 +472,13 @@ Node* PhaseCFG::select(Block* block, Node_List &worklist, GrowableArray &re break; } + // For nodes that produce a FlagsProj, make the node adjacent to the + // use of the FlagsProj + if (use->is_FlagsProj() && get_block_for_node(use) == block) { + found_machif = true; + break; + } + // More than this instruction pending for successor to be ready, // don't choose this if other opportunities are ready if (ready_cnt.at(use->_idx) > 1) diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 902ed5919f3..90372600190 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -32,6 +32,7 @@ #include "opto/callGenerator.hpp" #include "opto/cfgnode.hpp" #include "opto/idealKit.hpp" +#include "opto/mathexactnode.hpp" #include "opto/mulnode.hpp" #include "opto/parse.hpp" #include "opto/runtime.hpp" @@ -199,6 +200,8 @@ class LibraryCallKit : public GraphKit { bool inline_math_native(vmIntrinsics::ID id); bool inline_trig(vmIntrinsics::ID id); bool inline_math(vmIntrinsics::ID id); + bool inline_math_mathExact(Node* math); + bool inline_math_addExact(); bool inline_exp(); bool inline_pow(); void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName); @@ -498,6 +501,15 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { if (!UseCRC32Intrinsics) return NULL; break; + case vmIntrinsics::_addExact: + if (!Matcher::match_rule_supported(Op_AddExactI)) { + return NULL; + } + if (!UseMathExactIntrinsics) { + return NULL; + } + break; + default: assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); @@ -668,6 +680,8 @@ bool LibraryCallKit::try_to_inline() { case vmIntrinsics::_min: case vmIntrinsics::_max: return inline_min_max(intrinsic_id()); + case vmIntrinsics::_addExact: return inline_math_addExact(); + case vmIntrinsics::_arraycopy: return inline_arraycopy(); case vmIntrinsics::_compareTo: return inline_string_compareTo(); @@ -1911,6 +1925,45 @@ bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) { return true; } +bool LibraryCallKit::inline_math_mathExact(Node* math) { + Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node)); + Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node)); + + Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) ); + IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); + Node* fast_path = _gvn.transform( new (C) IfFalseNode(check)); + Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) ); + + { + PreserveJVMState pjvms(this); + PreserveReexecuteState preexecs(this); + jvms()->set_should_reexecute(true); + + set_control(slow_path); + set_i_o(i_o()); + + uncommon_trap(Deoptimization::Reason_intrinsic, + Deoptimization::Action_none); + } + + set_control(fast_path); + set_result(result); + return true; +} + +bool LibraryCallKit::inline_math_addExact() { + Node* arg1 = argument(0); + Node* arg2 = argument(1); + + Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) ); + if (add->Opcode() == Op_AddExactI) { + return inline_math_mathExact(add); + } else { + set_result(add); + } + return true; +} + Node* LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { // These are the candidate return value: diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp index a30fc80df39..41c0a9d416d 100644 --- a/hotspot/src/share/vm/opto/loopTransform.cpp +++ b/hotspot/src/share/vm/opto/loopTransform.cpp @@ -776,6 +776,9 @@ bool IdealLoopTree::policy_range_check( PhaseIdealLoop *phase ) const { continue; // not RC Node *cmp = bol->in(1); + if (cmp->is_FlagsProj()) { + continue; + } Node *rc_exp = cmp->in(1); Node *limit = cmp->in(2); diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index 31b5d8a5b7b..9ee7ec7db9a 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -2355,7 +2355,8 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) { opc == Op_Catch || opc == Op_CatchProj || opc == Op_Jump || - opc == Op_JumpProj) { + opc == Op_JumpProj || + opc == Op_FlagsProj) { #if !defined(PRODUCT) if (TracePartialPeeling) { tty->print_cr("\nExit control too complex: lp: %d", head->_idx); diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp index ae27f6ffa21..85474115f30 100644 --- a/hotspot/src/share/vm/opto/matcher.cpp +++ b/hotspot/src/share/vm/opto/matcher.cpp @@ -1964,6 +1964,7 @@ void Matcher::find_shared( Node *n ) { case Op_Catch: case Op_CatchProj: case Op_CProj: + case Op_FlagsProj: case Op_JumpProj: case Op_JProj: case Op_NeverBranch: diff --git a/hotspot/src/share/vm/opto/matcher.hpp b/hotspot/src/share/vm/opto/matcher.hpp index 8435b0f997b..23ad64d2b83 100644 --- a/hotspot/src/share/vm/opto/matcher.hpp +++ b/hotspot/src/share/vm/opto/matcher.hpp @@ -337,6 +337,9 @@ public: // Register for MODL projection of divmodL static RegMask modL_proj_mask(); + static const RegMask mathExactI_result_proj_mask(); + static const RegMask mathExactI_flags_proj_mask(); + // Use hardware DIV instruction when it is faster than // a code which use multiply for division by constant. static bool use_asm_for_ldiv_by_con( jlong divisor ); diff --git a/hotspot/src/share/vm/opto/mathexactnode.cpp b/hotspot/src/share/vm/opto/mathexactnode.cpp new file mode 100644 index 00000000000..e15b3360526 --- /dev/null +++ b/hotspot/src/share/vm/opto/mathexactnode.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "memory/allocation.inline.hpp" +#include "opto/addnode.hpp" +#include "opto/machnode.hpp" +#include "opto/mathexactnode.hpp" +#include "opto/matcher.hpp" +#include "opto/subnode.hpp" + +MathExactNode::MathExactNode(Node* ctrl, Node* n1, Node* n2) : MultiNode(3) { + init_req(0, ctrl); + init_req(1, n1); + init_req(2, n2); +} + +Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) { + uint ideal_reg = proj->ideal_reg(); + RegMask rm; + if (proj->_con == result_proj_node) { + rm = m->mathExactI_result_proj_mask(); + } else { + assert(proj->_con == flags_proj_node, "must be result or flags"); + assert(ideal_reg == Op_RegFlags, "sanity"); + rm = m->mathExactI_flags_proj_mask(); + } + return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg); +} + +// If the MathExactNode won't overflow we have to replace the +// FlagsProjNode and ProjNode that is generated by the MathExactNode +Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) { + PhaseIterGVN *igvn = phase->is_IterGVN(); + if (igvn) { + ProjNode* result = result_node(); + ProjNode* flags = flags_node(); + + if (result != NULL) { + igvn->replace_node(result, new_result); + } + + if (flags != NULL) { + BoolNode* bolnode = (BoolNode *) flags->unique_out(); + switch (bolnode->_test._test) { + case BoolTest::overflow: + // if the check is for overflow - never taken + igvn->replace_node(bolnode, phase->intcon(0)); + break; + case BoolTest::no_overflow: + // if the check is for no overflow - always taken + igvn->replace_node(bolnode, phase->intcon(1)); + break; + default: + fatal("Unexpected value of BoolTest"); + break; + } + flags->del_req(0); + } + } + return new_result; +} + +Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) { + Node *arg1 = in(1); + Node *arg2 = in(2); + + const Type* type1 = phase->type(arg1); + const Type* type2 = phase->type(arg2); + + if (type1 != Type::TOP && type1->singleton() && + type2 != Type::TOP && type2->singleton()) { + jint val1 = arg1->get_int(); + jint val2 = arg2->get_int(); + jint result = val1 + val2; + // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result + if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) { + Node* con_result = ConINode::make(phase->C, result); + return no_overflow(phase, con_result); + } + return NULL; + } + + if (type1 == TypeInt::ZERO) { // (Add 0 x) == x + Node* add_result = new (phase->C) AddINode(arg1, arg2); + return no_overflow(phase, add_result); + } + + if (type2 == TypeInt::ZERO) { // (Add x 0) == x + Node* add_result = new (phase->C) AddINode(arg1, arg2); + return no_overflow(phase, add_result); + } + + if (type2->singleton()) { + return NULL; // no change - keep constant on the right + } + + if (type1->singleton()) { + // Make it x + Constant - move constant to the right + swap_edges(1, 2); + return this; + } + + if (arg2->is_Load()) { + return NULL; // no change - keep load on the right + } + + if (arg1->is_Load()) { + // Make it x + Load - move load to the right + swap_edges(1, 2); + return this; + } + + if (arg1->_idx > arg2->_idx) { + // Sort the edges + swap_edges(1, 2); + return this; + } + + return NULL; +} + diff --git a/hotspot/src/share/vm/opto/mathexactnode.hpp b/hotspot/src/share/vm/opto/mathexactnode.hpp new file mode 100644 index 00000000000..30d649941a0 --- /dev/null +++ b/hotspot/src/share/vm/opto/mathexactnode.hpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_OPTO_MATHEXACTNODE_HPP +#define SHARE_VM_OPTO_MATHEXACTNODE_HPP + +#include "opto/multnode.hpp" +#include "opto/node.hpp" +#include "opto/type.hpp" + +class Node; + +class PhaseGVN; +class PhaseTransform; + +class MathExactNode : public MultiNode { +public: + MathExactNode(Node* ctrl, Node* in1, Node* in2); + enum { + result_proj_node = 0, + flags_proj_node = 1 + }; + virtual int Opcode() const; + virtual Node* Identity(PhaseTransform* phase) { return this; } + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape) { return NULL; } + virtual const Type* Value(PhaseTransform* phase) const { return bottom_type(); } + virtual uint hash() const { return Node::hash(); } + virtual bool is_CFG() const { return false; } + virtual uint ideal_reg() const { return NotAMachineReg; } + + ProjNode* result_node() { return proj_out(result_proj_node); } + ProjNode* flags_node() { return proj_out(flags_proj_node); } +protected: + Node* no_overflow(PhaseGVN *phase, Node* new_result); +}; + +class AddExactINode : public MathExactNode { +public: + AddExactINode(Node* ctrl, Node* in1, Node* in2) : MathExactNode(ctrl, in1, in2) {} + virtual int Opcode() const; + virtual const Type* bottom_type() const { return TypeTuple::INT_CC_PAIR; } + virtual Node* match(const ProjNode* proj, const Matcher* m); + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); +}; + +class FlagsProjNode : public ProjNode { +public: + FlagsProjNode(Node* src, uint con) : ProjNode(src, con) { + init_class_id(Class_FlagsProj); + } + + virtual int Opcode() const; + virtual bool is_CFG() const { return false; } + virtual const Type* bottom_type() const { return TypeInt::CC; } + virtual uint ideal_reg() const { return Op_RegFlags; } +}; + + +#endif + diff --git a/hotspot/src/share/vm/opto/multnode.cpp b/hotspot/src/share/vm/opto/multnode.cpp index dca8dbe703c..286f0461b20 100644 --- a/hotspot/src/share/vm/opto/multnode.cpp +++ b/hotspot/src/share/vm/opto/multnode.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "opto/callnode.hpp" #include "opto/matcher.hpp" +#include "opto/mathexactnode.hpp" #include "opto/multnode.hpp" #include "opto/opcodes.hpp" #include "opto/phaseX.hpp" @@ -46,15 +47,21 @@ ProjNode* MultiNode::proj_out(uint which_proj) const { assert(Opcode() != Op_If || outcnt() == 2, "bad if #1"); for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) { Node *p = fast_out(i); - if( !p->is_Proj() ) { + if (p->is_Proj()) { + ProjNode *proj = p->as_Proj(); + if (proj->_con == which_proj) { + assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2"); + return proj; + } + } else if (p->is_FlagsProj()) { + FlagsProjNode *proj = p->as_FlagsProj(); + if (proj->_con == which_proj) { + return proj; + } + } else { assert(p == this && this->is_Start(), "else must be proj"); continue; } - ProjNode *proj = p->as_Proj(); - if( proj->_con == which_proj ) { - assert(Opcode() != Op_If || proj->Opcode() == (which_proj?Op_IfTrue:Op_IfFalse), "bad if #2"); - return proj; - } } return NULL; } diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp index 1c695f5660b..0e58abc8518 100644 --- a/hotspot/src/share/vm/opto/node.hpp +++ b/hotspot/src/share/vm/opto/node.hpp @@ -69,6 +69,7 @@ class EncodePNode; class EncodePKlassNode; class FastLockNode; class FastUnlockNode; +class FlagsProjNode; class IfNode; class IfFalseNode; class IfTrueNode; @@ -623,6 +624,7 @@ public: DEFINE_CLASS_ID(Cmp, Sub, 0) DEFINE_CLASS_ID(FastLock, Cmp, 0) DEFINE_CLASS_ID(FastUnlock, Cmp, 1) + DEFINE_CLASS_ID(FlagsProj, Cmp, 2) DEFINE_CLASS_ID(MergeMem, Node, 7) DEFINE_CLASS_ID(Bool, Node, 8) @@ -726,6 +728,7 @@ public: DEFINE_CLASS_QUERY(EncodePKlass) DEFINE_CLASS_QUERY(FastLock) DEFINE_CLASS_QUERY(FastUnlock) + DEFINE_CLASS_QUERY(FlagsProj) DEFINE_CLASS_QUERY(If) DEFINE_CLASS_QUERY(IfFalse) DEFINE_CLASS_QUERY(IfTrue) diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp index 275b4d80dd1..4e2c8b7aef6 100644 --- a/hotspot/src/share/vm/opto/subnode.cpp +++ b/hotspot/src/share/vm/opto/subnode.cpp @@ -1064,7 +1064,7 @@ const Type *BoolTest::cc2logical( const Type *CC ) const { // Print special per-node info #ifndef PRODUCT void BoolTest::dump_on(outputStream *st) const { - const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"}; + const char *msg[] = {"eq","gt","of","lt","ne","le","nof","ge"}; st->print(msg[_test]); } #endif @@ -1126,7 +1126,7 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *cmp = in(1); if( !cmp->is_Sub() ) return NULL; int cop = cmp->Opcode(); - if( cop == Op_FastLock || cop == Op_FastUnlock ) return NULL; + if( cop == Op_FastLock || cop == Op_FastUnlock || cop == Op_FlagsProj) return NULL; Node *cmp1 = cmp->in(1); Node *cmp2 = cmp->in(2); if( !cmp1 ) return NULL; diff --git a/hotspot/src/share/vm/opto/subnode.hpp b/hotspot/src/share/vm/opto/subnode.hpp index 50c0bfac9c7..47eb5c65c05 100644 --- a/hotspot/src/share/vm/opto/subnode.hpp +++ b/hotspot/src/share/vm/opto/subnode.hpp @@ -263,16 +263,16 @@ public: // We pick the values as 3 bits; the low order 2 bits we compare against the // condition codes, the high bit flips the sense of the result. struct BoolTest VALUE_OBJ_CLASS_SPEC { - enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, illegal = 8 }; + enum mask { eq = 0, ne = 4, le = 5, ge = 7, lt = 3, gt = 1, overflow = 2, no_overflow = 6, illegal = 8 }; mask _test; BoolTest( mask btm ) : _test(btm) {} const Type *cc2logical( const Type *CC ) const; // Commute the test. I use a small table lookup. The table is created as // a simple char array where each element is the ASCII version of a 'mask' // enum from above. - mask commute( ) const { return mask("038147858"[_test]-'0'); } + mask commute( ) const { return mask("032147658"[_test]-'0'); } mask negate( ) const { return mask(_test^4); } - bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); } + bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le || _test == BoolTest::overflow); } #ifndef PRODUCT void dump_on(outputStream *st) const; #endif diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index e25c529a886..18f2b9d3181 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -430,6 +430,11 @@ void Type::Initialize_shared(Compile* current) { longpair[1] = TypeLong::LONG; TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair); + const Type **intccpair = TypeTuple::fields(2); + intccpair[0] = TypeInt::INT; + intccpair[1] = TypeInt::CC; + TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair); + _const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM; _const_basic_type[T_NARROWKLASS] = Type::BOTTOM; _const_basic_type[T_BOOLEAN] = TypeInt::BOOL; @@ -1646,6 +1651,7 @@ const TypeTuple *TypeTuple::STORECONDITIONAL; const TypeTuple *TypeTuple::START_I2C; const TypeTuple *TypeTuple::INT_PAIR; const TypeTuple *TypeTuple::LONG_PAIR; +const TypeTuple *TypeTuple::INT_CC_PAIR; //------------------------------make------------------------------------------- diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index d4832591843..2d7637bb5c7 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -584,6 +584,7 @@ public: static const TypeTuple *START_I2C; static const TypeTuple *INT_PAIR; static const TypeTuple *LONG_PAIR; + static const TypeTuple *INT_CC_PAIR; #ifndef PRODUCT virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping #endif diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index c9365cf16e2..e526c76075c 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -176,6 +176,7 @@ #include "opto/loopnode.hpp" #include "opto/machnode.hpp" #include "opto/matcher.hpp" +#include "opto/mathexactnode.hpp" #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" #include "opto/parse.hpp" @@ -1927,6 +1928,9 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_c2_type(CmpF3Node, CmpFNode) \ declare_c2_type(CmpDNode, CmpNode) \ declare_c2_type(CmpD3Node, CmpDNode) \ + declare_c2_type(MathExactNode, MultiNode) \ + declare_c2_type(AddExactINode, MathExactNode) \ + declare_c2_type(FlagsProjNode, ProjNode) \ declare_c2_type(BoolNode, Node) \ declare_c2_type(AbsNode, Node) \ declare_c2_type(AbsINode, AbsNode) \ diff --git a/hotspot/test/compiler/intrinsics/mathexact/CondTest.java b/hotspot/test/compiler/intrinsics/mathexact/CondTest.java new file mode 100644 index 00000000000..a6507cf052f --- /dev/null +++ b/hotspot/test/compiler/intrinsics/mathexact/CondTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024924 + * @summary Test non constant addExact + * @compile CondTest.java Verify.java + * @run main CondTest + * + */ + +import java.lang.ArithmeticException; + +public class CondTest { + public static int result = 0; + + public static void main(String[] args) { + for (int i = 0; i < 50000; ++i) { + runTest(); + } + } + + public static void runTest() { + int i = 7; + while (java.lang.Math.addExact(i, result) < 89361) { + if ((java.lang.Math.addExact(i, i) & 1) == 1) { + i += 3; + } else if ((i & 5) == 4) { + i += 7; + } else if ((i & 0xf) == 6) { + i += 2; + } else { + i += 1; + } + result += 2; + } + } +} diff --git a/hotspot/test/compiler/intrinsics/mathexact/ConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/ConstantTest.java new file mode 100644 index 00000000000..b7bf93f66ec --- /dev/null +++ b/hotspot/test/compiler/intrinsics/mathexact/ConstantTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024924 + * @summary Test constant addExact + * @compile ConstantTest.java Verify.java + * @run main ConstantTest + * + */ + +import java.lang.ArithmeticException; + +public class ConstantTest { + public static void main(String[] args) { + for (int i = 0; i < 50000; ++i) { + Verify.verify(5, 7); + Verify.verify(Integer.MAX_VALUE, 1); + Verify.verify(Integer.MIN_VALUE, -1); + Verify.verify(Integer.MAX_VALUE, -1); + Verify.verify(Integer.MIN_VALUE, 1); + Verify.verify(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2); + Verify.verify(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3); + } + } +} diff --git a/hotspot/test/compiler/intrinsics/mathexact/LoadTest.java b/hotspot/test/compiler/intrinsics/mathexact/LoadTest.java new file mode 100644 index 00000000000..c04180ba634 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/mathexact/LoadTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024924 + * @summary Test non constant addExact + * @compile LoadTest.java Verify.java + * @run main LoadTest + * + */ + +import java.lang.ArithmeticException; + +public class LoadTest { + public static java.util.Random rnd = new java.util.Random(); + public static int[] values = new int[256]; + + public static void main(String[] args) { + for (int i = 0; i < values.length; ++i) { + values[i] = rnd.nextInt(); + } + + for (int i = 0; i < 50000; ++i) { + Verify.verify(values[i & 255], values[i & 255] - i); + Verify.verify(values[i & 255] + i, values[i & 255] - i); + Verify.verify(values[i & 255], values[i & 255]); + if ((i & 1) == 1 && i > 5) { + Verify.verify(values[i & 255] + i, values[i & 255] - i); + } else { + Verify.verify(values[i & 255] - i, values[i & 255] + i); + } + } + } +} diff --git a/hotspot/test/compiler/intrinsics/mathexact/LoopDependentTest.java b/hotspot/test/compiler/intrinsics/mathexact/LoopDependentTest.java new file mode 100644 index 00000000000..17f58921f28 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/mathexact/LoopDependentTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024924 + * @summary Test non constant addExact + * @compile LoopDependentTest.java Verify.java + * @run main LoopDependentTest + * + */ + +import java.lang.ArithmeticException; + +public class LoopDependentTest { + public static java.util.Random rnd = new java.util.Random(); + + public static void main(String[] args) { + int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt(); + for (int i = 0; i < 50000; ++i) { + Verify.verify(rnd1 + i, rnd2 + i); + Verify.verify(rnd1 + i, rnd2 + (i & 0xff)); + Verify.verify(rnd1 - i, rnd2 - (i & 0xff)); + Verify.verify(rnd1 + i + 1, rnd2 + i + 2); + Verify.verify(rnd1 + i * 2, rnd2 + i); + } + } +} diff --git a/hotspot/test/compiler/intrinsics/mathexact/NonConstantTest.java b/hotspot/test/compiler/intrinsics/mathexact/NonConstantTest.java new file mode 100644 index 00000000000..78c9f9d99e2 --- /dev/null +++ b/hotspot/test/compiler/intrinsics/mathexact/NonConstantTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024924 + * @summary Test non constant addExact + * @compile NonConstantTest.java Verify.java + * @run main NonConstantTest + * + */ + +import java.lang.ArithmeticException; + +public class NonConstantTest { + public static java.util.Random rnd = new java.util.Random(); + + public static void main(String[] args) { + for (int i = 0; i < 50000; ++i) { + int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt(); + Verify.verify(rnd1, rnd2); + Verify.verify(rnd1, rnd2 + 1); + Verify.verify(rnd1 + 1, rnd2); + Verify.verify(rnd1 - 1, rnd2); + Verify.verify(rnd1, rnd2 - 1); + } + } +} diff --git a/hotspot/test/compiler/intrinsics/mathexact/Verify.java b/hotspot/test/compiler/intrinsics/mathexact/Verify.java new file mode 100644 index 00000000000..de5a4cc44ef --- /dev/null +++ b/hotspot/test/compiler/intrinsics/mathexact/Verify.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class Verify { + public static String throwWord(boolean threw) { + return (threw ? "threw" : "didn't throw"); + } + + public static void verify(int a, int b) { + boolean exception1 = false, exception2 = false; + int result1 = 0, result2 = 0; + try { + result1 = testIntrinsic(a, b); + } catch (ArithmeticException e) { + exception1 = true; + } + try { + result2 = testNonIntrinsic(a, b); + } catch (ArithmeticException e) { + exception2 = true; + } + + if (exception1 != exception2) { + throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b); + } + if (result1 != result2) { + throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b); + } + } + + public static int testIntrinsic(int a, int b) { + return java.lang.Math.addExact(a, b); + } + + public static int testNonIntrinsic(int a, int b) { + return safeAddExact(a, b); + } + + // Copied java.lang.Math.addExact to avoid intrinsification + public static int safeAddExact(int x, int y) { + int r = x + y; + // HD 2-12 Overflow iff both arguments have the opposite sign of the result + if (((x ^ r) & (y ^ r)) < 0) { + throw new ArithmeticException("integer overflow"); + } + return r; + } +} From 0dee555eadd9e64f40e9c7a366c3931eec06f972 Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Fri, 27 Sep 2013 10:50:55 +0200 Subject: [PATCH 222/293] 8020151: PSR:PERF Large performance regressions when code cache is filled Code cache sweeping based on method hotness; removed speculatively disconnect Reviewed-by: kvn, iveresov --- hotspot/src/share/vm/code/codeCache.cpp | 86 ----- hotspot/src/share/vm/code/codeCache.hpp | 6 - hotspot/src/share/vm/code/nmethod.cpp | 29 +- hotspot/src/share/vm/code/nmethod.hpp | 27 +- .../src/share/vm/compiler/compileBroker.cpp | 53 +-- hotspot/src/share/vm/oops/method.cpp | 10 - hotspot/src/share/vm/runtime/arguments.cpp | 7 + hotspot/src/share/vm/runtime/globals.hpp | 13 +- hotspot/src/share/vm/runtime/safepoint.cpp | 4 +- hotspot/src/share/vm/runtime/sweeper.cpp | 322 +++++++----------- hotspot/src/share/vm/runtime/sweeper.hpp | 75 ++-- hotspot/src/share/vm/runtime/vmStructs.cpp | 4 +- .../src/share/vm/runtime/vm_operations.cpp | 4 - .../src/share/vm/runtime/vm_operations.hpp | 11 - hotspot/src/share/vm/trace/trace.xml | 7 - 15 files changed, 240 insertions(+), 418 deletions(-) diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp index 65c1e5f2eb5..fcdab3d5af4 100644 --- a/hotspot/src/share/vm/code/codeCache.cpp +++ b/hotspot/src/share/vm/code/codeCache.cpp @@ -124,7 +124,6 @@ int CodeCache::_number_of_nmethods = 0; int CodeCache::_number_of_nmethods_with_dependencies = 0; bool CodeCache::_needs_cache_clean = false; nmethod* CodeCache::_scavenge_root_nmethods = NULL; -nmethod* CodeCache::_saved_nmethods = NULL; int CodeCache::_codemem_full_count = 0; @@ -464,96 +463,11 @@ void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) { } #endif //PRODUCT -/** - * Remove and return nmethod from the saved code list in order to reanimate it. - */ -nmethod* CodeCache::reanimate_saved_code(Method* m) { - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - nmethod* saved = _saved_nmethods; - nmethod* prev = NULL; - while (saved != NULL) { - if (saved->is_in_use() && saved->method() == m) { - if (prev != NULL) { - prev->set_saved_nmethod_link(saved->saved_nmethod_link()); - } else { - _saved_nmethods = saved->saved_nmethod_link(); - } - assert(saved->is_speculatively_disconnected(), "shouldn't call for other nmethods"); - saved->set_speculatively_disconnected(false); - saved->set_saved_nmethod_link(NULL); - if (PrintMethodFlushing) { - saved->print_on(tty, " ### nmethod is reconnected"); - } - if (LogCompilation && (xtty != NULL)) { - ttyLocker ttyl; - xtty->begin_elem("nmethod_reconnected compile_id='%3d'", saved->compile_id()); - xtty->method(m); - xtty->stamp(); - xtty->end_elem(); - } - return saved; - } - prev = saved; - saved = saved->saved_nmethod_link(); - } - return NULL; -} - -/** - * Remove nmethod from the saved code list in order to discard it permanently - */ -void CodeCache::remove_saved_code(nmethod* nm) { - // For conc swpr this will be called with CodeCache_lock taken by caller - assert_locked_or_safepoint(CodeCache_lock); - assert(nm->is_speculatively_disconnected(), "shouldn't call for other nmethods"); - nmethod* saved = _saved_nmethods; - nmethod* prev = NULL; - while (saved != NULL) { - if (saved == nm) { - if (prev != NULL) { - prev->set_saved_nmethod_link(saved->saved_nmethod_link()); - } else { - _saved_nmethods = saved->saved_nmethod_link(); - } - if (LogCompilation && (xtty != NULL)) { - ttyLocker ttyl; - xtty->begin_elem("nmethod_removed compile_id='%3d'", nm->compile_id()); - xtty->stamp(); - xtty->end_elem(); - } - return; - } - prev = saved; - saved = saved->saved_nmethod_link(); - } - ShouldNotReachHere(); -} - -void CodeCache::speculatively_disconnect(nmethod* nm) { - assert_locked_or_safepoint(CodeCache_lock); - assert(nm->is_in_use() && !nm->is_speculatively_disconnected(), "should only disconnect live nmethods"); - nm->set_saved_nmethod_link(_saved_nmethods); - _saved_nmethods = nm; - if (PrintMethodFlushing) { - nm->print_on(tty, " ### nmethod is speculatively disconnected"); - } - if (LogCompilation && (xtty != NULL)) { - ttyLocker ttyl; - xtty->begin_elem("nmethod_disconnected compile_id='%3d'", nm->compile_id()); - xtty->method(nm->method()); - xtty->stamp(); - xtty->end_elem(); - } - nm->method()->clear_code(); - nm->set_speculatively_disconnected(true); -} - void CodeCache::gc_prologue() { assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called"); } - void CodeCache::gc_epilogue() { assert_locked_or_safepoint(CodeCache_lock); FOR_ALL_ALIVE_BLOBS(cb) { diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp index 3e8eda6e2b2..e190b11ae7e 100644 --- a/hotspot/src/share/vm/code/codeCache.hpp +++ b/hotspot/src/share/vm/code/codeCache.hpp @@ -57,7 +57,6 @@ class CodeCache : AllStatic { static int _number_of_nmethods_with_dependencies; static bool _needs_cache_clean; static nmethod* _scavenge_root_nmethods; // linked via nm->scavenge_root_link() - static nmethod* _saved_nmethods; // Linked list of speculatively disconnected nmethods. static void verify_if_often() PRODUCT_RETURN; @@ -167,17 +166,12 @@ class CodeCache : AllStatic { static size_t capacity() { return _heap->capacity(); } static size_t max_capacity() { return _heap->max_capacity(); } static size_t unallocated_capacity() { return _heap->unallocated_capacity(); } - static bool needs_flushing() { return unallocated_capacity() < CodeCacheFlushingMinimumFreeSpace; } static double reverse_free_ratio(); static bool needs_cache_clean() { return _needs_cache_clean; } static void set_needs_cache_clean(bool v) { _needs_cache_clean = v; } static void clear_inline_caches(); // clear all inline caches - static nmethod* reanimate_saved_code(Method* m); - static void remove_saved_code(nmethod* nm); - static void speculatively_disconnect(nmethod* nm); - // Deoptimization static int mark_for_deoptimization(DepChange& changes); #ifdef HOTSWAP diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp index 4f8608f08a0..cfc2ddeab1c 100644 --- a/hotspot/src/share/vm/code/nmethod.cpp +++ b/hotspot/src/share/vm/code/nmethod.cpp @@ -462,7 +462,6 @@ void nmethod::init_defaults() { _state = alive; _marked_for_reclamation = 0; _has_flushed_dependencies = 0; - _speculatively_disconnected = 0; _has_unsafe_access = 0; _has_method_handle_invokes = 0; _lazy_critical_native = 0; @@ -481,7 +480,6 @@ void nmethod::init_defaults() { _osr_link = NULL; _scavenge_root_link = NULL; _scavenge_root_state = 0; - _saved_nmethod_link = NULL; _compiler = NULL; #ifdef HAVE_DTRACE_H @@ -686,6 +684,7 @@ nmethod::nmethod( _osr_entry_point = NULL; _exception_cache = NULL; _pc_desc_cache.reset_to(NULL); + _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); code_buffer->copy_values_to(this); if (ScavengeRootsInCode && detect_scavenge_root_oops()) { @@ -770,6 +769,7 @@ nmethod::nmethod( _osr_entry_point = NULL; _exception_cache = NULL; _pc_desc_cache.reset_to(NULL); + _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); code_buffer->copy_values_to(this); debug_only(verify_scavenge_root_oops()); @@ -842,6 +842,7 @@ nmethod::nmethod( _comp_level = comp_level; _compiler = compiler; _orig_pc_offset = orig_pc_offset; + _hotness_counter = NMethodSweeper::hotness_counter_reset_val(); // Section offsets _consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()); @@ -1176,7 +1177,7 @@ void nmethod::cleanup_inline_caches() { // This is a private interface with the sweeper. void nmethod::mark_as_seen_on_stack() { - assert(is_not_entrant(), "must be a non-entrant method"); + assert(is_alive(), "Must be an alive method"); // Set the traversal mark to ensure that the sweeper does 2 // cleaning passes before moving to zombie. set_stack_traversal_mark(NMethodSweeper::traversal_count()); @@ -1261,7 +1262,7 @@ void nmethod::make_unloaded(BoolObjectClosure* is_alive, oop cause) { set_osr_link(NULL); //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods - NMethodSweeper::notify(this); + NMethodSweeper::notify(); } void nmethod::invalidate_osr_method() { @@ -1351,6 +1352,15 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { nmethod_needs_unregister = true; } + // Must happen before state change. Otherwise we have a race condition in + // nmethod::can_not_entrant_be_converted(). I.e., a method can immediately + // transition its state from 'not_entrant' to 'zombie' without having to wait + // for stack scanning. + if (state == not_entrant) { + mark_as_seen_on_stack(); + OrderAccess::storestore(); + } + // Change state _state = state; @@ -1369,11 +1379,6 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { HandleMark hm; method()->clear_code(); } - - if (state == not_entrant) { - mark_as_seen_on_stack(); - } - } // leave critical region under Patching_lock // When the nmethod becomes zombie it is no longer alive so the @@ -1416,7 +1421,7 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) { } // Make sweeper aware that there is a zombie method that needs to be removed - NMethodSweeper::notify(this); + NMethodSweeper::notify(); return true; } @@ -1451,10 +1456,6 @@ void nmethod::flush() { CodeCache::drop_scavenge_root_nmethod(this); } - if (is_speculatively_disconnected()) { - CodeCache::remove_saved_code(this); - } - #ifdef SHARK ((SharkCompiler *) compiler())->free_compiled_method(insts_begin()); #endif // SHARK diff --git a/hotspot/src/share/vm/code/nmethod.hpp b/hotspot/src/share/vm/code/nmethod.hpp index 4929ea820c0..538bcf77837 100644 --- a/hotspot/src/share/vm/code/nmethod.hpp +++ b/hotspot/src/share/vm/code/nmethod.hpp @@ -119,7 +119,6 @@ class nmethod : public CodeBlob { // To support simple linked-list chaining of nmethods: nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head nmethod* _scavenge_root_link; // from CodeCache::scavenge_root_nmethods - nmethod* _saved_nmethod_link; // from CodeCache::speculatively_disconnect static nmethod* volatile _oops_do_mark_nmethods; nmethod* volatile _oops_do_mark_link; @@ -165,7 +164,6 @@ class nmethod : public CodeBlob { // protected by CodeCache_lock bool _has_flushed_dependencies; // Used for maintenance of dependencies (CodeCache_lock) - bool _speculatively_disconnected; // Marked for potential unload bool _marked_for_reclamation; // Used by NMethodSweeper (set only by sweeper) bool _marked_for_deoptimization; // Used for stack deoptimization @@ -180,7 +178,7 @@ class nmethod : public CodeBlob { unsigned int _has_wide_vectors:1; // Preserve wide vectors at safepoints // Protected by Patching_lock - unsigned char _state; // {alive, not_entrant, zombie, unloaded} + volatile unsigned char _state; // {alive, not_entrant, zombie, unloaded} #ifdef ASSERT bool _oops_are_stale; // indicates that it's no longer safe to access oops section @@ -202,11 +200,18 @@ class nmethod : public CodeBlob { // not_entrant method removal. Each mark_sweep pass will update // this mark to current sweep invocation count if it is seen on the - // stack. An not_entrant method can be removed when there is no + // stack. An not_entrant method can be removed when there are no // more activations, i.e., when the _stack_traversal_mark is less than // current sweep traversal index. long _stack_traversal_mark; + // The _hotness_counter indicates the hotness of a method. The higher + // the value the hotter the method. The hotness counter of a nmethod is + // set to [(ReservedCodeCacheSize / (1024 * 1024)) * 2] each time the method + // is active while stack scanning (mark_active_nmethods()). The hotness + // counter is decreased (by 1) while sweeping. + int _hotness_counter; + ExceptionCache *_exception_cache; PcDescCache _pc_desc_cache; @@ -382,6 +387,10 @@ class nmethod : public CodeBlob { int total_size () const; + void dec_hotness_counter() { _hotness_counter--; } + void set_hotness_counter(int val) { _hotness_counter = val; } + int hotness_counter() const { return _hotness_counter; } + // Containment bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); } bool insts_contains (address addr) const { return insts_begin () <= addr && addr < insts_end (); } @@ -408,8 +417,8 @@ class nmethod : public CodeBlob { // alive. It is used when an uncommon trap happens. Returns true // if this thread changed the state of the nmethod or false if // another thread performed the transition. - bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); } - bool make_zombie() { return make_not_entrant_or_zombie(zombie); } + bool make_not_entrant() { return make_not_entrant_or_zombie(not_entrant); } + bool make_zombie() { return make_not_entrant_or_zombie(zombie); } // used by jvmti to track if the unload event has been reported bool unload_reported() { return _unload_reported; } @@ -437,9 +446,6 @@ class nmethod : public CodeBlob { bool has_method_handle_invokes() const { return _has_method_handle_invokes; } void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } - bool is_speculatively_disconnected() const { return _speculatively_disconnected; } - void set_speculatively_disconnected(bool z) { _speculatively_disconnected = z; } - bool is_lazy_critical_native() const { return _lazy_critical_native; } void set_lazy_critical_native(bool z) { _lazy_critical_native = z; } @@ -499,9 +505,6 @@ public: nmethod* scavenge_root_link() const { return _scavenge_root_link; } void set_scavenge_root_link(nmethod *n) { _scavenge_root_link = n; } - nmethod* saved_nmethod_link() const { return _saved_nmethod_link; } - void set_saved_nmethod_link(nmethod *n) { _saved_nmethod_link = n; } - public: // Sweeper support diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index e8f57b24e19..594c58b5d68 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -634,19 +634,36 @@ CompileTask* CompileQueue::get() { NMethodSweeper::possibly_sweep(); MutexLocker locker(lock()); - // Wait for an available CompileTask. + // If _first is NULL we have no more compile jobs. There are two reasons for + // having no compile jobs: First, we compiled everything we wanted. Second, + // we ran out of code cache so compilation has been disabled. In the latter + // case we perform code cache sweeps to free memory such that we can re-enable + // compilation. while (_first == NULL) { - // There is no work to be done right now. Wait. - if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) { - // During the emergency sweeping periods, wake up and sweep occasionally - bool timedout = lock()->wait(!Mutex::_no_safepoint_check_flag, NmethodSweepCheckInterval*1000); - if (timedout) { + if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) { + // Wait a certain amount of time to possibly do another sweep. + // We must wait until stack scanning has happened so that we can + // transition a method's state from 'not_entrant' to 'zombie'. + long wait_time = NmethodSweepCheckInterval * 1000; + if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) { + // Only one thread at a time can do sweeping. Scale the + // wait time according to the number of compiler threads. + // As a result, the next sweep is likely to happen every 100ms + // with an arbitrary number of threads that do sweeping. + wait_time = 100 * CICompilerCount; + } + bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time); + if (timeout) { MutexUnlocker ul(lock()); - // When otherwise not busy, run nmethod sweeping NMethodSweeper::possibly_sweep(); } } else { - // During normal operation no need to wake up on timer + // If there are no compilation tasks and we can compile new jobs + // (i.e., there is enough free space in the code cache) there is + // no need to invoke the sweeper. As a result, the hotness of methods + // remains unchanged. This behavior is desired, since we want to keep + // the stable state, i.e., we do not want to evict methods from the + // code cache if it is unnecessary. lock()->wait(); } } @@ -1227,16 +1244,9 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci, return method_code; } } - if (method->is_not_compilable(comp_level)) return NULL; - - if (UseCodeCacheFlushing) { - nmethod* saved = CodeCache::reanimate_saved_code(method()); - if (saved != NULL) { - method->set_code(method, saved); - return saved; - } + if (method->is_not_compilable(comp_level)) { + return NULL; } - } else { // osr compilation #ifndef TIERED @@ -1585,9 +1595,6 @@ void CompileBroker::compiler_thread_loop() { if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { // the code cache is really full handle_full_code_cache(); - } else if (UseCodeCacheFlushing && CodeCache::needs_flushing()) { - // Attempt to start cleaning the code cache while there is still a little headroom - NMethodSweeper::handle_full_code_cache(false); } CompileTask* task = queue->get(); @@ -1943,7 +1950,11 @@ void CompileBroker::handle_full_code_cache() { } #endif if (UseCodeCacheFlushing) { - NMethodSweeper::handle_full_code_cache(true); + // Since code cache is full, immediately stop new compiles + if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) { + NMethodSweeper::log_sweep("disable_compiler"); + NMethodSweeper::possibly_sweep(); + } } else { UseCompiler = false; AlwaysCompileLoopMethods = false; diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp index 30631fa3b61..9d30c40f9b0 100644 --- a/hotspot/src/share/vm/oops/method.cpp +++ b/hotspot/src/share/vm/oops/method.cpp @@ -901,16 +901,6 @@ address Method::make_adapters(methodHandle mh, TRAPS) { // This function must not hit a safepoint! address Method::verified_code_entry() { debug_only(No_Safepoint_Verifier nsv;) - nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code); - if (code == NULL && UseCodeCacheFlushing) { - nmethod *saved_code = CodeCache::reanimate_saved_code(this); - if (saved_code != NULL) { - methodHandle method(this); - assert( ! saved_code->is_osr_method(), "should not get here for osr" ); - set_code( method, saved_code ); - } - } - assert(_from_compiled_entry != NULL, "must be set"); return _from_compiled_entry; } diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 53454e55885..9a76b1b6a65 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1130,6 +1130,9 @@ void Arguments::set_tiered_flags() { Tier3InvokeNotifyFreqLog = 0; Tier4InvocationThreshold = 0; } + if (FLAG_IS_DEFAULT(NmethodSweepFraction)) { + FLAG_SET_DEFAULT(NmethodSweepFraction, 1 + ReservedCodeCacheSize / (16 * M)); + } } #if INCLUDE_ALL_GCS @@ -2333,6 +2336,10 @@ bool Arguments::check_vm_args_consistency() { (2*G)/M); status = false; } + + status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction"); + status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity"); + return status; } diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 9d429cd76db..394358d785e 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -2868,6 +2868,10 @@ class CommandLineFlags { product(intx, NmethodSweepCheckInterval, 5, \ "Compilers wake up every n seconds to possibly sweep nmethods") \ \ + product(intx, NmethodSweepActivity, 10, \ + "Removes cold nmethods from code cache if > 0. Higher values " \ + "result in more aggressive sweeping") \ + \ notproduct(bool, LogSweeper, false, \ "Keep a ring buffer of sweeper activity") \ \ @@ -3239,15 +3243,6 @@ class CommandLineFlags { product(bool, UseCodeCacheFlushing, true, \ "Attempt to clean the code cache before shutting off compiler") \ \ - product(intx, MinCodeCacheFlushingInterval, 30, \ - "Min number of seconds between code cache cleaning sessions") \ - \ - product(uintx, CodeCacheFlushingMinimumFreeSpace, 1500*K, \ - "When less than X space left, start code cache cleaning") \ - \ - product(uintx, CodeCacheFlushingFraction, 2, \ - "Fraction of the code cache that is flushed when full") \ - \ /* interpreter debugging */ \ develop(intx, BinarySwitchThreshold, 5, \ "Minimal number of lookupswitch entries for rewriting to binary " \ diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index f3191e524de..95c395fad92 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -519,8 +519,8 @@ void SafepointSynchronize::do_cleanup_tasks() { } { - TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime); - NMethodSweeper::scan_stacks(); + TraceTime t4("mark nmethods", TraceSafepointCleanupTime); + NMethodSweeper::mark_active_nmethods(); } if (SymbolTable::needs_rehashing()) { diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp index 37315aec328..eab7636fac1 100644 --- a/hotspot/src/share/vm/runtime/sweeper.cpp +++ b/hotspot/src/share/vm/runtime/sweeper.cpp @@ -127,64 +127,79 @@ void NMethodSweeper::record_sweep(nmethod* nm, int line) { #define SWEEP(nm) #endif +nmethod* NMethodSweeper::_current = NULL; // Current nmethod +long NMethodSweeper::_traversals = 0; // Nof. stack traversals performed +int NMethodSweeper::_seen = 0; // Nof. nmethods we have currently processed in current pass of CodeCache +int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep +int NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep +int NMethodSweeper::_marked_count = 0; // Nof. nmethods marked for reclaim in current sweep -long NMethodSweeper::_traversals = 0; // No. of stack traversals performed -nmethod* NMethodSweeper::_current = NULL; // Current nmethod -int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache -int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep -int NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep -int NMethodSweeper::_marked_count = 0; // Nof. nmethods marked for reclaim in current sweep - -volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass +volatile int NMethodSweeper::_invocations = 0; // Nof. invocations left until we are completed with this pass volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress. -jint NMethodSweeper::_locked_seen = 0; +jint NMethodSweeper::_locked_seen = 0; jint NMethodSweeper::_not_entrant_seen_on_stack = 0; -bool NMethodSweeper::_resweep = false; -jint NMethodSweeper::_flush_token = 0; -jlong NMethodSweeper::_last_full_flush_time = 0; -int NMethodSweeper::_highest_marked = 0; -int NMethodSweeper::_dead_compile_ids = 0; -long NMethodSweeper::_last_flush_traversal_id = 0; +bool NMethodSweeper::_request_mark_phase = false; -int NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache int NMethodSweeper::_total_nof_methods_reclaimed = 0; -jlong NMethodSweeper::_total_time_sweeping = 0; -jlong NMethodSweeper::_total_time_this_sweep = 0; -jlong NMethodSweeper::_peak_sweep_time = 0; -jlong NMethodSweeper::_peak_sweep_fraction_time = 0; -jlong NMethodSweeper::_total_disconnect_time = 0; -jlong NMethodSweeper::_peak_disconnect_time = 0; +jlong NMethodSweeper::_total_time_sweeping = 0; +jlong NMethodSweeper::_total_time_this_sweep = 0; +jlong NMethodSweeper::_peak_sweep_time = 0; +jlong NMethodSweeper::_peak_sweep_fraction_time = 0; +int NMethodSweeper::_hotness_counter_reset_val = 0; + class MarkActivationClosure: public CodeBlobClosure { public: virtual void do_code_blob(CodeBlob* cb) { - // If we see an activation belonging to a non_entrant nmethod, we mark it. - if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) { - ((nmethod*)cb)->mark_as_seen_on_stack(); + if (cb->is_nmethod()) { + nmethod* nm = (nmethod*)cb; + nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val()); + // If we see an activation belonging to a non_entrant nmethod, we mark it. + if (nm->is_not_entrant()) { + nm->mark_as_seen_on_stack(); + } } } }; static MarkActivationClosure mark_activation_closure; +class SetHotnessClosure: public CodeBlobClosure { +public: + virtual void do_code_blob(CodeBlob* cb) { + if (cb->is_nmethod()) { + nmethod* nm = (nmethod*)cb; + nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val()); + } + } +}; +static SetHotnessClosure set_hotness_closure; + + +int NMethodSweeper::hotness_counter_reset_val() { + if (_hotness_counter_reset_val == 0) { + _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2; + } + return _hotness_counter_reset_val; +} bool NMethodSweeper::sweep_in_progress() { return (_current != NULL); } -void NMethodSweeper::scan_stacks() { +// Scans the stacks of all Java threads and marks activations of not-entrant methods. +// No need to synchronize access, since 'mark_active_nmethods' is always executed at a +// safepoint. +void NMethodSweeper::mark_active_nmethods() { assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); - if (!MethodFlushing) return; - - // No need to synchronize access, since this is always executed at a - // safepoint. - - // Make sure CompiledIC_lock in unlocked, since we might update some - // inline caches. If it is, we just bail-out and try later. - if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return; + // If we do not want to reclaim not-entrant or zombie methods there is no need + // to scan stacks + if (!MethodFlushing) { + return; + } // Check for restart assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid"); - if (!sweep_in_progress() && _resweep) { + if (!sweep_in_progress() && need_marking_phase()) { _seen = 0; _invocations = NmethodSweepFraction; _current = CodeCache::first_nmethod(); @@ -197,30 +212,22 @@ void NMethodSweeper::scan_stacks() { Threads::nmethods_do(&mark_activation_closure); // reset the flags since we started a scan from the beginning. - _resweep = false; + reset_nmethod_marking(); _locked_seen = 0; _not_entrant_seen_on_stack = 0; + } else { + // Only set hotness counter + Threads::nmethods_do(&set_hotness_closure); } - if (UseCodeCacheFlushing) { - // only allow new flushes after the interval is complete. - jlong now = os::javaTimeMillis(); - jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; - jlong curr_interval = now - _last_full_flush_time; - if (curr_interval > max_interval) { - _flush_token = 0; - } - - if (!CodeCache::needs_flushing() && !CompileBroker::should_compile_new_jobs()) { - CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); - log_sweep("restart_compiler"); - } - } + OrderAccess::storestore(); } void NMethodSweeper::possibly_sweep() { assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode"); - if (!MethodFlushing || !sweep_in_progress()) return; + if (!MethodFlushing || !sweep_in_progress()) { + return; + } if (_invocations > 0) { // Only one thread at a time will sweep @@ -258,8 +265,7 @@ void NMethodSweeper::sweep_code_cache() { if (!CompileBroker::should_compile_new_jobs()) { // If we have turned off compilations we might as well do full sweeps // in order to reach the clean state faster. Otherwise the sleeping compiler - // threads will slow down sweeping. After a few iterations the cache - // will be clean and sweeping stops (_resweep will not be set) + // threads will slow down sweeping. _invocations = 1; } @@ -271,9 +277,11 @@ void NMethodSweeper::sweep_code_cache() { int todo = (CodeCache::nof_nmethods() - _seen) / _invocations; int swept_count = 0; + assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); assert(!CodeCache_lock->owned_by_self(), "just checking"); + int freed_memory = 0; { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); @@ -299,7 +307,7 @@ void NMethodSweeper::sweep_code_cache() { // Now ready to process nmethod and give up CodeCache_lock { MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - process_nmethod(_current); + freed_memory += process_nmethod(_current); } _seen++; _current = next; @@ -308,11 +316,11 @@ void NMethodSweeper::sweep_code_cache() { assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache"); - if (!sweep_in_progress() && !_resweep && (_locked_seen || _not_entrant_seen_on_stack)) { + if (!sweep_in_progress() && !need_marking_phase() && (_locked_seen || _not_entrant_seen_on_stack)) { // we've completed a scan without making progress but there were // nmethods we were unable to process either because they were - // locked or were still on stack. We don't have to aggresively - // clean them up so just stop scanning. We could scan once more + // locked or were still on stack. We don't have to aggressively + // clean them up so just stop scanning. We could scan once more // but that complicates the control logic and it's unlikely to // matter much. if (PrintMethodFlushing) { @@ -351,9 +359,16 @@ void NMethodSweeper::sweep_code_cache() { log_sweep("finished"); } - // Sweeper is the only case where memory is released, - // check here if it is time to restart the compiler. - if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs() && !CodeCache::needs_flushing()) { + // Sweeper is the only case where memory is released, check here if it + // is time to restart the compiler. Only checking if there is a certain + // amount of free memory in the code cache might lead to re-enabling + // compilation although no memory has been released. For example, there are + // cases when compilation was disabled although there is 4MB (or more) free + // memory in the code cache. The reason is code cache fragmentation. Therefore, + // it only makes sense to re-enable compilation if we have actually freed memory. + // Note that typically several kB are released for sweeping 16MB of the code + // cache. As a result, 'freed_memory' > 0 to restart the compiler. + if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() && (freed_memory > 0))) { CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); log_sweep("restart_compiler"); } @@ -367,8 +382,8 @@ class NMethodMarker: public StackObj { _thread = CompilerThread::current(); if (!nm->is_zombie() && !nm->is_unloaded()) { // Only expose live nmethods for scanning - _thread->set_scanned_nmethod(nm); - } + _thread->set_scanned_nmethod(nm); + } } ~NMethodMarker() { _thread->set_scanned_nmethod(NULL); @@ -392,20 +407,20 @@ void NMethodSweeper::release_nmethod(nmethod *nm) { nm->flush(); } -void NMethodSweeper::process_nmethod(nmethod *nm) { +int NMethodSweeper::process_nmethod(nmethod *nm) { assert(!CodeCache_lock->owned_by_self(), "just checking"); + int freed_memory = 0; // Make sure this nmethod doesn't get unloaded during the scan, - // since the locks acquired below might safepoint. + // since safepoints may happen during acquired below locks. NMethodMarker nmm(nm); - SWEEP(nm); // Skip methods that are currently referenced by the VM if (nm->is_locked_by_vm()) { // But still remember to clean-up inline caches for alive nmethods if (nm->is_alive()) { - // Clean-up all inline caches that points to zombie/non-reentrant methods + // Clean inline caches that point to zombie/non-entrant methods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); SWEEP(nm); @@ -413,18 +428,19 @@ void NMethodSweeper::process_nmethod(nmethod *nm) { _locked_seen++; SWEEP(nm); } - return; + return freed_memory; } if (nm->is_zombie()) { - // If it is first time, we see nmethod then we mark it. Otherwise, - // we reclame it. When we have seen a zombie method twice, we know that + // If it is the first time we see nmethod then we mark it. Otherwise, + // we reclaim it. When we have seen a zombie method twice, we know that // there are no inline caches that refer to it. if (nm->is_marked_for_reclamation()) { assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); if (PrintMethodFlushing && Verbose) { tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); } + freed_memory = nm->total_size(); release_nmethod(nm); _flushed_count++; } else { @@ -432,19 +448,19 @@ void NMethodSweeper::process_nmethod(nmethod *nm) { tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); } nm->mark_for_reclamation(); - _resweep = true; + request_nmethod_marking(); _marked_count++; SWEEP(nm); } } else if (nm->is_not_entrant()) { - // If there is no current activations of this method on the + // If there are no current activations of this method on the // stack we can safely convert it to a zombie method if (nm->can_not_entrant_be_converted()) { if (PrintMethodFlushing && Verbose) { tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); } nm->make_zombie(); - _resweep = true; + request_nmethod_marking(); _zombified_count++; SWEEP(nm); } else { @@ -459,159 +475,57 @@ void NMethodSweeper::process_nmethod(nmethod *nm) { } } else if (nm->is_unloaded()) { // Unloaded code, just make it a zombie - if (PrintMethodFlushing && Verbose) + if (PrintMethodFlushing && Verbose) { tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); - + } if (nm->is_osr_method()) { SWEEP(nm); // No inline caches will ever point to osr methods, so we can just remove it + freed_memory = nm->total_size(); release_nmethod(nm); _flushed_count++; } else { nm->make_zombie(); - _resweep = true; + request_nmethod_marking(); _zombified_count++; SWEEP(nm); } } else { - assert(nm->is_alive(), "should be alive"); - if (UseCodeCacheFlushing) { - if (nm->is_speculatively_disconnected() && !nm->is_locked_by_vm() && !nm->is_osr_method() && - (_traversals > _last_flush_traversal_id + 2) && (nm->compile_id() < _highest_marked)) { - // This method has not been called since the forced cleanup happened - nm->make_not_entrant(); + if (!nm->is_locked_by_vm() && !nm->is_osr_method() && !nm->is_native_method()) { + // Do not make native methods and OSR-methods not-entrant + nm->dec_hotness_counter(); + // Get the initial value of the hotness counter. This value depends on the + // ReservedCodeCacheSize + int reset_val = hotness_counter_reset_val(); + int time_since_reset = reset_val - nm->hotness_counter(); + double threshold = -reset_val + (CodeCache::reverse_free_ratio() * NmethodSweepActivity); + // The less free space in the code cache we have - the bigger reverse_free_ratio() is. + // I.e., 'threshold' increases with lower available space in the code cache and a higher + // NmethodSweepActivity. If the current hotness counter - which decreases from its initial + // value until it is reset by stack walking - is smaller than the computed threshold, the + // corresponding nmethod is considered for removal. + if ((NmethodSweepActivity > 0) && (nm->hotness_counter() < threshold) && (time_since_reset > 10)) { + // A method is marked as not-entrant if the method is + // 1) 'old enough': nm->hotness_counter() < threshold + // 2) The method was in_use for a minimum amount of time: (time_since_reset > 10) + // The second condition is necessary if we are dealing with very small code cache + // sizes (e.g., <10m) and the code cache size is too small to hold all hot methods. + // The second condition ensures that methods are not immediately made not-entrant + // after compilation. + nm->make_not_entrant(); + request_nmethod_marking(); + } } } - - // Clean-up all inline caches that points to zombie/non-reentrant methods + // Clean-up all inline caches that point to zombie/non-reentrant methods MutexLocker cl(CompiledIC_lock); nm->cleanup_inline_caches(); SWEEP(nm); } + return freed_memory; } -// Code cache unloading: when compilers notice the code cache is getting full, -// they will call a vm op that comes here. This code attempts to speculatively -// unload the oldest half of the nmethods (based on the compile job id) by -// saving the old code in a list in the CodeCache. Then -// execution resumes. If a method so marked is not called by the second sweeper -// stack traversal after the current one, the nmethod will be marked non-entrant and -// got rid of by normal sweeping. If the method is called, the Method*'s -// _code field is restored and the Method*/nmethod -// go back to their normal state. -void NMethodSweeper::handle_full_code_cache(bool is_full) { - - if (is_full) { - // Since code cache is full, immediately stop new compiles - if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) { - log_sweep("disable_compiler"); - } - } - - // Make sure only one thread can flush - // The token is reset after CodeCacheMinimumFlushInterval in scan stacks, - // no need to check the timeout here. - jint old = Atomic::cmpxchg( 1, &_flush_token, 0 ); - if (old != 0) { - return; - } - - VM_HandleFullCodeCache op(is_full); - VMThread::execute(&op); - - // resweep again as soon as possible - _resweep = true; -} - -void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) { - // If there was a race in detecting full code cache, only run - // one vm op for it or keep the compiler shut off - - jlong disconnect_start_counter = os::elapsed_counter(); - - // Traverse the code cache trying to dump the oldest nmethods - int curr_max_comp_id = CompileBroker::get_compilation_id(); - int flush_target = ((curr_max_comp_id - _dead_compile_ids) / CodeCacheFlushingFraction) + _dead_compile_ids; - - log_sweep("start_cleaning"); - - nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); - jint disconnected = 0; - jint made_not_entrant = 0; - jint nmethod_count = 0; - - while ((nm != NULL)){ - int curr_comp_id = nm->compile_id(); - - // OSR methods cannot be flushed like this. Also, don't flush native methods - // since they are part of the JDK in most cases - if (!nm->is_osr_method() && !nm->is_locked_by_vm() && !nm->is_native_method()) { - - // only count methods that can be speculatively disconnected - nmethod_count++; - - if (nm->is_in_use() && (curr_comp_id < flush_target)) { - if ((nm->method()->code() == nm)) { - // This method has not been previously considered for - // unloading or it was restored already - CodeCache::speculatively_disconnect(nm); - disconnected++; - } else if (nm->is_speculatively_disconnected()) { - // This method was previously considered for preemptive unloading and was not called since then - CompilationPolicy::policy()->delay_compilation(nm->method()); - nm->make_not_entrant(); - made_not_entrant++; - } - - if (curr_comp_id > _highest_marked) { - _highest_marked = curr_comp_id; - } - } - } - nm = CodeCache::alive_nmethod(CodeCache::next(nm)); - } - - // remember how many compile_ids wheren't seen last flush. - _dead_compile_ids = curr_max_comp_id - nmethod_count; - - log_sweep("stop_cleaning", - "disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'", - disconnected, made_not_entrant); - - // Shut off compiler. Sweeper will start over with a new stack scan and - // traversal cycle and turn it back on if it clears enough space. - if (is_full) { - _last_full_flush_time = os::javaTimeMillis(); - } - - jlong disconnect_end_counter = os::elapsed_counter(); - jlong disconnect_time = disconnect_end_counter - disconnect_start_counter; - _total_disconnect_time += disconnect_time; - _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time); - - EventCleanCodeCache event(UNTIMED); - if (event.should_commit()) { - event.set_starttime(disconnect_start_counter); - event.set_endtime(disconnect_end_counter); - event.set_disconnectedCount(disconnected); - event.set_madeNonEntrantCount(made_not_entrant); - event.commit(); - } - _number_of_flushes++; - - // After two more traversals the sweeper will get rid of unrestored nmethods - _last_flush_traversal_id = _traversals; - _resweep = true; -#ifdef ASSERT - - if(PrintMethodFlushing && Verbose) { - tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time); - } -#endif -} - - // Print out some state information about the current sweep and the // state of the code cache if it's requested. void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp index da4a13adc77..bd351760769 100644 --- a/hotspot/src/share/vm/runtime/sweeper.hpp +++ b/hotspot/src/share/vm/runtime/sweeper.hpp @@ -27,8 +27,30 @@ // An NmethodSweeper is an incremental cleaner for: // - cleanup inline caches -// - reclamation of unreferences zombie nmethods -// +// - reclamation of nmethods +// Removing nmethods from the code cache includes two operations +// 1) mark active nmethods +// Is done in 'mark_active_nmethods()'. This function is called at a +// safepoint and marks all nmethods that are active on a thread's stack. +// 2) sweep nmethods +// Is done in sweep_code_cache(). This function is the only place in the +// sweeper where memory is reclaimed. Note that sweep_code_cache() is not +// called at a safepoint. However, sweep_code_cache() stops executing if +// another thread requests a safepoint. Consequently, 'mark_active_nmethods()' +// and sweep_code_cache() cannot execute at the same time. +// To reclaim memory, nmethods are first marked as 'not-entrant'. Methods can +// be made not-entrant by (i) the sweeper, (ii) deoptimization, (iii) dependency +// invalidation, and (iv) being replaced be a different method version (tiered +// compilation). Not-entrant nmethod cannot be called by Java threads, but they +// can still be active on the stack. To ensure that active nmethod are not reclaimed, +// we have to wait until the next marking phase has completed. If a not-entrant +// nmethod was NOT marked as active, it can be converted to 'zombie' state. To safely +// remove the nmethod, all inline caches (IC) that point to the the nmethod must be +// cleared. After that, the nmethod can be evicted from the code cache. Each nmethod's +// state change happens during separate sweeps. It may take at least 3 sweeps before an +// nmethod's space is freed. Sweeping is currently done by compiler threads between +// compilations or at least each 5 sec (NmethodSweepCheckInterval) when the code cache +// is full. class NMethodSweeper : public AllStatic { static long _traversals; // Stack scan count, also sweep ID. @@ -41,46 +63,38 @@ class NMethodSweeper : public AllStatic { static volatile int _invocations; // No. of invocations left until we are completed with this pass static volatile int _sweep_started; // Flag to control conc sweeper - //The following are reset in scan_stacks and synchronized by the safepoint - static bool _resweep; // Indicates that a change has happend and we want another sweep, - // always checked and reset at a safepoint so memory will be in sync. - static int _locked_seen; // Number of locked nmethods encountered during the scan + //The following are reset in mark_active_nmethods and synchronized by the safepoint + static bool _request_mark_phase; // Indicates that a change has happend and we need another mark pahse, + // always checked and reset at a safepoint so memory will be in sync. + static int _locked_seen; // Number of locked nmethods encountered during the scan static int _not_entrant_seen_on_stack; // Number of not entrant nmethod were are still on stack - static jint _flush_token; // token that guards method flushing, making sure it is executed only once. - - // These are set during a flush, a VM-operation - static long _last_flush_traversal_id; // trav number at last flush unloading - static jlong _last_full_flush_time; // timestamp of last emergency unloading - - // These are synchronized by the _sweep_started token - static int _highest_marked; // highest compile id dumped at last emergency unloading - static int _dead_compile_ids; // number of compile ids that where not in the cache last flush // Stat counters - static int _number_of_flushes; // Total of full traversals caused by full cache static int _total_nof_methods_reclaimed; // Accumulated nof methods flushed static jlong _total_time_sweeping; // Accumulated time sweeping static jlong _total_time_this_sweep; // Total time this sweep static jlong _peak_sweep_time; // Peak time for a full sweep static jlong _peak_sweep_fraction_time; // Peak time sweeping one fraction - static jlong _total_disconnect_time; // Total time cleaning code mem - static jlong _peak_disconnect_time; // Peak time cleaning code mem - static void process_nmethod(nmethod *nm); + static int process_nmethod(nmethod *nm); static void release_nmethod(nmethod* nm); - static void log_sweep(const char* msg, const char* format = NULL, ...); static bool sweep_in_progress(); + static void sweep_code_cache(); + static void request_nmethod_marking() { _request_mark_phase = true; } + static void reset_nmethod_marking() { _request_mark_phase = false; } + static bool need_marking_phase() { return _request_mark_phase; } + + static int _hotness_counter_reset_val; public: static long traversal_count() { return _traversals; } - static int number_of_flushes() { return _number_of_flushes; } static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } static jlong total_time_sweeping() { return _total_time_sweeping; } static jlong peak_sweep_time() { return _peak_sweep_time; } static jlong peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } - static jlong total_disconnect_time() { return _total_disconnect_time; } - static jlong peak_disconnect_time() { return _peak_disconnect_time; } + static void log_sweep(const char* msg, const char* format = NULL, ...); + #ifdef ASSERT static bool is_sweeping(nmethod* which) { return _current == which; } @@ -90,19 +104,18 @@ class NMethodSweeper : public AllStatic { static void report_events(); #endif - static void scan_stacks(); // Invoked at the end of each safepoint - static void sweep_code_cache(); // Concurrent part of sweep job - static void possibly_sweep(); // Compiler threads call this to sweep + static void mark_active_nmethods(); // Invoked at the end of each safepoint + static void possibly_sweep(); // Compiler threads call this to sweep - static void notify(nmethod* nm) { + static int sort_nmethods_by_hotness(nmethod** nm1, nmethod** nm2); + static int hotness_counter_reset_val(); + + static void notify() { // Request a new sweep of the code cache from the beginning. No // need to synchronize the setting of this flag since it only // changes to false at safepoint so we can never overwrite it with false. - _resweep = true; + request_nmethod_marking(); } - - static void handle_full_code_cache(bool is_full); // Called by compilers who fail to allocate - static void speculative_disconnect_nmethods(bool was_full); // Called by vm op to deal with alloc failure }; #endif // SHARE_VM_RUNTIME_SWEEPER_HPP diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index e526c76075c..e274b903442 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -842,7 +842,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; nonstatic_field(nmethod, _osr_link, nmethod*) \ nonstatic_field(nmethod, _scavenge_root_link, nmethod*) \ nonstatic_field(nmethod, _scavenge_root_state, jbyte) \ - nonstatic_field(nmethod, _state, unsigned char) \ + nonstatic_field(nmethod, _state, volatile unsigned char) \ nonstatic_field(nmethod, _exception_offset, int) \ nonstatic_field(nmethod, _deoptimize_offset, int) \ nonstatic_field(nmethod, _deoptimize_mh_offset, int) \ @@ -1360,6 +1360,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_integer_type(long) \ declare_integer_type(char) \ declare_unsigned_integer_type(unsigned char) \ + declare_unsigned_integer_type(volatile unsigned char) \ declare_unsigned_integer_type(u_char) \ declare_unsigned_integer_type(unsigned int) \ declare_unsigned_integer_type(uint) \ @@ -1382,6 +1383,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; declare_toplevel_type(char**) \ declare_toplevel_type(u_char*) \ declare_toplevel_type(unsigned char*) \ + declare_toplevel_type(volatile unsigned char*) \ \ /*******************************************************************/ \ /* Types which it will be handy to have available over in the SA */ \ diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp index 5166cfdaae1..e26c3938b20 100644 --- a/hotspot/src/share/vm/runtime/vm_operations.cpp +++ b/hotspot/src/share/vm/runtime/vm_operations.cpp @@ -173,10 +173,6 @@ void VM_UnlinkSymbols::doit() { SymbolTable::unlink(); } -void VM_HandleFullCodeCache::doit() { - NMethodSweeper::speculative_disconnect_nmethods(_is_full); -} - void VM_Verify::doit() { Universe::heap()->prepare_for_verify(); Universe::verify(_silent); diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp index b6555b45704..ca616a52cf4 100644 --- a/hotspot/src/share/vm/runtime/vm_operations.hpp +++ b/hotspot/src/share/vm/runtime/vm_operations.hpp @@ -51,7 +51,6 @@ template(DeoptimizeAll) \ template(ZombieAll) \ template(UnlinkSymbols) \ - template(HandleFullCodeCache) \ template(Verify) \ template(PrintJNI) \ template(HeapDumper) \ @@ -261,16 +260,6 @@ class VM_DeoptimizeFrame: public VM_Operation { bool allow_nested_vm_operations() const { return true; } }; -class VM_HandleFullCodeCache: public VM_Operation { - private: - bool _is_full; - public: - VM_HandleFullCodeCache(bool is_full) { _is_full = is_full; } - VMOp_Type type() const { return VMOp_HandleFullCodeCache; } - void doit(); - bool allow_nested_vm_operations() const { return true; } -}; - #ifndef PRODUCT class VM_DeoptimizeAll: public VM_Operation { private: diff --git a/hotspot/src/share/vm/trace/trace.xml b/hotspot/src/share/vm/trace/trace.xml index 6b1d9a8850f..a4286116a67 100644 --- a/hotspot/src/share/vm/trace/trace.xml +++ b/hotspot/src/share/vm/trace/trace.xml @@ -313,13 +313,6 @@ Declares a structure type that can be used in other events. - - - - - Date: Sat, 28 Sep 2013 12:32:09 +0400 Subject: [PATCH 223/293] 8024678: Java source files in hotspot/test/testlibrary should not use @author tag in JavaDoc Reviewed-by: twisti --- .../ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java | 3 +-- .../ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java | 1 - .../ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java | 2 -- .../ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java | 2 -- .../ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java | 3 --- .../testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java | 2 -- .../testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java | 3 --- .../test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java | 2 -- 8 files changed, 1 insertion(+), 17 deletions(-) diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java index 3ee3526568d..b1e8fe294f4 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java @@ -36,8 +36,7 @@ import java.nio.file.*; import java.nio.file.attribute.*; /** - * * Handler for dirs containing classes to compile. - * @author igor.ignatyev@oracle.com + * Handler for dirs containing classes to compile. */ public class ClassPathDirEntry extends PathHandler { diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java index 3d39f1b2573..a639a637159 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java @@ -35,7 +35,6 @@ import java.nio.file.*; /** * Handler for jar-files containing classes to compile. - * @author igor.ignatyev@oracle.com */ public class ClassPathJarEntry extends PathHandler { diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java index 328280a2d88..a9f7c8a964e 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java @@ -31,8 +31,6 @@ import java.util.concurrent.Executor; /** * Handler for dirs containing jar-files with classes to compile. - * - * @author igor.ignatyev@oracle.com */ public class ClassPathJarInDirEntry extends PathHandler { diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java index 6f36d8b5c6d..d25364ad561 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java @@ -32,8 +32,6 @@ import java.util.concurrent.Executor; /** * Handler for files containing a list of classes to compile. - * - * @author igor.ignatyev@oracle.com */ public class ClassesListInFile extends PathHandler { public ClassesListInFile(Path root, Executor executor) { diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java index f1d46526d31..12d09434d7b 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java @@ -32,9 +32,6 @@ import java.nio.file.Paths; import java.util.List; import java.util.concurrent.*; -/** - * @author igor.ignatyev@oracle.com - */ public class CompileTheWorld { /** * Entry point. Compiles classes in {@code args}, or all classes in diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java index ccb2d3ae53a..1a5a034869a 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java @@ -36,8 +36,6 @@ import java.util.concurrent.atomic.AtomicLong; /** * Provide method to compile whole class. * Also contains compiled methods and classes counters. - * - * @author igor.ignatyev@oracle.com */ public class Compiler { private Compiler() { } diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java index 5c284f896a8..04b23e75770 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java @@ -35,10 +35,7 @@ import java.util.concurrent.Executor; /** * Abstract handler for path. - *

    * Concrete subclasses should implement method {@link #process()}. - * - * @author igor.ignatyev@oracle.com */ public abstract class PathHandler { private static final Pattern JAR_IN_DIR_PATTERN diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java index 5ffd06cee8b..ea621cb7b39 100644 --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java @@ -31,8 +31,6 @@ import java.util.regex.Pattern; /** * Auxiliary methods. - * - * @author igor.ignatyev@oracle.com */ public class Utils { /** From 30874d35f19cc7f185342c7ebaa11bd525412601 Mon Sep 17 00:00:00 2001 From: Igor Ignatyev Date: Sat, 28 Sep 2013 12:32:10 +0400 Subject: [PATCH 224/293] 8023452: TestCase$Helper(java.lang.Object) must be osr_compiled Reviewed-by: kvn --- hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java | 5 ++++- hotspot/test/compiler/whitebox/DeoptimizeAllTest.java | 6 ++++++ hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java | 6 ++++++ .../compiler/whitebox/EnqueueMethodForCompilationTest.java | 6 ++---- hotspot/test/compiler/whitebox/IsMethodCompilableTest.java | 6 ++++++ .../test/compiler/whitebox/MakeMethodNotCompilableTest.java | 6 ++++++ 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java index f6c2414f17d..0058981be21 100644 --- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java +++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java @@ -74,6 +74,9 @@ public abstract class CompilerWhiteBoxTest { protected static final int THRESHOLD; /** count of invocation to triger OSR compilation */ protected static final long BACKEDGE_THRESHOLD; + /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ + protected static final String MODE + = System.getProperty("java.vm.info"); static { if (TIERED_COMPILATION) { @@ -202,7 +205,7 @@ public abstract class CompilerWhiteBoxTest { if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { throw new RuntimeException(method + " osr_comp_level must be == 0"); } - } + } /** * Checks, that {@linkplain #method} is compiled. diff --git a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java index 2f49d054a48..61d8b599845 100644 --- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java +++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java @@ -53,6 +53,12 @@ public class DeoptimizeAllTest extends CompilerWhiteBoxTest { */ @Override protected void test() throws Exception { + if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith( + "compiled ")) { + System.err.printf("Warning: %s is not applicable in %s%n", + testCase.name(), CompilerWhiteBoxTest.MODE); + return; + } compile(); checkCompiled(); WHITE_BOX.deoptimizeAll(); diff --git a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java index 502c9b77fb7..8ac065bd1e8 100644 --- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java +++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java @@ -53,6 +53,12 @@ public class DeoptimizeMethodTest extends CompilerWhiteBoxTest { */ @Override protected void test() throws Exception { + if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith( + "compiled ")) { + System.err.printf("Warning: %s is not applicable in %s%n", + testCase.name(), CompilerWhiteBoxTest.MODE); + return; + } compile(); checkCompiled(); deoptimize(); diff --git a/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java b/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java index 909a9fda281..6d14d9211e2 100644 --- a/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java +++ b/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java @@ -70,12 +70,10 @@ public class EnqueueMethodForCompilationTest extends CompilerWhiteBoxTest { int compLevel = getCompLevel(); int bci = WHITE_BOX.getMethodEntryBci(method); - System.out.println("bci = " + bci); - printInfo(); deoptimize(); - printInfo(); checkNotCompiled(); - printInfo(); + WHITE_BOX.clearMethodState(method); + WHITE_BOX.enqueueMethodForCompilation(method, compLevel, bci); checkCompiled(); deoptimize(); diff --git a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java index e9817deb1d3..a17fcb82f40 100644 --- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java +++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java @@ -68,6 +68,12 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { */ @Override protected void test() throws Exception { + if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith( + "compiled ")) { + System.err.printf("Warning: %s is not applicable in %s%n", + testCase.name(), CompilerWhiteBoxTest.MODE); + return; + } if (!isCompilable()) { throw new RuntimeException(method + " must be compilable"); } diff --git a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java index 3768b3b0191..6a1e3613fec 100644 --- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java +++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java @@ -62,6 +62,12 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { */ @Override protected void test() throws Exception { + if (testCase.isOsr && CompilerWhiteBoxTest.MODE.startsWith( + "compiled ")) { + System.err.printf("Warning: %s is not applicable in %s%n", + testCase.name(), CompilerWhiteBoxTest.MODE); + return; + } checkNotCompiled(); if (!isCompilable()) { throw new RuntimeException(method + " must be compilable"); From 9376d94e6c2a527593c362159e7597522fbb9ba5 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Sat, 28 Sep 2013 12:42:22 -0700 Subject: [PATCH 225/293] 8025613: clang: remove -Wno-unused-value Reviewed-by: iveresov --- hotspot/agent/src/os/linux/LinuxDebuggerLocal.c | 3 ++- hotspot/agent/src/os/linux/ps_proc.c | 2 ++ hotspot/agent/src/os/linux/salibelf.c | 1 + hotspot/agent/src/os/linux/symtab.c | 2 +- hotspot/make/bsd/makefiles/gcc.make | 4 ++-- hotspot/make/linux/makefiles/gcc.make | 2 +- hotspot/src/cpu/x86/vm/assembler_x86.cpp | 4 ++-- hotspot/src/share/vm/classfile/defaultMethods.cpp | 5 ++--- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c index 17f607e0af0..0d3960f7ae7 100644 --- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c +++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -80,7 +81,7 @@ JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_in (JNIEnv *env, jclass cls) { jclass listClass; - if (init_libproc(getenv("LIBSAPROC_DEBUG")) != true) { + if (init_libproc(getenv("LIBSAPROC_DEBUG") != NULL) != true) { THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc"); } diff --git a/hotspot/agent/src/os/linux/ps_proc.c b/hotspot/agent/src/os/linux/ps_proc.c index 61f08692ca8..61923a25529 100644 --- a/hotspot/agent/src/os/linux/ps_proc.c +++ b/hotspot/agent/src/os/linux/ps_proc.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include "libproc_impl.h" diff --git a/hotspot/agent/src/os/linux/salibelf.c b/hotspot/agent/src/os/linux/salibelf.c index 9634da8be56..4c860a0fe08 100644 --- a/hotspot/agent/src/os/linux/salibelf.c +++ b/hotspot/agent/src/os/linux/salibelf.c @@ -25,6 +25,7 @@ #include "salibelf.h" #include #include +#include extern void print_debug(const char*,...); diff --git a/hotspot/agent/src/os/linux/symtab.c b/hotspot/agent/src/os/linux/symtab.c index bea59e37823..f9fc33f14ec 100644 --- a/hotspot/agent/src/os/linux/symtab.c +++ b/hotspot/agent/src/os/linux/symtab.c @@ -305,7 +305,7 @@ static struct symtab* build_symtab_from_build_id(Elf64_Nhdr *note) unsigned char *bytes = (unsigned char*)(note+1) + note->n_namesz; - unsigned char *filename + char *filename = (build_id_to_debug_filename (note->n_descsz, bytes)); fd = pathmap_open(filename); diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index 0277bb66aa3..37c0268cdbe 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -247,7 +247,7 @@ endif ifeq ($(USE_CLANG), true) # However we need to clean the code up before we can unrestrictedly enable this option with Clang - WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses + WARNINGS_ARE_ERRORS += -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-compare # Not yet supported by clang in Xcode 4.6.2 # WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare @@ -262,7 +262,7 @@ ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& # conversions which might affect the values. Only enable it in earlier versions. WARNING_FLAGS = -Wunused-function ifeq ($(USE_CLANG),) - WARNINGS_FLAGS += -Wconversion + WARNING_FLAGS += -Wconversion endif endif diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make index a62ea4b52ee..bc4a24c7787 100644 --- a/hotspot/make/linux/makefiles/gcc.make +++ b/hotspot/make/linux/makefiles/gcc.make @@ -208,7 +208,7 @@ WARNINGS_ARE_ERRORS = -Werror ifeq ($(USE_CLANG), true) # However we need to clean the code up before we can unrestrictedly enable this option with Clang - WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses + WARNINGS_ARE_ERRORS += -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index 761b5c3259f..53f201b5033 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -4769,7 +4769,7 @@ void Assembler::adcq(Register dst, Address src) { } void Assembler::adcq(Register dst, Register src) { - (int) prefixq_and_encode(dst->encoding(), src->encoding()); + (void) prefixq_and_encode(dst->encoding(), src->encoding()); emit_arith(0x13, 0xC0, dst, src); } @@ -4824,7 +4824,7 @@ void Assembler::andq(Register dst, Address src) { } void Assembler::andq(Register dst, Register src) { - (int) prefixq_and_encode(dst->encoding(), src->encoding()); + (void) prefixq_and_encode(dst->encoding(), src->encoding()); emit_arith(0x23, 0xC0, dst, src); } diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 99a45b55b6d..2adc6268473 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -977,7 +977,7 @@ Method* DefaultMethods::find_super_default( return target; } -#ifndef PRODUCT +#ifdef ASSERT // Return true is broad type is a covariant return of narrow type static bool covariant_return_type(BasicType narrow, BasicType broad) { if (narrow == broad) { @@ -988,7 +988,7 @@ static bool covariant_return_type(BasicType narrow, BasicType broad) { } return false; } -#endif // ndef PRODUCT +#endif static int assemble_redirect( BytecodeConstantPool* cp, BytecodeBuffer* buffer, @@ -1281,4 +1281,3 @@ static void merge_in_new_methods(InstanceKlass* klass, MetadataFactory::free_array(cld, original_ordering); } } - From 84fd9150e25f7c5c6a9e21bc8a7d548ed07230ed Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 27 Sep 2013 11:52:24 +0400 Subject: [PATCH 226/293] 8014447: Object.hashCode intrinsic breaks inline caches Try to inline as normal method first, then fall back to intrinsic. Reviewed-by: kvn, twisti --- hotspot/src/share/vm/opto/callGenerator.hpp | 2 ++ hotspot/src/share/vm/opto/doCall.cpp | 19 ++++++++++++++++++- hotspot/src/share/vm/opto/library_call.cpp | 10 ++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp index a1616de4dc7..956f227c32f 100644 --- a/hotspot/src/share/vm/opto/callGenerator.hpp +++ b/hotspot/src/share/vm/opto/callGenerator.hpp @@ -65,6 +65,8 @@ class CallGenerator : public ResourceObj { virtual bool is_predicted() const { return false; } // is_trap: Does not return to the caller. (E.g., uncommon trap.) virtual bool is_trap() const { return false; } + // does_virtual_dispatch: Should try inlining as normal method first. + virtual bool does_virtual_dispatch() const { return false; } // is_late_inline: supports conversion of call into an inline virtual bool is_late_inline() const { return false; } diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp index 8784bbe2dc5..9558d604068 100644 --- a/hotspot/src/share/vm/opto/doCall.cpp +++ b/hotspot/src/share/vm/opto/doCall.cpp @@ -110,6 +110,7 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool // then we return it as the inlined version of the call. // We do this before the strict f.p. check below because the // intrinsics handle strict f.p. correctly. + CallGenerator* cg_intrinsic = NULL; if (allow_inline && allow_intrinsics) { CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); if (cg != NULL) { @@ -121,7 +122,16 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg); } } - return cg; + + // If intrinsic does the virtual dispatch, we try to use the type profile + // first, and hopefully inline it as the regular virtual call below. + // We will retry the intrinsic if nothing had claimed it afterwards. + if (cg->does_virtual_dispatch()) { + cg_intrinsic = cg; + cg = NULL; + } else { + return cg; + } } } @@ -266,6 +276,13 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool } } + // Nothing claimed the intrinsic, we go with straight-forward inlining + // for already discovered intrinsic. + if (allow_inline && allow_intrinsics && cg_intrinsic != NULL) { + assert(cg_intrinsic->does_virtual_dispatch(), "sanity"); + return cg_intrinsic; + } + // There was no special inlining tactic, or it bailed out. // Use a more generic tactic, like a simple call. if (call_does_dispatch) { diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 90372600190..45b8f333799 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -47,19 +47,22 @@ class LibraryIntrinsic : public InlineCallGenerator { private: bool _is_virtual; bool _is_predicted; + bool _does_virtual_dispatch; vmIntrinsics::ID _intrinsic_id; public: - LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, vmIntrinsics::ID id) + LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool does_virtual_dispatch, vmIntrinsics::ID id) : InlineCallGenerator(m), _is_virtual(is_virtual), _is_predicted(is_predicted), + _does_virtual_dispatch(does_virtual_dispatch), _intrinsic_id(id) { } virtual bool is_intrinsic() const { return true; } virtual bool is_virtual() const { return _is_virtual; } virtual bool is_predicted() const { return _is_predicted; } + virtual bool does_virtual_dispatch() const { return _does_virtual_dispatch; } virtual JVMState* generate(JVMState* jvms); virtual Node* generate_predicate(JVMState* jvms); vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; } @@ -355,6 +358,7 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { } bool is_predicted = false; + bool does_virtual_dispatch = false; switch (id) { case vmIntrinsics::_compareTo: @@ -381,8 +385,10 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { break; case vmIntrinsics::_hashCode: if (!InlineObjectHash) return NULL; + does_virtual_dispatch = true; break; case vmIntrinsics::_clone: + does_virtual_dispatch = true; case vmIntrinsics::_copyOf: case vmIntrinsics::_copyOfRange: if (!InlineObjectCopy) return NULL; @@ -541,7 +547,7 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { if (!InlineUnsafeOps) return NULL; } - return new LibraryIntrinsic(m, is_virtual, is_predicted, (vmIntrinsics::ID) id); + return new LibraryIntrinsic(m, is_virtual, is_predicted, does_virtual_dispatch, (vmIntrinsics::ID) id); } //----------------------register_library_intrinsics----------------------- From 0c588fa80bcee7c34ba79d33088d06bc687cc2de Mon Sep 17 00:00:00 2001 From: Axel Siebenborn Date: Mon, 30 Sep 2013 15:42:39 -0700 Subject: [PATCH 227/293] 8025599: Missing store barrier with OptimizeStringConcat Reviewed-by: kvn, twisti --- hotspot/src/share/vm/opto/graphKit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index dcdd104ee72..684ccc67aa1 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3849,9 +3849,9 @@ void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) { const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), false, NULL, 0); const TypePtr* value_field_type = string_type->add_offset(value_offset); - int value_field_idx = C->get_alias_index(value_field_type); - store_to_memory(ctrl, basic_plus_adr(str, value_offset), - value, T_OBJECT, value_field_idx); + + store_oop_to_object(ctrl, str, basic_plus_adr(str, value_offset), value_field_type, + value, TypeAryPtr::CHARS, T_OBJECT); } void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) { From 02f6818d8f472a5b1897a78c67a1a8bb72e259fd Mon Sep 17 00:00:00 2001 From: David Chase Date: Fri, 27 Sep 2013 13:36:25 -0400 Subject: [PATCH 228/293] 8025260: Methodhandles/JSR292: NullPointerException (NPE) thrown instead of AbstractMethodError (AME) Copied null-checks from templateInterpreter_CPU into methodHandles_CPU Reviewed-by: jrose, twisti --- .../src/cpu/sparc/vm/methodHandles_sparc.cpp | 14 +- hotspot/src/cpu/x86/vm/methodHandles_x86.cpp | 10 +- .../ByteClassLoader.java | 44 ++++++ .../jsr292/methodHandleExceptions/C.java | 33 ++++ .../jsr292/methodHandleExceptions/I.java | 27 ++++ .../methodHandleExceptions/TestAMEnotNPE.java | 143 ++++++++++++++++++ 6 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 hotspot/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java create mode 100644 hotspot/test/compiler/jsr292/methodHandleExceptions/C.java create mode 100644 hotspot/test/compiler/jsr292/methodHandleExceptions/I.java create mode 100644 hotspot/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java diff --git a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp index 546cfaf08f1..af6d6289644 100644 --- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,6 +121,7 @@ void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Registe void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp, bool for_compiler_entry) { + Label L_no_such_method; assert(method == G5_method, "interpreter calling convention"); assert_different_registers(method, target, temp); @@ -133,6 +134,9 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset()); __ ld(interp_only, temp); __ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code); + // Null method test is replicated below in compiled case, + // it might be able to address across the verify_thread() + __ br_null_short(G5_method, Assembler::pn, L_no_such_method); __ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), target); __ jmp(target, 0); __ delayed()->nop(); @@ -141,11 +145,19 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth // it doesn't matter, since this is interpreter code. } + // Compiled case, either static or fall-through from runtime conditional + __ br_null_short(G5_method, Assembler::pn, L_no_such_method); + const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : Method::from_interpreted_offset(); __ ld_ptr(G5_method, in_bytes(entry_offset), target); __ jmp(target, 0); __ delayed()->nop(); + + __ bind(L_no_such_method); + AddressLiteral ame(StubRoutines::throw_AbstractMethodError_entry()); + __ jump_to(ame, temp); + __ delayed()->nop(); } void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp index 30c9199436d..2a8fdd56be0 100644 --- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp +++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,6 +114,11 @@ void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Registe void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp, bool for_compiler_entry) { assert(method == rbx, "interpreter calling convention"); + + Label L_no_such_method; + __ testptr(rbx, rbx); + __ jcc(Assembler::zero, L_no_such_method); + __ verify_method_ptr(method); if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) { @@ -138,6 +143,9 @@ void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register meth const ByteSize entry_offset = for_compiler_entry ? Method::from_compiled_offset() : Method::from_interpreted_offset(); __ jmp(Address(method, entry_offset)); + + __ bind(L_no_such_method); + __ jump(RuntimeAddress(StubRoutines::throw_AbstractMethodError_entry())); } void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm, diff --git a/hotspot/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java b/hotspot/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java new file mode 100644 index 00000000000..de257ad71ff --- /dev/null +++ b/hotspot/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * A minimal classloader for loading bytecodes that could not result from + * properly compiled Java. + * + * @author dr2chase + */ +public class ByteClassLoader extends ClassLoader { + /** + * (pre)load class name using classData for the definition. + * + * @param name + * @param classData + * @return + */ + public Class loadBytes(String name, byte[] classData) { + Class clazz = defineClass(name, classData, 0, classData.length); + resolveClass(clazz); + return clazz; + } +} diff --git a/hotspot/test/compiler/jsr292/methodHandleExceptions/C.java b/hotspot/test/compiler/jsr292/methodHandleExceptions/C.java new file mode 100644 index 00000000000..86678967faf --- /dev/null +++ b/hotspot/test/compiler/jsr292/methodHandleExceptions/C.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * Test class -- implements I, which provides default for m, but this class + * declares it abstract which (should) hide the interface default, and throw + * an abstract method error if it is called (calling it requires bytecode hacking + * or inconsistent compilation). + */ +public abstract class C implements I { + public abstract int m(); +} diff --git a/hotspot/test/compiler/jsr292/methodHandleExceptions/I.java b/hotspot/test/compiler/jsr292/methodHandleExceptions/I.java new file mode 100644 index 00000000000..f4cc27e3994 --- /dev/null +++ b/hotspot/test/compiler/jsr292/methodHandleExceptions/I.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +public interface I { + default public int m() { return 1; } +} diff --git a/hotspot/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java b/hotspot/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java new file mode 100644 index 00000000000..2b41c15f87b --- /dev/null +++ b/hotspot/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import java.lang.reflect.InvocationTargetException; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.Handle; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; + +/** + * @test + * @bug 8025260 + * @summary Ensure that AbstractMethodError is thrown, not NullPointerException, through MethodHandles::jump_from_method_handle code path + * + * @compile -XDignore.symbol.file ByteClassLoader.java I.java C.java TestAMEnotNPE.java + * @run main/othervm TestAMEnotNPE + */ + +public class TestAMEnotNPE implements Opcodes { + + /** + * The bytes for D, a NOT abstract class extending abstract class C + * without supplying an implementation for abstract method m. + * There is a default method in the interface I, but it should lose to + * the abstract class. + + class D extends C { + D() { super(); } + // does not define m + } + + * @return + * @throws Exception + */ + public static byte[] bytesForD() throws Exception { + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); + MethodVisitor mv; + + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "D", null, "C", null); + + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "C", "", "()V"); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + cw.visitEnd(); + + return cw.toByteArray(); + } + + + /** + * The bytecodes for an invokeExact of a particular methodHandle, I.m, invoked on a D + + class T { + T() { super(); } // boring constructor + int test() { + MethodHandle mh = `I.m():int`; + D d = new D(); + return mh.invokeExact(d); // Should explode here, AbstractMethodError + } + } + + * @return + * @throws Exception + */ + public static byte[] bytesForT() throws Exception { + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); + MethodVisitor mv; + + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "T", null, "java/lang/Object", null); + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); + mv.visitInsn(RETURN); + mv.visitMaxs(0,0); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "()I", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "I", "m", "()I")); + mv.visitTypeInsn(NEW, "D"); + mv.visitInsn(DUP); + mv.visitMethodInsn(INVOKESPECIAL, "D", "", "()V"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeExact", "(LI;)I"); + mv.visitInsn(IRETURN); + mv.visitMaxs(0,0); + mv.visitEnd(); + } + cw.visitEnd(); + return cw.toByteArray(); + } + + public static void main(String args[] ) throws Throwable { + ByteClassLoader bcl = new ByteClassLoader(); + Class d = bcl.loadBytes("D", bytesForD()); + Class t = bcl.loadBytes("T", bytesForT()); + try { + Object result = t.getMethod("test").invoke(null); + System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw no exception"); + throw new Error("Missing expected exception"); + } catch (InvocationTargetException e) { + Throwable th = e.getCause(); + if (th instanceof AbstractMethodError) { + th.printStackTrace(System.out); + System.out.println("PASS, saw expected exception (AbstractMethodError, wrapped in InvocationTargetException)."); + } else { + System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw " + th); + throw th; + } + } + } +} From b364358afe42fd46f5db03767f1883f1d84a4833 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Fri, 27 Sep 2013 13:49:57 -0400 Subject: [PATCH 229/293] 8024990: JT_JDK: 11 failures with SIGSEGV on arm-sflt platforms in nightly fastdebug build Enable patching for load_appendix_id. Reviewed-by: kvn, dlong, bdelsart --- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 037bc31f658..df063204338 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -1078,14 +1078,17 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i // replace instructions // first replace the tail, then the call #ifdef ARM - if(load_klass_or_mirror_patch_id && !VM_Version::supports_movw()) { + if((load_klass_or_mirror_patch_id || + stub_id == Runtime1::load_appendix_patching_id) && + !VM_Version::supports_movw()) { nmethod* nm = CodeCache::find_nmethod(instr_pc); address addr = NULL; assert(nm != NULL, "invalid nmethod_pc"); RelocIterator mds(nm, copy_buff, copy_buff + 1); while (mds.next()) { if (mds.type() == relocInfo::oop_type) { - assert(stub_id == Runtime1::load_mirror_patching_id, "wrong stub id"); + assert(stub_id == Runtime1::load_mirror_patching_id || + stub_id == Runtime1::load_appendix_patching_id, "wrong stub id"); oop_Relocation* r = mds.oop_reloc(); addr = (address)r->oop_addr(); break; From 2c516bc7b4990e1b29ca1d28fa563baa3caa0e58 Mon Sep 17 00:00:00 2001 From: Patrick Reinhart Date: Fri, 27 Sep 2013 13:04:54 -0700 Subject: [PATCH 230/293] 6870661: Setting a custom PrintService on a PrinterJob leads to a PrinterException Reviewed-by: prr, jgodinez --- .../classes/sun/awt/windows/WPrinterJob.java | 9 +- .../CustomPrintService/PrintDialog.java | 59 +++++++ .../CustomPrintService/PrintServiceStub.java | 160 ++++++++++++++++++ .../SetPrintServiceTest.java | 48 ++++++ 4 files changed, 271 insertions(+), 5 deletions(-) create mode 100644 jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java create mode 100644 jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintServiceStub.java create mode 100644 jdk/test/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java diff --git a/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java b/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java index 519a0be422e..6f22231a53c 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java +++ b/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java @@ -96,7 +96,6 @@ import javax.print.attribute.standard.PrinterName; import javax.print.attribute.standard.JobMediaSheetsSupported; import javax.print.attribute.standard.PageRanges; import javax.print.attribute.Size2DSyntax; -import javax.print.StreamPrintService; import sun.awt.Win32FontManager; @@ -440,7 +439,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { throw new HeadlessException(); } - if (getPrintService() instanceof StreamPrintService) { + if (!(getPrintService() instanceof Win32PrintService)) { return super.pageDialog(page); } @@ -586,7 +585,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { attributes = new HashPrintRequestAttributeSet(); } - if (getPrintService() instanceof StreamPrintService) { + if (!(getPrintService() instanceof Win32PrintService)) { return super.printDialog(attributes); } @@ -611,7 +610,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { public void setPrintService(PrintService service) throws PrinterException { super.setPrintService(service); - if (service instanceof StreamPrintService) { + if (!(service instanceof Win32PrintService)) { return; } driverDoesMultipleCopies = false; @@ -648,7 +647,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { } myService = PrintServiceLookup.lookupDefaultPrintService(); - if (myService != null) { + if (myService instanceof Win32PrintService) { try { setNativePrintServiceIfNeeded(myService.getName()); } catch (Exception e) { diff --git a/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java new file mode 100644 index 00000000000..d18ee86878d --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.*; +import java.awt.print.PrinterJob; +import javax.print.PrintServiceLookup; + +/** + * @test + * @bug 6870661 + * @summary Verify that no native dialog is opened for a custom PrintService + * @run main/manual PrintDialog + * @author reinhapa + */ +public class PrintDialog { + + private static final String instructions = + "This test shows a non native print dialog having a 'test' print service\n" + + "selected. No other options are selectable on the General tab. The other\n" + + "tabs are as follows:\n" + + "Page Setup: Media & Margins enabled, Orientation disabled\n" + + "Appearance: All parts disabled\n\n" + + "Test passes if the dialog is shown as described above."; + + public static void main(String[] args) throws Exception { + // instruction dialog + Frame instruction = new Frame("Verify that no native print dialog is showed"); + instruction.add(new TextArea(instructions)); + instruction.pack(); + instruction.show(); + // test begin + PrintServiceStub service = new PrintServiceStub("test"); + PrintServiceLookup.registerService(service); + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintService(service); + job.printDialog(); + System.out.println("test passed"); + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintServiceStub.java b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintServiceStub.java new file mode 100644 index 00000000000..c430959c42b --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintServiceStub.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintService; +import javax.print.ServiceUIFactory; +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashPrintServiceAttributeSet; +import javax.print.attribute.PrintServiceAttribute; +import javax.print.attribute.PrintServiceAttributeSet; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.standard.PrinterInfo; +import javax.print.attribute.standard.PrinterIsAcceptingJobs; +import javax.print.attribute.standard.PrinterMakeAndModel; +import javax.print.attribute.standard.PrinterName; +import javax.print.attribute.standard.PrinterState; +import javax.print.event.PrintServiceAttributeListener; + +/** + * Stub implementation of a custom {@link PrintService}. + * + * @author reinhapa + */ +public class PrintServiceStub implements PrintService { + private final String _name; + private final Set _flavors; + private final Map, Object> _attributes; + + public PrintServiceStub(String name) { + _name = name; + _flavors = new HashSet(); + _flavors.add(DocFlavor.SERVICE_FORMATTED.PAGEABLE); + _flavors.add(DocFlavor.SERVICE_FORMATTED.PRINTABLE); + _attributes = new HashMap<>(); + _attributes.put(PrinterName.class, new PrinterName(name, null)); + _attributes.put(PrinterState.class, PrinterState.IDLE); + _attributes.put(PrinterInfo.class, new PrinterInfo("Custom location", + null)); + _attributes.put(PrinterIsAcceptingJobs.class, + PrinterIsAcceptingJobs.ACCEPTING_JOBS); + _attributes.put(PrinterMakeAndModel.class, new PrinterMakeAndModel( + "Custom printer", null)); + _attributes.put(Media.class, new Media[] { MediaSizeName.ISO_A4 }); + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean isDocFlavorSupported(DocFlavor flavor) { + return _flavors.contains(flavor); + } + + @Override + public Object getSupportedAttributeValues( + Class category, DocFlavor flavor, + AttributeSet attributes) { + return _attributes.get(category); + } + + @Override + public boolean isAttributeCategorySupported( + Class category) { + return _attributes.containsKey(category); + } + + @Override + public T getAttribute(Class category) { + return category.cast(_attributes.get(category)); + } + + @Override + public PrintServiceAttributeSet getAttributes() { + return new HashPrintServiceAttributeSet(_attributes.values().toArray( + new PrintServiceAttribute[_attributes.size()])); + } + + @Override + public DocFlavor[] getSupportedDocFlavors() { + return _flavors.toArray(new DocFlavor[_flavors.size()]); + } + + // not implemented methods + + @Override + public DocPrintJob createPrintJob() { + return null; + } + + @Override + public void addPrintServiceAttributeListener( + PrintServiceAttributeListener listener) { + + } + + @Override + public void removePrintServiceAttributeListener( + PrintServiceAttributeListener listener) { + + } + + @Override + public Class[] getSupportedAttributeCategories() { + return null; + } + + @Override + public Object getDefaultAttributeValue(Class category) { + return null; + } + + @Override + public boolean isAttributeValueSupported(Attribute attrval, + DocFlavor flavor, AttributeSet attributes) { + return false; + } + + @Override + public AttributeSet getUnsupportedAttributes(DocFlavor flavor, + AttributeSet attributes) { + return null; + } + + @Override + public ServiceUIFactory getServiceUIFactory() { + return null; + } +} diff --git a/jdk/test/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java new file mode 100644 index 00000000000..a6bc7ff9877 --- /dev/null +++ b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; + +/** + * @test + * @bug 6870661 + * @summary tests setPrintService() with a custom implementation + * @author reinhapa + */ +public class SetPrintServiceTest { + + public static void main(String[] args) { + PrintServiceStub service = new PrintServiceStub("CustomPrintService"); + PrinterJob printerJob = PrinterJob.getPrinterJob(); + try { + printerJob.setPrintService(service); + System.out.println("Test Passed"); + } catch (PrinterException e) { + throw new RuntimeException("Test FAILED", e); + } + } + +} From 7001d7b786ab50f0037608266ba6d03e334c40de Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 27 Sep 2013 13:06:47 -0700 Subject: [PATCH 231/293] 8020190: Fatal: Bug in native code: jfieldID must match object Reviewed-by: jgodinez, vadim --- jdk/src/share/classes/sun/font/FreetypeFontScaler.java | 8 ++++---- jdk/src/share/native/sun/font/freetypeScaler.c | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/classes/sun/font/FreetypeFontScaler.java b/jdk/src/share/classes/sun/font/FreetypeFontScaler.java index 3edfe5f0e6a..b4d961a881d 100644 --- a/jdk/src/share/classes/sun/font/FreetypeFontScaler.java +++ b/jdk/src/share/classes/sun/font/FreetypeFontScaler.java @@ -169,7 +169,7 @@ class FreetypeFontScaler extends FontScaler { public synchronized void dispose() { if (nativeScaler != 0L) { - disposeNativeScaler(nativeScaler); + disposeNativeScaler(font.get(), nativeScaler); nativeScaler = 0L; } } @@ -190,7 +190,7 @@ class FreetypeFontScaler extends FontScaler { synchronized int getGlyphCode(char charCode) throws FontScalerException { if (nativeScaler != 0L) { - return getGlyphCodeNative(nativeScaler, charCode); + return getGlyphCodeNative(font.get(), nativeScaler, charCode); } return FontScaler.getNullScaler().getGlyphCode(charCode); } @@ -245,9 +245,9 @@ class FreetypeFontScaler extends FontScaler { private native long getLayoutTableCacheNative(long pScaler); - private native void disposeNativeScaler(long pScaler); + private native void disposeNativeScaler(Font2D font2D, long pScaler); - private native int getGlyphCodeNative(long pScaler, char charCode); + private native int getGlyphCodeNative(Font2D font, long pScaler, char charCode); private native int getNumGlyphsNative(long pScaler); private native int getMissingGlyphCodeNative(long pScaler); diff --git a/jdk/src/share/native/sun/font/freetypeScaler.c b/jdk/src/share/native/sun/font/freetypeScaler.c index e84e77c4207..7e82c4da555 100644 --- a/jdk/src/share/native/sun/font/freetypeScaler.c +++ b/jdk/src/share/native/sun/font/freetypeScaler.c @@ -902,13 +902,13 @@ Java_sun_font_FreetypeFontScaler_getLayoutTableCacheNative( */ JNIEXPORT void JNICALL Java_sun_font_FreetypeFontScaler_disposeNativeScaler( - JNIEnv *env, jobject scaler, jlong pScaler) { + JNIEnv *env, jobject scaler, jobject font2D, jlong pScaler) { FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler); /* Freetype functions *may* cause callback to java that can use cached values. Make sure our cache is up to date. NB: scaler context is not important at this point, can use NULL. */ - int errCode = setupFTContext(env, scaler, scalerInfo, NULL); + int errCode = setupFTContext(env, font2D, scalerInfo, NULL); if (errCode) { return; } @@ -957,7 +957,8 @@ Java_sun_font_FreetypeFontScaler_getMissingGlyphCodeNative( */ JNIEXPORT jint JNICALL Java_sun_font_FreetypeFontScaler_getGlyphCodeNative( - JNIEnv *env, jobject scaler, jlong pScaler, jchar charCode) { + JNIEnv *env, jobject scaler, + jobject font2D, jlong pScaler, jchar charCode) { FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler); int errCode; @@ -970,7 +971,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphCodeNative( /* Freetype functions *may* cause callback to java that can use cached values. Make sure our cache is up to date. Scaler context is not important here, can use NULL. */ - errCode = setupFTContext(env, scaler, scalerInfo, NULL); + errCode = setupFTContext(env, font2D, scalerInfo, NULL); if (errCode) { return 0; } From 4baf04a8492a81fd2c978645783b28532e59a4ac Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Fri, 27 Sep 2013 16:27:34 -0700 Subject: [PATCH 232/293] 8023495: [infra] create 64-bit solaris bits with symlinks Reviewed-by: ihse, tbell, erikj --- common/makefiles/Jprt.gmk | 17 ++++++----------- common/makefiles/Main.gmk | 6 +----- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/common/makefiles/Jprt.gmk b/common/makefiles/Jprt.gmk index 4b19dc45e38..cf05583a869 100644 --- a/common/makefiles/Jprt.gmk +++ b/common/makefiles/Jprt.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -200,13 +200,8 @@ $(JPRT_ARCHIVE_BUNDLE): bundles $(RM) $@ $(CP) $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip $@ -ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64) - SRC_JDK_IMAGE_DIR := $(JDK_OVERLAY_IMAGE_DIR) - SRC_JRE_IMAGE_DIR := $(JRE_OVERLAY_IMAGE_DIR) -else - SRC_JDK_IMAGE_DIR := $(JDK_IMAGE_DIR) - SRC_JRE_IMAGE_DIR := $(JRE_IMAGE_DIR) -endif +SRC_JDK_IMAGE_DIR := $(JDK_IMAGE_DIR) +SRC_JRE_IMAGE_DIR := $(JRE_IMAGE_DIR) SRC_JDK_BUNDLE_DIR := $(JDK_BUNDLE_DIR) SRC_JRE_BUNDLE_DIR := $(JRE_BUNDLE_DIR) @@ -215,10 +210,10 @@ bundles: all bundles-only bundles-only: start-make @$(call TargetEnter) $(MKDIR) -p $(BUILD_OUTPUT)/bundles - $(CD) $(SRC_JDK_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip . - $(CD) $(SRC_JRE_IMAGE_DIR) && $(ZIP) -q -r $(BUILD_OUTPUT)/bundles/$(JRE_IMAGE_SUBDIR).zip . + $(CD) $(SRC_JDK_IMAGE_DIR) && $(ZIP) -y -q -r $(BUILD_OUTPUT)/bundles/$(JDK_IMAGE_SUBDIR).zip . + $(CD) $(SRC_JRE_IMAGE_DIR) && $(ZIP) -y -q -r $(BUILD_OUTPUT)/bundles/$(JRE_IMAGE_SUBDIR).zip . if [ -d $(BUILD_OUTPUT)/install/bundles ] ; then \ - $(CD) $(BUILD_OUTPUT)/install/bundles && $(ZIP) -q -r $(JPRT_ARCHIVE_INSTALL_BUNDLE) . ; \ + $(CD) $(BUILD_OUTPUT)/install/bundles && $(ZIP) -y -q -r $(JPRT_ARCHIVE_INSTALL_BUNDLE) . ; \ fi @$(call TargetExit) diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk index f5f01fce1ba..47b17e2631a 100644 --- a/common/makefiles/Main.gmk +++ b/common/makefiles/Main.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -68,10 +68,6 @@ default: jdk all: images docs @$(call CheckIfMakeAtEnd) -ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64) - all: overlay-images -endif - # Setup a rule for SPEC file that fails if executed. This check makes sure the configuration # is up to date after changes to configure $(SPEC): $(wildcard $(SRC_ROOT)/common/autoconf/*) From a210a6a74e6efc1636015bad98ef5a91811fc78b Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Fri, 27 Sep 2013 16:29:44 -0700 Subject: [PATCH 233/293] 8020552: [launcher] changes to support removal of Solaris 32-bit distribution 8023495: [infra] create 64-bit solaris bits with symlinks Reviewed-by: ihse, tbell, dholmes, darcy, alanb, erikj, sla, martin --- jdk/makefiles/Images.gmk | 28 ++- .../sun/tools/jdi/SunCommandLineLauncher.java | 16 +- jdk/src/solaris/bin/java_md_solinux.c | 3 +- jdk/test/com/sun/jdi/BadHandshakeTest.java | 13 +- jdk/test/com/sun/jdi/DoubleAgentTest.java | 13 +- jdk/test/com/sun/jdi/ExclusiveBind.java | 13 +- jdk/test/com/sun/jdi/PrivateTransportTest.sh | 25 +- jdk/test/com/sun/jdi/RunToExit.java | 13 +- .../com/sun/jdi/Solaris32AndSolaris64Test.sh | 226 ------------------ .../connect/spi/SimpleLaunchingConnector.java | 13 +- jdk/test/demo/jvmti/DemoRun.java | 26 +- .../inheritedChannel/Makefile | 25 +- .../lib/solaris-amd64/libLauncher.so | Bin 0 -> 10888 bytes .../lib/solaris-i586/libLauncher.so | Bin 7228 -> 0 bytes .../lib/solaris-sparc/libLauncher.so | Bin 7040 -> 0 bytes .../inheritedChannel/run_tests.sh | 17 +- .../sun/security/tools/keytool/autotest.sh | 4 +- jdk/test/sun/tools/jhat/HatRun.java | 22 +- .../tools/launcher/6842838/Test6842838.sh | 8 +- jdk/test/tools/launcher/ChangeDataModel.java | 52 +--- .../tools/launcher/ExecutionEnvironment.java | 218 ++++++++--------- jdk/test/tools/launcher/FXLauncherTest.java | 2 +- jdk/test/tools/launcher/RunpathTest.java | 14 +- jdk/test/tools/launcher/Test7029048.java | 112 ++------- jdk/test/tools/launcher/TestHelper.java | 72 +++--- 25 files changed, 220 insertions(+), 715 deletions(-) delete mode 100644 jdk/test/com/sun/jdi/Solaris32AndSolaris64Test.sh create mode 100644 jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/lib/solaris-amd64/libLauncher.so delete mode 100644 jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/lib/solaris-i586/libLauncher.so delete mode 100644 jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/lib/solaris-sparc/libLauncher.so diff --git a/jdk/makefiles/Images.gmk b/jdk/makefiles/Images.gmk index d265f4cd587..716616b2cdc 100644 --- a/jdk/makefiles/Images.gmk +++ b/jdk/makefiles/Images.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -190,6 +190,26 @@ $(foreach f,$(filter $(OVERLAY_FILTER),$(JDK_BIN_LIST)),\ $(foreach f,$(filter $(OVERLAY_FILTER),$(JDKJRE_BIN_LIST)),\ $(eval $(call AddFileToCopy,$(JDK_OUTPUTDIR),$(JDK_OVERLAY_IMAGE_DIR)/jre,$f,JDKJRE_BIN_TARGETS))) +ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_BITS),solaris-64) + define AddIsadirLink + # Param 1 - src file + # Param 2 - variable to add targets to + + $1_LINK := $$(dir $1)$(OPENJDK_TARGET_CPU_ISADIR)/$$(notdir $1) + + $$($1_LINK): + $(ECHO) $(LOG_INFO) Creating link $$(patsubst $(OUTPUT_ROOT)/%,%,$$@) + $(MKDIR) -p $$(@D) + $(LN) -s ../$$(@F) $$@ + + $2 += $$($1_LINK) + endef + + $(foreach f,$(JRE_BIN_TARGETS),$(eval $(call AddIsadirLink,$f,JRE_BIN_ISADIR_LINK_TARGETS))) + $(foreach f,$(JDK_BIN_TARGETS),$(eval $(call AddIsadirLink,$f,JDK_BIN_ISADIR_LINK_TARGETS))) + $(foreach f,$(JDKJRE_BIN_TARGETS),$(eval $(call AddIsadirLink,$f,JDKJRE_BIN_ISADIR_LINK_TARGETS))) +endif + ################################################################################ # /lib dir ifneq ($(OPENJDK_TARGET_OS), macosx) @@ -730,7 +750,8 @@ endif jre-image: $(JRE_BIN_TARGETS) $(JRE_LIB_TARGETS) $(JRE_IMAGE_DIR)/lib/applet \ $(JRE_IMAGE_DIR)/lib/meta-index $(JRE_IMAGE_DIR)/lib/ext/meta-index \ - $(JRE_MAN_PAGE_LIST) $(JRE_DOC_TARGETS) $(JRE_INFO_FILE) $(JRE_STRIP_LIST) + $(JRE_MAN_PAGE_LIST) $(JRE_DOC_TARGETS) $(JRE_INFO_FILE) $(JRE_STRIP_LIST) \ + $(JRE_BIN_ISADIR_LINK_TARGETS) jdk-image: $(JDK_BIN_TARGETS) $(JDKJRE_BIN_TARGETS) \ $(JDK_LIB_TARGETS) $(JDKJRE_LIB_TARGETS) \ @@ -741,7 +762,8 @@ jdk-image: $(JDK_BIN_TARGETS) $(JDKJRE_BIN_TARGETS) \ $(JDK_DB_TARGETS) $(JDK_INCLUDE_TARGETS) \ $(JDKJRE_DOC_TARGETS) $(JDK_DOC_TARGETS) \ $(JDK_INFO_FILE) $(JDKJRE_STRIP_LIST) $(JDK_BIN_STRIP_LIST) \ - $(JDK_IMAGE_DIR)/src.zip + $(JDK_IMAGE_DIR)/src.zip \ + $(JDK_BIN_ISADIR_LINK_TARGETS) $(JDKJRE_BIN_ISADIR_LINK_TARGETS) jre-overlay-image: $(JRE_OVERLAY_BIN_TARGETS) $(JRE_OVERLAY_LIB_TARGETS) \ $(JRE_OVERLAY_INFO_FILE) $(JRE_OVERLAY_STRIP_LIST) diff --git a/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java b/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java index 20be57c85c4..84a14557b30 100644 --- a/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java +++ b/jdk/src/share/classes/com/sun/tools/jdi/SunCommandLineLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -196,19 +196,7 @@ public class SunCommandLineLauncher extends AbstractLauncher implements Launchin try { if (home.length() > 0) { - /* - * A wrinkle in the environment: - * 64-bit executables are stored under $JAVA_HOME/bin/os_arch - * 32-bit executables are stored under $JAVA_HOME/bin - */ - String os_arch = System.getProperty("os.arch"); - if ("SunOS".equals(System.getProperty("os.name")) && - ("sparcv9".equals(os_arch) || "amd64".equals(os_arch))) { - exePath = home + File.separator + "bin" + File.separator + - os_arch + File.separator + exe; - } else { - exePath = home + File.separator + "bin" + File.separator + exe; - } + exePath = home + File.separator + "bin" + File.separator + exe; } else { exePath = exe; } diff --git a/jdk/src/solaris/bin/java_md_solinux.c b/jdk/src/solaris/bin/java_md_solinux.c index b0028bde78d..e5b9672314e 100644 --- a/jdk/src/solaris/bin/java_md_solinux.c +++ b/jdk/src/solaris/bin/java_md_solinux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,6 @@ */ #ifdef __solaris__ -# define DUAL_MODE # ifndef LIBARCH32NAME # error "The macro LIBARCH32NAME was not defined on the compile line" # endif diff --git a/jdk/test/com/sun/jdi/BadHandshakeTest.java b/jdk/test/com/sun/jdi/BadHandshakeTest.java index 8ba9ea5a03d..73f13fe253e 100644 --- a/jdk/test/com/sun/jdi/BadHandshakeTest.java +++ b/jdk/test/com/sun/jdi/BadHandshakeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -108,16 +108,7 @@ public class BadHandshakeTest { */ private static Process launch(String address, String class_name) throws IOException { String exe = System.getProperty("java.home") - + File.separator + "bin" + File.separator; - String arch = System.getProperty("os.arch"); - String osname = System.getProperty("os.name"); - if (osname.equals("SunOS") && arch.equals("sparcv9")) { - exe += "sparcv9/java"; - } else if (osname.equals("SunOS") && arch.equals("amd64")) { - exe += "amd64/java"; - } else { - exe += "java"; - } + + File.separator + "bin" + File.separator + "java"; String cmd = exe + " " + VMConnection.getDebuggeeVMOptions() + " -agentlib:jdwp=transport=dt_socket" + ",server=y" + ",suspend=y" + ",address=" + address + diff --git a/jdk/test/com/sun/jdi/DoubleAgentTest.java b/jdk/test/com/sun/jdi/DoubleAgentTest.java index 355d750b0dd..1a4902ce586 100644 --- a/jdk/test/com/sun/jdi/DoubleAgentTest.java +++ b/jdk/test/com/sun/jdi/DoubleAgentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,16 +90,7 @@ public class DoubleAgentTest { */ private static Process launch(String address, String class_name) throws IOException { String exe = System.getProperty("java.home") - + File.separator + "bin" + File.separator; - String arch = System.getProperty("os.arch"); - String osname = System.getProperty("os.name"); - if (osname.equals("SunOS") && arch.equals("sparcv9")) { - exe += "sparcv9/java"; - } else if (osname.equals("SunOS") && arch.equals("amd64")) { - exe += "amd64/java"; - } else { - exe += "java"; - } + + File.separator + "bin" + File.separator + "java"; String jdwpOption = "-agentlib:jdwp=transport=dt_socket" + ",server=y" + ",suspend=y" + ",address=" + address; String cmd = exe + " " + VMConnection.getDebuggeeVMOptions() diff --git a/jdk/test/com/sun/jdi/ExclusiveBind.java b/jdk/test/com/sun/jdi/ExclusiveBind.java index 159a7cddb64..3389ee220f8 100644 --- a/jdk/test/com/sun/jdi/ExclusiveBind.java +++ b/jdk/test/com/sun/jdi/ExclusiveBind.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,16 +97,7 @@ public class ExclusiveBind { */ private static Process launch(String address, boolean suspend, String class_name) throws IOException { String exe = System.getProperty("java.home") + File.separator + "bin" + - File.separator; - String arch = System.getProperty("os.arch"); - String osname = System.getProperty("os.name"); - if (osname.equals("SunOS") && arch.equals("sparcv9")) { - exe += "sparcv9/java"; - } else if (osname.equals("SunOS") && arch.equals("amd64")) { - exe += "amd64/java"; - } else { - exe += "java"; - } + File.separator + "java"; String cmd = exe + " " + VMConnection.getDebuggeeVMOptions() + " -agentlib:jdwp=transport=dt_socket,server=y,suspend="; if (suspend) { diff --git a/jdk/test/com/sun/jdi/PrivateTransportTest.sh b/jdk/test/com/sun/jdi/PrivateTransportTest.sh index 64459008826..32677db795b 100644 --- a/jdk/test/com/sun/jdi/PrivateTransportTest.sh +++ b/jdk/test/com/sun/jdi/PrivateTransportTest.sh @@ -1,7 +1,7 @@ #!/bin/ksh -p # -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -102,28 +102,7 @@ libdir=${TESTCLASSES} is_windows=false is_cygwin=false case `uname -s` in - SunOS) - libarch=`uname -p` - d64=`echo "${DEBUGGEEFLAGS}" | fgrep -- -d64` - case `uname -p` in - sparc) - if [ "${d64}" != "" ] ; then - libarch=sparcv9 - fi - ;; - i386) - if [ "${d64}" != "" ] ; then - libarch=amd64 - fi - ;; - *) - echo "FAILURE: Unknown uname -p: " `uname -p` - exit 1 - ;; - esac - libloc=${jreloc}/lib/${libarch} - ;; - Linux) + SunOS|Linux) xx=`find ${jreloc}/lib -name libdt_socket.so` libloc=`dirname ${xx}` ;; diff --git a/jdk/test/com/sun/jdi/RunToExit.java b/jdk/test/com/sun/jdi/RunToExit.java index 9186a9d9888..95d6256862c 100644 --- a/jdk/test/com/sun/jdi/RunToExit.java +++ b/jdk/test/com/sun/jdi/RunToExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -113,16 +113,7 @@ public class RunToExit { */ private static Process launch(String address, String class_name) throws IOException { String exe = System.getProperty("java.home") - + File.separator + "bin" + File.separator; - String arch = System.getProperty("os.arch"); - String osname = System.getProperty("os.name"); - if (osname.equals("SunOS") && arch.equals("sparcv9")) { - exe += "sparcv9/java"; - } else if (osname.equals("SunOS") && arch.equals("amd64")) { - exe += "amd64/java"; - } else { - exe += "java"; - } + + File.separator + "bin" + File.separator + "java"; String cmd = exe + " " + VMConnection.getDebuggeeVMOptions() + " -agentlib:jdwp=transport=dt_socket" + ",server=y" + ",suspend=y" + ",address=" + address + diff --git a/jdk/test/com/sun/jdi/Solaris32AndSolaris64Test.sh b/jdk/test/com/sun/jdi/Solaris32AndSolaris64Test.sh deleted file mode 100644 index 7e03dfb652e..00000000000 --- a/jdk/test/com/sun/jdi/Solaris32AndSolaris64Test.sh +++ /dev/null @@ -1,226 +0,0 @@ -#!/bin/ksh -p - -# -# Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# -# @test Solaris32AndSolaris64Test.sh -# @bug 4478312 4780570 4913748 6730273 -# @summary Test debugging with mixed 32/64bit VMs. -# @author Tim Bell -# Based on test/java/awt/TEMPLATE/AutomaticShellTest.sh -# -# @run build TestScaffold VMConnection TargetListener TargetAdapter -# @run compile -g FetchLocals.java -# @run compile -g DataModelTest.java -# @run shell/timeout=240 Solaris32AndSolaris64Test.sh DataModelTest -# @run shell/timeout=240 Solaris32AndSolaris64Test.sh FetchLocals - -# Beginning of subroutines: -status=1 - -#Call this from anywhere to fail the test with an error message -# usage: fail "reason why the test failed" -fail() - { echo "The test failed :-(" - echo "$*" 1>&2 - echo "exit status was $status" - exit $status - } #end of fail() - -#Call this from anywhere to pass the test with a message -# usage: pass "reason why the test passed if applicable" -pass() - { echo "The test passed!!!" - echo "$*" 1>&2 - exit 0 - } #end of pass() - -# end of subroutines - -if [ $# = 0 ] ; then - echo "Error: no testname specified on cmd line" - exit 1 -fi -testName=$1 -shift - -#Set appropriate jdk - -if [ -z "${TESTJAVA}" ] ; then - # TESTJAVA is not set, so the test is running stand-alone. - # TESTJAVA holds the path to the root directory of the build of the JDK - # to be tested. That is, any java files run explicitly in this shell - # should use TESTJAVA in the path to the java interpreter. - # So, we'll set this to the JDK spec'd on the command line. If none - # is given on the command line, tell the user that and use a default. - # THIS IS THE JDK BEING TESTED. - if [ -n "$1" ] ; then - TESTJAVA=$1 - else - echo "no JDK specified on command line so using JAVA_HOME=$JAVA_HOME" - TESTJAVA=$JAVA_HOME - fi - TESTSRC=. - TESTCLASSES=. - STANDALONE=1; -fi -echo "JDK under test is: $TESTJAVA" - - -# The beginning of the script proper - -# Checking for proper OS and processor type. -# -# This test is only interested in SunOS SPARC sparcv9 and SunOS AMD64 -# (supporting both 32 and 64 bit Solaris binaries). -# -# All other platforms will instantly complete with passing -# status. -# -OS=`uname -s` -case "$OS" in - SunOS ) - PATHSEP=":" - PTYPE=`uname -p` - if [ -x /usr/bin/isainfo ]; then - # Instruction set being used by the OS - ISET=`isainfo -k` - else - #SunOS 5.6 didn't have "isainfo" - pass "This test always passes on $OS/$PTYPE (32-bit ${ISET})" - fi - ;; - - Linux | Darwin ) - pass "This test always passes on $OS" - ;; - - Windows* | CYGWIN*) - pass "This test always passes on $OS" - ;; - - # catch all other OSs - * ) - echo "Unrecognized system! $OS" - fail "Unrecognized system! $OS" - ;; -esac - -# Is the OS running in sparcv9 or amd64 mode? -case "${ISET}" in - sparc ) - pass "This test always passes on $OS/$PTYPE (32-bit ${ISET})" - ;; - i386 ) - pass "This test always passes on $OS/$PTYPE (32-bit ${ISET})" - ;; - amd64 ) - echo "OS is running in ${ISET} mode" - ;; - sparcv9 ) - echo "OS is running in ${ISET} mode" - ;; - # catch all others - * ) - echo "Unrecognized instruction set! $OS/$PTYPE/${ISET}" - fail "Unrecognized instruction set! $OS/$PTYPE/${ISET}" - ;; -esac - -# SunOS 32 and 64 bit binaries must be available -# to test in the remainder of the script below. -$TESTJAVA/bin/java -d64 -version > /dev/null 2<&1 -if [ $? = 1 ]; then - # The 64 bit version is not installed. Make the test pass. - pass "This test always passes on $OS/$PTYPE if 64 bit jdk is not installed" -fi - -# Want this test to run standalone as well as in the harness, so do the -# following to copy the test's directory into the harness's scratch directory -# and set all appropriate variables: - -#Deal with .class files: -if [ -n "${STANDALONE}" ] ; then - #if running standalone, compile the support files - ${TESTJAVA}/bin/javac -d ${TESTCLASSES} \ - -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}${TESTSRC}" \ - TestScaffold.java VMConnection.java TargetListener.java TargetAdapter.java - ${TESTJAVA}/bin/javac -d ${TESTCLASSES} \ - -classpath "$TESTJAVA/lib/tools.jar${PATHSEP}${TESTSRC}" -g \ - FetchLocals.java DataModelTest.java -fi - -# Get DEBUGGEE flags -DEBUGGEEFLAGS= -filename=$TESTCLASSES/@debuggeeVMOptions -if [ ! -r ${filename} ] ; then - filename=$TESTCLASSES/../@debuggeeVMOptions -fi -# Remove -d32, -d64 if present, and remove -XX:[+-]UseCompressedOops -# if present since it is illegal in 32 bit mode. -if [ -r ${filename} ] ; then - DEBUGGEEFLAGS=`cat ${filename} | sed \ - -e 's/-d32//g' \ - -e 's/-d64//g' \ - -e 's/-XX:.UseCompressedOops//g' \ - ` -fi - -# -CLASSPATH="$TESTJAVA/lib/tools.jar${PATHSEP}${TESTCLASSES}" -export CLASSPATH -CP="-classpath \"${CLASSPATH}\"" - -for DEBUGGERMODEL in \ - 32 \ - 64 \ -; do - - for TARGETMODEL in \ - 32 \ - 64 \ - ; do - DEBUGGERFLAGS="-d${DEBUGGERMODEL} -showversion -DEXPECTED=${TARGETMODEL}" - CONNECTSTRING="-connect 'com.sun.jdi.CommandLineLaunch:options=-d${TARGETMODEL} $DEBUGGEEFLAGS -showversion'" - - for TARGETCLASS in $testName ; do - echo "--------------------------------------------" - echo "debugger=${DEBUGGERMODEL} debugee=${TARGETMODEL} class=${TARGETCLASS}" - echo "--------------------------------------------" - echo ${TESTJAVA}/bin/java -DHANGINGJAVA_DEB ${DEBUGGERFLAGS} ${CP} ${TARGETCLASS} ${CONNECTSTRING} - eval ${TESTJAVA}/bin/java -DHANGINGJAVA_DEB ${DEBUGGERFLAGS} ${CP} ${TARGETCLASS} ${CONNECTSTRING} - status=$? - if [ $status -ne "0" ]; - then fail "$DEBUGGERMODEL to $TARGETMODEL test failed for class=$TARGETCLASS!" - fi - done - done -done -# -# pass or fail the test based on status of the command -if [ $status -eq "0" ]; - then pass "" - - else fail "unspecified test failure" -fi diff --git a/jdk/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java b/jdk/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java index 422955b239e..63517835734 100644 --- a/jdk/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java +++ b/jdk/test/com/sun/jdi/connect/spi/SimpleLaunchingConnector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,16 +143,7 @@ public class SimpleLaunchingConnector implements LaunchingConnector { TransportService.ListenKey key = ts.startListening(); String exe = System.getProperty("java.home") + File.separator + "bin" + - File.separator; - String arch = System.getProperty("os.arch"); - String osname = System.getProperty("os.name"); - if (osname.equals("SunOS") && arch.equals("sparcv9")) { - exe += "sparcv9/java"; - } else if (osname.equals("SunOS") && arch.equals("amd64")) { - exe += "amd64/java"; - } else { - exe += "java"; - } + File.separator + "java"; String cmd = exe + " -Xdebug -Xrunjdwp:transport=dt_socket,timeout=15000,address=" + key.address() + " -classpath " + System.getProperty("test.classes") + diff --git a/jdk/test/demo/jvmti/DemoRun.java b/jdk/test/demo/jvmti/DemoRun.java index 9a0ec96f20f..907e5ce97e7 100644 --- a/jdk/test/demo/jvmti/DemoRun.java +++ b/jdk/test/demo/jvmti/DemoRun.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,28 +125,22 @@ public class DemoRun { String libprefix = os_name.contains("Windows")?"":"lib"; String libsuffix = os_name.contains("Windows")?".dll": os_name.contains("OS X")?".dylib":".so"; - boolean d64 = ( os_name.contains("Solaris") || - os_name.contains("SunOS") ) - && ( os_arch.equals("sparcv9") || - os_arch.equals("amd64")); boolean hprof = demo_name.equals("hprof"); - String isa_dir = d64?(File.separator+os_arch):""; String java = jre_home - + File.separator + "bin" + isa_dir + + File.separator + "bin" + File.separator + "java"; /* Array of strings to be passed in for exec: * 1. java * 2. -Dtest.classes=. - * 3. -d64 (optional) - * 4. -Xcheck:jni (Just because it finds bugs) - * 5. -Xverify:all (Make sure verification is on full blast) - * 6. -agent + * 3. -Xcheck:jni (Just because it finds bugs) + * 4. -Xverify:all (Make sure verification is on full blast) + * 5. -agent * vm_options - * 7+i. classname + * 6+i. classname */ int nvm_options = 0; if ( vm_options != null ) nvm_options = vm_options.length; - String cmd[] = new String[1 + (d64?1:0) + 7 + nvm_options]; + String cmd[] = new String[1 + 7 + nvm_options]; String cmdLine; int exitStatus; int i,j; @@ -160,10 +154,6 @@ public class DemoRun { cmdLine += (cmd[i++] = cdir); cmdLine += " "; cmdLine += (cmd[i++] = "-Dtest.classes=" + cdir); - if ( d64 ) { - cmdLine += " "; - cmdLine += (cmd[i++] = "-d64"); - } cmdLine += " "; cmdLine += (cmd[i++] = "-Xcheck:jni"); cmdLine += " "; @@ -178,7 +168,7 @@ public class DemoRun { + File.separator + "demo" + File.separator + "jvmti" + File.separator + demo_name - + File.separator + "lib" + isa_dir + + File.separator + "lib" + File.separator + libprefix + demo_name + libsuffix; cmdLine += " "; cmdLine += (cmd[i++] = "-agentpath:" + libname diff --git a/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Makefile b/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Makefile index c868afe9a26..9b474913aaa 100644 --- a/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Makefile +++ b/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/Makefile @@ -21,33 +21,14 @@ uname := $(shell uname) ifeq ($(uname), SunOS) PLATFORM = solaris ISAINFO = isainfo - ifndef ARCH_DATA_MODEL - ARCH_DATA_MODEL=32 - endif - ifeq ($(ARCH_DATA_MODEL), 32) - archExpr = case "`$(UNAME) -p`" in \ - i386) \ - $(ECHO) i586 \ - ;; \ - sparc*) \ - $(ECHO) sparc \ - ;; \ - *) \ - $(UNAME) -p \ - ;; \ - esac - ARCH := $(shell $(archExpr) ) - else - ARCH := $(shell $(ISAINFO) -n) - endif + ARCH_DATA_MODEL=64 + ARCH := $(shell $(ISAINFO) -n) CC = cc LD = ld CFLAGS = -D_REENTRANT -D__solaris__ LDFLAGS_COMMON = -G EXTRA_LIBS = -lc - ifeq ($(ARCH_DATA_MODEL), 64) - CC += -xarch=v9 - endif + CC += -m64 -Kpic endif ifeq ($(uname), Linux) diff --git a/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/lib/solaris-amd64/libLauncher.so b/jdk/test/java/nio/channels/spi/SelectorProvider/inheritedChannel/lib/solaris-amd64/libLauncher.so new file mode 100644 index 0000000000000000000000000000000000000000..6e7c2d8f5bf4bf0f004becef68dc6b1f33783a44 GIT binary patch literal 10888 zcmeHNeQX>@6`%7t$u(b&(+|?7z!GApDtu=Z|7_8e!ctFDvxKmM>xqVb_#wbq|Jdv=V#S}#9Bl( zay}`pm$J+9StU=sS2++W_k&TMqsRWc;5jWfd z*8Ja~o{iqt&8RB1;~1RN2TFZ22HLP17$_x@q2&2`zwnH$^K4wb!Z+>ld40=$t9@&H zYkf6NKFNInS0`-QpzMFqzINTWt9Gy9_#?SNTvX;Nbn?5&-3z%%^zWZh$x3pFOFJ4fWg*lbUae+r^gX4gBN)#?@aH(bp#Jx-$f7OaFM=12*Dw)(_(b zUA=qSZ_|T=?Yp}5phzUmI7tu{K{IUFh6tyVO(GOaq)cIsnW2M85$w3Lx4oxpw+IG9 z_MxN+$#@ty+Z?kUNwP7Vunsf=9gEr`Wm|S4CPs}|ED;j78wZUb*F6}M4Qdc*TL_Kv zH;RFMyU@@@j6^U<13{{Z`gsMyGp$2u((%2qAGWHIMO1_`J)ku z#%Y=p==Gwpoz@X#GpXiro@XZ2q%!8hk1Kq_h0iN|+J*Zt^iVqL!Zn2-bKwmNpLOAF z3SUq-&22Pyaf&FM+EzIKOcvlgN0H9)0=#gJJ6VA9oJjIB1$g0{I#+=6kVW$I1$g01 zaG?O_z9jj@0$fdH1dBHca9%?Yez^eWJ|lc-+e$1Mm+DsIK8>_gM|^~`vKO%ET&lZ{ zc&bu%Uh+2*PqSurR`Q#Or>102=H(8Gf#>w!5P`y6ccy2dr*+QO^4j|rVPSzRKshO`z`~2q z4-Zf0{#E&XTz+1=sO$+1o`CX{e%_JjMA_2fIsKQa3Nu}qc~_OcN$+5;)^nvQsP!Cb zoxZ+I)|9@O4Wa|5Gy3_%v!2Xs=TWr2E93ZMaV54IId8bDqP&rg<=eAwjw{!bned@r z?2zuvnm;V_ly6U0=2ET)7W+_Qg?c^>A55RqFOn-V`o&iL{P+l{ta0y=YF)a>tIxI9 zJl!USr}VQmPwQuQP!!yMEj?!DS-RV+FSJkgiN9Qfb~^?Lnz;qC?UQX}9nP52FX92k z-1`{3Ba4wzR1QhKuV(8D2qlWP#jecki_aq{hNo3LBsm@^9;bRP=Ix~sRJo9xxP!yu zWJW)E__9cU9^Ra;_MigGz5{}gD01PNx0jZ(V|eRGJlChUAG!Gjs=4fu#m0Yf$IhJ7 zj}m@P|2`2^0uj(NLjkh|(AtT{qUNp4qW-zh{# zQPUz$)0_}Hj$B--;frTw73W}ydsx;VT`g{9Hm#hr}eqCFFS%^3BHG# z?AlYRh7aF`fud9ot}C%lr8?g8Vuw4WznsxuMt9f^4jtbFch!1jx2y+o`{*E)vVWp? z4gL0Jl}DT=N9A6%XWt^5XEOR3*c`8Umc}!uw4Wm?1QcT7H*Q^(+Olqyvm3p9AteCwyc(UW+)PPeUh#tDpv%Oa>q&yhAy zkN3Iuny1>t;S1H|lYSa>O07LZV{=#Ljjkhy);oo7a0+kF%ueYiGWv;D{i1!fq-X3k zneh{j)UR-)k+1N1a8AgSDMF2QH4pBE1M@nw(2)+$j9+wYo+gCmt{ifL5SqPm$m2kA z%nmT{zzo6^!|<4jg@=F^be0e7i_gOb(ta$<12H2$64;xz_YU`%qY3MfZdnP-o!=FU znIlH5-5N=cnsGb7?T~_@#OSCI4{L^H8HcpdbjsEYTZ@?n9-{G3EFCsAJ7Q`{D=}gj zqgvb;HFM=h6M?S1#Rh33p$!|+m>HJ#17Y)EAfArJoN9>x421$IGd3I;CJBwaR3_c! z+TXfG;_s1vpUQtk(I2?vpH%#57yett|54G`6n)1f=dKSmque?B__(sug;wV7R#5OXHdSk;2fn`zD7Kt*73#oI>GyaV!XEO`Jb0g5M1XC zq~|SjF5=)=+?SQdscM7v~@J+>6e)JlN53e`(+;eHjx9zw!H`1+%Zd>TKUF;f4rTn-= z2c7ZxL`O0jlDwiKsP}dRMQ~uSy?-$HUw)Wa_tm<(p1LdQx^U@r+CWd2 z_!#=w6aUGWFtF}Teo-4p$F<$sHh*ISJ?sc+b(H8nIg z1RAymnp%XBQc6(A8rRZxWBr_nYmH6*#&RYaTeh{-H#92~+X9VS1Z}=A2j5~~CE1P-L|MIaiuy<<-xGE#5HTI!v%chd^&4*EOvpC#&3rghM?>MgXBfEW+XU_-J}_egsnU${1GD+5q|keDF)%xp;19fIch^%=A!#k^yw_mk*Lga z|=UG(Fx_%UI8$-fRAI6B%o*6r7 z2%AIck)X8hJVxWgi5wh_oBV7H4O!+vScoVas;mBeLT;wRY#u>00+5*U?^>kef%{}` z{<{oq&!CcIecp#M-K^x9us-v&&MwsF{VLOAEU2hke-rR!xVU`Y*D^h(^!Qr>>sKrM z2GGCaw;-&~`(LJGN{-r3<*+{Q51N6|?*dq#e{aKdPWhAc>Cvsf6BupLsU4JfKh2bX z&*S7eHu#z7t+?p7He9}@_RBe{gx%$_Gz$&HbnL3PCPnyYed+22*r z-}Py-QkvZQFGIwQkrwOkd5`iJE9f8j3|YZ}|TvR`vVp!_(2>v#LKPE&V-$#gxvWpOFACKS~#_hOp zeKE9( zr$wioTj`|r>1yoM3mW@(Z@luz`7W?S`@OWHXN8Y#SV%64zK-5C-Pk`&&K(I0rM%q{ zr&6Ht@L3#gBywGn79mR$PvHcml+)%~!(3DQJ<8|T1@k&Lzj9UXy}oZca&G5o^J>Gq z8gYJBQl(~V&`OJ4(P9@xsS^)A>bv>@bvRn^_plU4bHTiZ0XVLWn(IAh?%{au8g%LT zRp)f^wE1SwFU>diZeY6S8+?uuZOmQmn7j5^`xV9kWGMXH=YT!d4oUk?n~)#{KJhGe zmGt#EBf3U!DX`;o)au|6XpGmm|k~6nmA%VR|XmwEtf+IIrA` z1<={Ne5UhJz6}$eO`HMWneg62di5)BtJS-)`hvL%Dtxv&YF_R+Q<7t8)hd+Iiv2uN z4A!F!j&M)eV%w)x)MgN zUFbYZ1!PEUiqua@Rid~(!*_M*89L!h(?}tqG?(*EHFSMX zh`e8^*j^!J2Z4PuRjJp)lpUtZj*Wrq<;(SglL|{tsv7tUfn7;?cEy1Q-hE%!Hzuay zjrihC6>Ycd6ogT5mJF|6E<=t1!Fi+Rl#52O09@xO+=EBO2Rl#eNp!pl#P1R1Jf^>* zGoQR4Ow9B6Xt?(FhJWP^A#m~hi+m&jQijeUnd_`!o;ePM?*hPUNnFP|^8FM105@#p z(XCUw#fOyCi%@0WN*{$oQ8eny#@w8Zda-pxnKAWIIIR<6oyMYdNb6ubjg>erYMfVg zNX_FstV3qivHv=xmqar!>yTbb;tb@tbu_bNHP<0C^dwzp&zc^+lp~f7WV*@L0WUwE zm|%XxJW}V0ZOB_cmY~z0pKhVcJUPm9+o1nG&~;wj2K%Rg(_gm(w!>eufGN09<6i_m zoxqO)KLz|wK=Ky>e+K+egx3M-c0Q~~f0}sI7&AZ62q5tvwctMiuJvQy|6GFJ3;Qkt zPv-r9O3*3q%@+JGE%@JoYyUCtmv8KdhwBripwy2gn!ZoW`*$S*n5T7H0_XaVx8QfS z;2Ge_y#FBZSfB0UNDKd53;tjWo^QdK4;wYVYzJ;_k2^3tXkbF8^vIq?bDS6Z=WDez zx)^8jot7E+c;HJ!0i^Iq{LAvUD1TLcK3fX>6Y+y-!3k%=!1We}hX+Qi?17RU)PyxN zJ9c!|5|%kRZv7vYBkI}8DE}$WfKLLx2H8H3-Y-Y^*>}e$?yQ9c*H4$av+1GX?vW8A zn=>-QshJ}aG1YQW*^nbA88Sw0pvh2l?64j*rP+n3qcr4oLN|HdZfGL{z0Ca_8ZsYe;Nbt~7)2 zkxi1Vrf&zN^I(4*1vNi^+)p)QKy#a3--@OQ_fBl5BcdQW2DWaX^F?YX0Mr+z&D=M(D@K z>w9K@{`Ajy3QH~KrNd8Ll;9g<3uTlWr5GA3won}oEiBoA6rWX^_a%=jA2>=gn8gFZVZ{d$I5oc>`_9h;m@?eSCZ$kv+a znV;G-q2<083+C%?xv)9&)3xV+OOTeHN;S32>on)RK&GlF6_7EhnveD9`3MJ))f`JV zR%xt9$;aB1{S-ROJjx&sD<@V{oFgA=M0VD+x{;TS|L?w?s@_@>k2cK4@ zJl2%5u7nV-W1Y->S?e0;l+8KTPVBePu&9xTjkOo~xSlmA`)@GTjq=#|MNspx_R;l^ zBt|rj4@P6^%^HILV@g(_l*fKII&~u-YnMylI~CyoO*>fYabNPW202EjCmLyNtO04$ zyYX4zp{=@6UKNY@f2tHZb>q1$pi`D^uYh4uZ-z-d^b=$9-i5`Ves+51$xJrG;W!sI%>SC12lPWEphP&SRjSlXU3luYeBuya^pd7wrKI4@#H@vZ)8X7oB+e z(5dCo`_bb*93@ci1fE%*#5jkfgw&Dk;OF|0CubZ`+Z-IE$jaV23 zkzZq9HP=jI#%y|4)d`Fm2a2rbE?b4rFO=BAso8HB#lmQ63f^XT4*V7n&!PUq2Yx1F zup!3Y$H0WWqP*$FdC4H|1m_-+^N4v)lk)^G%6Y^shyCUJfcvnH%ee&@y7)Z7`^9`e z&OqM*G0$NsrysKWq#T0t6WDWk4)a)(Q!r>T44Y#Zc`+b)`rg3tP%v!GDj0Ue@V9Z4 z)%*-}EBO5c&Q}t+ZwlF^c%lT(A5Y*u*t1>o6SNuO`YzLhKoWs60;2i?q4tsVg z{;>oWRK8<$a?yYBkBt{@4z{O09Bd!IHQ1iHk!w$NvKs63Xb-=cYaf5{Pn?ZiMgqSx zxbbo8>IBQS*gdp7#XI)5Tzlr??g^&&pZjyC@40_6rpB~RsrQ`Ho5t0`P_0Qs%XUKCso^eLvu`_FRu;ksiAEF78@l z&u(u1p7cPTM)F=oZ?)N@ds=K4$$1IDmB%`n_xD`idF5bx;7Vm_pmlX=b9Z7#&pSGM z;PQa>1dXruwll4lT95W_Y<@`Vuj}m5lwY^m0=?OnA7bn`4_?1p{8}o0v~M2`w&xR> zd#}O285O5C;_&)z_;6LDSmjkLQvN=BDZ8{^?Nz%+%S^z|pFXB#Q!%{Ly6;k))Vga) zoIbB~h+NwHD%o@C!B!mai?Hdo2|%#|6Pq;N$ZgzA^ONkCp*Nj}#HaW#U=N9gGowN7txj&^*3}-ZzcbV3Uyhe| zFR{)J*nVE?0T0iwO9NW}1tb&6A$#Q6>vVGMd7Qri@b!^i$hs-<#7>++TBr2x+Sq)T z^r|_;dY)kJXAEnZWM0b>o$wnu8586p&5=(kW@`KnzBKfj>8&1i1rDW~oS>(fEt z2aF}O6SbPNYSt!$)n?uCqUp1i(}-N(W6bjFbH#h%-m(dc&P0W*w zJ?PYOm~UakcS(li(4D;l>psRvd|yEC!McBAyjvq)-g?CQieR#j-eZ!+?IJu&^U`j@ z@kedj5GFlTU+ zfK#l}IDJ>e4Rm^s#tpc7oANo}^xlmdaBioX08Ym;ZoqLWS)}wMIHd1;iUByqYp=p( zJP&s9kEC$2e^U96#pM4y;-z7%BG?o!1NaLNU6lCqnB$F%LHm&y$XNb9zN&CZzt)An zqV&T#(*If){SRIEAHiRwIq=hd{Jo3b0iEv;=(IoYDY^{a2Pu6NuaA_!pp(C!D1KpY z24NOW;_;qJoUUBnB>uTBTtnF2MvjX2G2WVb=-14^4G)G5Gq7~bs23?7p)7_ic4RpW z3+QZ$9?1p%Ql1KYj);LRRs;V`as{k9(Lxls-s;%c@VHSrS~Y`^8Pl^<1~V2GCr>UK z|CbMR9#P6=q+I4Lj63LJlI=L(Y(gdu?E6v}*{)xx=1Yaq@qDqQ7b|*cL|b_3L_#%O zy!DBroF5<8OGUjr95bvqX4DKEBXYthY8;wp~n#WF#CT`SDQ_k#@qVIhG8< zC=bGzUP@vexpfETmkXn%+to{AsW3FoHDhHG9U{h_l_Wjw8K>xo?*$rsC%Ud3`O7-gtq z);W2+%=MP^a*`Hno^Mk~N`-N56>WI3I5JSrp62ArFi#oeRAMx3Sjl4|13!q<%=&}5NbP8K#j90Oa3 z73UELDG6r1iOQW*DUis&Egl7DVtt7&-tcSU%AopQ-`e+Ar+i7siN+NF1o@93&StM8EWPvo6P6OoN zib#FKZN$xJMM~)xZj*MD`haFdF;#yN=H#P)GGMY{jcg3)U+EKo2i%qFS7!jvx zOCsP08$6mto(P*imCSGLtv68^nPRQD$F`hhq8af;iZtjx>?@WR$y;`qM{A4bgi4nz zoyT;z_>WM+YH>ksxu!VvZub<9h8c*9gibULc}zU z*!1k-N})u5hb;ThvWYv|vkyIO9y)pWj$Z1{*@hoPy6uLi%lfGhe(5F(wPpQGh3L2KybV`h;9pjLFdz79E)Ib1diagdjT{@V zC}KOLrS(;)!is#Kucl`lg*HT`r7z4aj8VyD>&vdETb6bZe^bWE>FL?UlasTHgc$M( zXc*c-U%UNH7(W7i?cfQe_Om#++;nSp*8@}4nEx|LO1`GWc3SE+_Sr^y%c0)n^&8c8 z)PF5;47_fm+KuWlstM@bhbJHJs7I*O;%kYAY9y+gXl^g2&x_7$SWNLo`lvl5>Q`F3 zZAo;dF|n3-NFKE>q7!@sq?YKsro}p50}+kt0IEZ19qJ;gDXI6&16NJdkBp6Ag7~nW zYEA0wujr~Ny-#35^2Ps;Q9LvfjoLAEg13oUh}T0(2GI$oK7&p*8}Z?p%hc$ws`{n?R`EeFUBKB3Ar=7qo90I@-P0 zU /dev/null 2<&1 - if [ $? = 1 ]; then - ARCH=sparc - else - ARCH=sparcv9 - DFLAG=-d64 - fi + ARCH=sparcv9 ;; esac fi diff --git a/jdk/test/sun/security/tools/keytool/autotest.sh b/jdk/test/sun/security/tools/keytool/autotest.sh index 9c797dd21e5..1d691076616 100644 --- a/jdk/test/sun/security/tools/keytool/autotest.sh +++ b/jdk/test/sun/security/tools/keytool/autotest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ OS=`uname -s` case "$OS" in SunOS ) FS="/" - LIBNAME="/usr/lib/mps/libsoftokn3.so" + LIBNAME="/usr/lib/mps/`isainfo -n`/libsoftokn3.so" ;; Linux ) FS="/" diff --git a/jdk/test/sun/tools/jhat/HatRun.java b/jdk/test/sun/tools/jhat/HatRun.java index e9765408d47..284083580ec 100644 --- a/jdk/test/sun/tools/jhat/HatRun.java +++ b/jdk/test/sun/tools/jhat/HatRun.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -167,28 +167,23 @@ public class HatRun { String cdir = System.getProperty("test.classes", "."); String os_arch = System.getProperty("os.arch"); String os_name = System.getProperty("os.name"); - boolean d64 = os_name.equals("SunOS") && ( - os_arch.equals("sparcv9") || - os_arch.equals("amd64")); - String isa_dir = d64?(File.separator+os_arch):""; String java = jre_home - + File.separator + "bin" + isa_dir + + File.separator + "bin" + File.separator + "java"; String jhat = sdk_home + File.separator + "bin" + File.separator + "jhat"; /* Array of strings to be passed in for exec: * 1. java * 2. -Dtest.classes=. - * 3. -d64 (optional) - * 4. -Xcheck:jni (Just because it finds bugs) - * 5. -Xverify:all (Make sure verification is on full blast) - * 6. -agent + * 3. -Xcheck:jni (Just because it finds bugs) + * 4. -Xverify:all (Make sure verification is on full blast) + * 5. -agent * vm_options - * 7+i. classname + * 6+i. classname */ int nvm_options = 0; if ( vm_options != null ) nvm_options = vm_options.length; - String cmd[] = new String[1 + (d64?1:0) + 7 + nvm_options]; + String cmd[] = new String[1 + 7 + nvm_options]; int i,j; i = 0; @@ -196,9 +191,6 @@ public class HatRun { cmd[i++] = "-cp"; cmd[i++] = cdir; cmd[i++] = "-Dtest.classes=" + cdir; - if ( d64 ) { - cmd[i++] = "-d64"; - } cmd[i++] = "-Xcheck:jni"; cmd[i++] = "-Xverify:all"; dumpfile= cdir + File.separator + class_name + ".hdump"; diff --git a/jdk/test/tools/launcher/6842838/Test6842838.sh b/jdk/test/tools/launcher/6842838/Test6842838.sh index b552152a9f3..011e2dd1789 100644 --- a/jdk/test/tools/launcher/6842838/Test6842838.sh +++ b/jdk/test/tools/launcher/6842838/Test6842838.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -48,16 +48,16 @@ case "$OS" in NULL=/dev/null PS=":" FS="/" - JAVA_EXE=${TESTJAVA}${FS}bin${FS}sparcv9${FS}java + JAVA_EXE=${TESTJAVA}${FS}bin${FS}java ;; * ) - printf "Only testing on sparcv9 (use libumem to reliably catch buffer overrun)\n" + printf "Only testing on solaris 64-bit (use libumem to reliably catch buffer overrun)\n" exit 0; ;; esac if [ ! -x ${JAVA_EXE} ]; then - printf "Warning: sparcv9 components not installed - skipping test.\n" + printf "Warning: 64-bit components not installed - skipping test.\n" exit 0 fi diff --git a/jdk/test/tools/launcher/ChangeDataModel.java b/jdk/test/tools/launcher/ChangeDataModel.java index 6b4b6bb19c4..86909eb2efb 100644 --- a/jdk/test/tools/launcher/ChangeDataModel.java +++ b/jdk/test/tools/launcher/ChangeDataModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ * @author Joseph D. Darcy, ksrini */ import java.io.File; -import java.util.HashMap; -import java.util.Map; public class ChangeDataModel extends TestHelper { private static final File TestJar = new File("test" + JAR_FILE_EXT); @@ -54,48 +52,14 @@ public class ChangeDataModel extends TestHelper { throw new Error("unsupported data model"); } - // test dual mode systems - if (isDualMode) { - // albeit dual mode we may not have the 64 bit components present - if (dualModePresent()) { - // 32-bit -> 64-bit - checkExecCount(javaCmd, "-d64"); - // 64-bit -> 32-bit - checkExecCount(java64Cmd, "-d32"); - - checkAcceptance(javaCmd, "-d64"); - checkAcceptance(java64Cmd, "-d32"); - } else { - System.out.println("Warning: no 64-bit components found;" + - " only one data model tested."); - } + // Negative tests: ensure that non-dual mode systems reject the + // complementary (other) data model + if (is32Bit) { + checkRejection(javaCmd, "-d64"); + } else if (is64Bit) { + checkRejection(javaCmd, "-d32"); } else { - // Negative tests: ensure that non-dual mode systems reject the - // complementary (other) data model - if (is32Bit) { - checkRejection(javaCmd, "-d64"); - } else if (is64Bit) { - checkRejection(javaCmd, "-d32"); - } else { - throw new Error("unsupported data model"); - } - } - } - - static void checkExecCount(String cmd, String dmodel) { - Map envMap = new HashMap<>(); - envMap.put(JLDEBUG_KEY, "true"); - TestResult tr = doExec(envMap, javaCmd, "-d64", - "-jar", TestJar.getAbsolutePath()); - int count = 0; - for (String x : tr.testOutput) { - if (x.contains(EXPECTED_MARKER)) { - count++; - if (count > 1) { - System.out.println(tr); - throw new RuntimeException("Maximum exec count of 1 execeeded"); - } - } + throw new Error("unsupported data model"); } } diff --git a/jdk/test/tools/launcher/ExecutionEnvironment.java b/jdk/test/tools/launcher/ExecutionEnvironment.java index 3b8b7eb848e..3587a1c0abe 100644 --- a/jdk/test/tools/launcher/ExecutionEnvironment.java +++ b/jdk/test/tools/launcher/ExecutionEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ * @bug 4780570 4731671 6354700 6367077 6670965 4882974 * @summary Checks for LD_LIBRARY_PATH and execution on *nixes * @compile -XDignore.symbol.file ExecutionEnvironment.java - * @run main ExecutionEnvironment + * @run main/othervm ExecutionEnvironment */ /* @@ -46,6 +46,9 @@ * b. LD_LIBRARY_PATH32 is ignored if set * 5. no extra symlink exists on Solaris ie. * jre/lib/$arch/libjvm.so -> client/libjvm.so + * 6. Since 32-bit Solaris is no longer supported we continue to ensure that + * the appropriate paths are ignored or used, additionally we also test to + * ensure the 64-bit isadir exists and contains appropriate links. * TODO: * a. perhaps we need to add a test to audit all environment variables are * in pristine condition after the launch, there may be a few that the @@ -54,10 +57,16 @@ */ import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import static java.nio.file.LinkOption.*; +import java.util.regex.Pattern; public class ExecutionEnvironment extends TestHelper { @@ -80,13 +89,14 @@ public class ExecutionEnvironment extends TestHelper { static final File testJarFile = new File("EcoFriendly.jar"); - static int errors = 0; - static int passes = 0; - static final String LIBJVM = TestHelper.isWindows ? "jvm.dll" : "libjvm" + (TestHelper.isMacOSX ? ".dylib" : ".so"); + public ExecutionEnvironment() { + createTestJar(); + } + static void createTestJar() { try { List codeList = new ArrayList<>(); @@ -111,13 +121,17 @@ public class ExecutionEnvironment extends TestHelper { throw new RuntimeException(fnfe); } } - + private void flagError(TestResult tr, String message) { + System.err.println(tr); + throw new RuntimeException(message); + } /* * tests if the launcher pollutes the LD_LIBRARY_PATH variables ie. there * should not be any new variables or pollution/mutations of any kind, the * environment should be pristine. */ - private static void ensureEcoFriendly() { + @Test + void testEcoFriendly() { TestResult tr = null; Map env = new HashMap<>(); @@ -129,17 +143,12 @@ public class ExecutionEnvironment extends TestHelper { tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath()); if (!tr.isNotZeroOutput()) { - System.out.println(tr); - throw new RuntimeException("Error: No output at all. Did the test execute ?"); + flagError(tr, "Error: No output at all. Did the test execute ?"); } for (String x : LD_PATH_STRINGS) { if (!tr.contains(x)) { - System.out.println("FAIL: did not get <" + x + ">"); - System.out.println(tr); - errors++; - } else { - passes++; + flagError(tr, "FAIL: did not get <" + x + ">"); } } } @@ -148,19 +157,15 @@ public class ExecutionEnvironment extends TestHelper { * ensures that there are no execs as long as we are in the same * data model */ - static void ensureNoExec() { + @Test + void testNoExec() { Map env = new HashMap<>(); env.put(JLDEBUG_KEY, "true"); TestResult tr = doExec(env, javaCmd, "-version"); if (tr.testOutput.contains(EXPECTED_MARKER)) { - System.out.println("FAIL: EnsureNoExecs: found expected warning <" + - EXPECTED_MARKER + + flagError(tr, "testNoExec: found warning <" + EXPECTED_MARKER + "> the process execing ?"); - errors++; - } else { - passes++; } - return; } /* @@ -173,8 +178,8 @@ public class ExecutionEnvironment extends TestHelper { * For Solaris 64-bit * * The LD_LIBRARY_PATH_64 should override LD_LIBRARY_PATH if specified */ - - static void verifyJavaLibraryPath() { + @Test + void testJavaLibraryPath() { TestResult tr = null; Map env = new HashMap<>(); @@ -200,88 +205,33 @@ public class ExecutionEnvironment extends TestHelper { env.put(pairs[0], pairs[1]); } - // verify the override occurs, since we know the invocation always - // uses by default is 32-bit, therefore we also set the test - // expectation to be the same. + // verify the override occurs for 64-bit system tr = doExec(env, javaCmd, "-jar", testJarFile.getAbsolutePath()); - verifyJavaLibraryPathOverride(tr, true); - - // try changing the model from 32 to 64 bit - if (dualModePresent() && is32Bit) { - // verify the override occurs - env.clear(); - for (String x : LD_PATH_STRINGS) { - String pairs[] = x.split("="); - env.put(pairs[0], pairs[1]); - } - tr = doExec(env, javaCmd, "-d64", "-jar", - testJarFile.getAbsolutePath()); - verifyJavaLibraryPathOverride(tr, false); - - // no override - env.clear(); - env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); - tr = doExec(env, javaCmd, "-jar", - testJarFile.getAbsolutePath()); - verifyJavaLibraryPathGeneric(tr); - } - - // try changing the model from 64 to 32 bit - if (java64Cmd != null && is64Bit) { - // verify the override occurs - env.clear(); - for (String x : LD_PATH_STRINGS) { - String pairs[] = x.split("="); - env.put(pairs[0], pairs[1]); - } - tr = doExec(env, java64Cmd, "-d32", "-jar", - testJarFile.getAbsolutePath()); - verifyJavaLibraryPathOverride(tr, true); - - // no override - env.clear(); - env.put(LD_LIBRARY_PATH, LD_LIBRARY_PATH_VALUE); - tr = doExec(env, java64Cmd, "-d32", "-jar", - testJarFile.getAbsolutePath()); - verifyJavaLibraryPathGeneric(tr); - } + verifyJavaLibraryPathOverride(tr, false); } } - private static void verifyJavaLibraryPathGeneric(TestResult tr) { + private void verifyJavaLibraryPathGeneric(TestResult tr) { if (!tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) { - System.out.print("FAIL: verifyJavaLibraryPath: "); - System.out.println(" java.library.path does not contain " + + flagError(tr, "testJavaLibraryPath: java.library.path does not contain " + LD_LIBRARY_PATH_VALUE); - System.out.println(tr); - errors++; - } else { - passes++; } } - private static void verifyJavaLibraryPathOverride(TestResult tr, + private void verifyJavaLibraryPathOverride(TestResult tr, boolean is32Bit) { // make sure the 32/64 bit value exists if (!tr.matches("java.library.path=.*" + (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE) + ".*")) { - System.out.print("FAIL: verifyJavaLibraryPathOverride: "); - System.out.println(" java.library.path does not contain " + + flagError(tr, "verifyJavaLibraryPathOverride: " + + " java.library.path does not contain " + (is32Bit ? LD_LIBRARY_PATH_32_VALUE : LD_LIBRARY_PATH_64_VALUE)); - System.out.println(tr); - errors++; - } else { - passes++; + } // make sure the generic value is absent - if (tr.matches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) { - System.out.print("FAIL: verifyJavaLibraryPathOverride: "); - System.out.println(" java.library.path contains " + - LD_LIBRARY_PATH_VALUE); - System.out.println(tr); - errors++; - } else { - passes++; + if (!tr.notMatches("java.library.path=.*" + LD_LIBRARY_PATH_VALUE + ".*")) { + flagError(tr, "verifyJavaLibraryPathOverride: " + + " java.library.path contains " + LD_LIBRARY_PATH_VALUE); } } @@ -289,34 +239,28 @@ public class ExecutionEnvironment extends TestHelper { * ensures we have indeed exec'ed the correct vm of choice, all VMs support * -server, however 32-bit VMs support -client and -server. */ - static void verifyVmSelection() { + @Test + void testVmSelection() { TestResult tr = null; if (is32Bit) { tr = doExec(javaCmd, "-client", "-version"); if (!tr.matches(".*Client VM.*")) { - System.out.println("FAIL: the expected vm -client did not launch"); - System.out.println(tr); - errors++; - } else { - passes++; + flagError(tr, "the expected vm -client did not launch"); } } tr = doExec(javaCmd, "-server", "-version"); if (!tr.matches(".*Server VM.*")) { - System.out.println("FAIL: the expected vm -server did not launch"); - System.out.println(tr); - errors++; - } else { - passes++; + flagError(tr, "the expected vm -server did not launch"); } } /* * checks to see there is no extra libjvm.so than needed */ - static void verifyNoSymLink() { + @Test + void testNoSymLink() { if (is64Bit) { return; } @@ -326,31 +270,65 @@ public class ExecutionEnvironment extends TestHelper { symLink = new File(JAVAHOME, libPathPrefix + getJreArch() + "/" + LIBJVM); if (symLink.exists()) { - System.out.println("FAIL: The symlink exists " + - symLink.getAbsolutePath()); - errors++; - } else { - passes++; + throw new RuntimeException("symlink exists " + symLink.getAbsolutePath()); } } + /* + * verify if all the symlinks in the images are created correctly, + * only on solaris, this test works only on images. + */ + @Test + void testSymLinks() throws Exception { + if (!isSolaris) + return; + verifySymLinks(JAVA_BIN); + verifySymLinks(JAVA_JRE_BIN); + } + // exclude non-consequential binaries or scripts co-packaged in other + // build phases + private final String excludeRE = + ".*jvisualvm.*" + + "|.*javaws.*" + + "|.*ControlPanel.*" + + "|.*java-rmi.cgi" + + "|.*jcontrol.*"; + private final Pattern symlinkExcludes = Pattern.compile(excludeRE); + + private void verifySymLinks(String bindir) throws IOException { + File binDir = new File(bindir); + System.err.println("verifying links in: " + bindir); + File isaDir = new File(binDir, getArch()).getAbsoluteFile(); + if (!isaDir.exists()) { + throw new RuntimeException("dir: " + isaDir + " does not exist"); + } + try (DirectoryStream ds = Files.newDirectoryStream(binDir.toPath())) { + for (Path p : ds) { + if (symlinkExcludes.matcher(p.toString()).matches() || + Files.isDirectory(p, NOFOLLOW_LINKS)) { + continue; + } + Path link = new File(isaDir, p.getFileName().toString()).toPath(); + if (Files.isSymbolicLink(link)) { + Path target = Files.readSymbolicLink(link); + if (target.startsWith("..") && p.endsWith(target.getFileName())) { + // System.out.println(target + " OK"); + continue; + } + System.err.println("target:" + target); + System.err.println("file:" + p); + } + throw new RuntimeException("could not find link to " + p); + } + } + + } public static void main(String... args) throws Exception { if (isWindows) { - System.out.println("Warning: noop on windows"); + System.err.println("Warning: test not applicable to windows"); return; } - // create our test jar first - createTestJar(); - ensureNoExec(); - verifyVmSelection(); - ensureEcoFriendly(); - verifyJavaLibraryPath(); - verifyNoSymLink(); - if (errors > 0) { - throw new Exception("ExecutionEnvironment: FAIL: with " + - errors + " errors and passes " + passes ); - } else { - System.out.println("ExecutionEnvironment: PASS " + passes); - } + ExecutionEnvironment ee = new ExecutionEnvironment(); + ee.run(args); } } diff --git a/jdk/test/tools/launcher/FXLauncherTest.java b/jdk/test/tools/launcher/FXLauncherTest.java index 1ed251bad19..32cd7c522a0 100644 --- a/jdk/test/tools/launcher/FXLauncherTest.java +++ b/jdk/test/tools/launcher/FXLauncherTest.java @@ -405,7 +405,7 @@ public class FXLauncherTest extends TestHelper { } } else { System.err.println("Warning: JavaFX components missing or not supported"); - System.err.println(" test passes vacuosly."); + System.err.println(" test passes vacuously."); } } } diff --git a/jdk/test/tools/launcher/RunpathTest.java b/jdk/test/tools/launcher/RunpathTest.java index 631be16d975..7738c4bdd9f 100644 --- a/jdk/test/tools/launcher/RunpathTest.java +++ b/jdk/test/tools/launcher/RunpathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,15 +64,9 @@ public class RunpathTest extends TestHelper { } void testRpath() { - if (isDualMode && is64Bit) { - String expectedRpath = ".*RPATH.*\\$ORIGIN/../../lib/" + getJreArch() - + ":\\$ORIGIN/../../jre/lib/" + getJreArch() + ".*"; - elfCheck(java64Cmd, expectedRpath); - } else { - String expectedRpath = ".*RPATH.*\\$ORIGIN/../lib/" + getJreArch() - + ":\\$ORIGIN/../jre/lib/" + getJreArch() + ".*"; - elfCheck(javaCmd, expectedRpath); - } + String expectedRpath = ".*RPATH.*\\$ORIGIN/../lib/" + getJreArch() + + ":\\$ORIGIN/../jre/lib/" + getJreArch() + ".*"; + elfCheck(javaCmd, expectedRpath); } public static void main(String... args) throws Exception { diff --git a/jdk/test/tools/launcher/Test7029048.java b/jdk/test/tools/launcher/Test7029048.java index aafee368432..9437c3e1817 100644 --- a/jdk/test/tools/launcher/Test7029048.java +++ b/jdk/test/tools/launcher/Test7029048.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,8 @@ */ /* - * 7029048: test for LD_LIBRARY_PATH set to different paths pointing which may - * contain a libjvm.so and may not, but we test to ensure that the launcher + * 7029048: test for LD_LIBRARY_PATH set to different paths which may or + * may not contain a libjvm.so, but we test to ensure that the launcher * behaves correctly in all cases. */ import java.io.File; @@ -50,8 +50,6 @@ public class Test7029048 extends TestHelper { private static final String LIBJVM = ExecutionEnvironment.LIBJVM; private static final String LD_LIBRARY_PATH = ExecutionEnvironment.LD_LIBRARY_PATH; - private static final String LD_LIBRARY_PATH_32 = - ExecutionEnvironment.LD_LIBRARY_PATH_32; private static final String LD_LIBRARY_PATH_64 = ExecutionEnvironment.LD_LIBRARY_PATH_64; @@ -70,24 +68,8 @@ public class Test7029048 extends TestHelper { private static final File dstClientDir = new File(dstLibArchDir, "client"); private static final File dstClientLibjvm = new File(dstClientDir, LIBJVM); - // used primarily to test the solaris variants in dual mode - private static final File dstOtherArchDir; - private static final File dstOtherServerDir; - private static final File dstOtherServerLibjvm; - private static final Map env = new HashMap<>(); - static { - if (isDualMode) { - dstOtherArchDir = new File(dstLibDir, getComplementaryJreArch()); - dstOtherServerDir = new File(dstOtherArchDir, "server"); - dstOtherServerLibjvm = new File(dstOtherServerDir, LIBJVM); - } else { - dstOtherArchDir = null; - dstOtherServerDir = null; - dstOtherServerLibjvm = null; - } - } static String getValue(String name, List in) { for (String x : in) { @@ -99,45 +81,20 @@ public class Test7029048 extends TestHelper { return null; } - static void run(boolean want32, String dflag, Map env, + static void run(Map env, int nLLPComponents, String caseID) { - final boolean want64 = want32 == false; env.put(ExecutionEnvironment.JLDEBUG_KEY, "true"); List cmdsList = new ArrayList<>(); - - // only for a dual-mode system - if (want64 && isDualMode) { - cmdsList.add(java64Cmd); - } else { - cmdsList.add(javaCmd); // a 32-bit java command for all - } - - /* - * empty or null strings can confuse the ProcessBuilder. A null flag - * indicates that the appropriate data model is enforced on the chosen - * launcher variant. - */ - - if (dflag != null) { - cmdsList.add(dflag); - } else { - cmdsList.add(want32 ? "-d32" : "-d64"); - } + cmdsList.add(javaCmd); cmdsList.add("-server"); cmdsList.add("-jar"); cmdsList.add(ExecutionEnvironment.testJarFile.getAbsolutePath()); String[] cmds = new String[cmdsList.size()]; TestResult tr = doExec(env, cmdsList.toArray(cmds)); + System.out.println(tr); analyze(tr, nLLPComponents, caseID); } - // no cross launch, ie. no change to the data model. - static void run(Map env, int nLLPComponents, String caseID) - throws IOException { - boolean want32 = is32Bit; - run(want32, null, env, nLLPComponents, caseID); - } - static void analyze(TestResult tr, int nLLPComponents, String caseID) { String envValue = getValue(LD_LIBRARY_PATH, tr.testOutput); /* @@ -192,10 +149,6 @@ public class Test7029048 extends TestHelper { copyFile(srcLibjvmSo, dstServerLibjvm); // does not matter if it is client or a server copyFile(srcLibjvmSo, dstClientLibjvm); - // does not matter if the arch do not match either - if (isDualMode) { - copyFile(srcLibjvmSo, dstOtherServerLibjvm); - } desc = "LD_LIBRARY_PATH should be set"; break; case LLP_SET_EMPTY_PATH: @@ -211,14 +164,6 @@ public class Test7029048 extends TestHelper { Files.deleteIfExists(dstServerLibjvm.toPath()); } - if (isDualMode) { - if (!dstOtherServerDir.exists()) { - Files.createDirectories(dstOtherServerDir.toPath()); - } else { - Files.deleteIfExists(dstOtherServerLibjvm.toPath()); - } - } - desc = "LD_LIBRARY_PATH should not be set"; break; case LLP_SET_NON_EXISTENT_PATH: @@ -245,40 +190,14 @@ public class Test7029048 extends TestHelper { env.put(LD_LIBRARY_PATH, dstClientDir.getAbsolutePath()); run(env, v.value + 1, "Case 2: " + desc); - if (!isDualMode) { - continue; // nothing more to do for Linux - } - - // Tests applicable only to solaris. - - // initialize test variables for dual mode operations - final File dst32ServerDir = is32Bit - ? dstServerDir - : dstOtherServerDir; - - final File dst64ServerDir = is64Bit - ? dstServerDir - : dstOtherServerDir; - - /* - * Case 3: set the appropriate LLP_XX flag, - * java32 -d32, LLP_32 is relevant, LLP_64 is ignored - * java64 -d64, LLP_64 is relevant, LLP_32 is ignored - */ - env.clear(); - env.put(LD_LIBRARY_PATH_32, dst32ServerDir.getAbsolutePath()); - env.put(LD_LIBRARY_PATH_64, dst64ServerDir.getAbsolutePath()); - run(is32Bit, null, env, v.value + 1, "Case 3: " + desc); - - /* - * Case 4: we are in dual mode environment, running 64-bit then - * we have the following scenarios: - * java32 -d64, LLP_64 is relevant, LLP_32 is ignored - * java64 -d32, LLP_32 is relevant, LLP_64 is ignored - */ - if (dualModePresent()) { - run(true, "-d64", env, v.value + 1, "Case 4A: " + desc); - run(false,"-d32", env, v.value + 1, "Case 4B: " + desc); + if (isSolaris) { + /* + * Case 3: set the appropriate LLP_XX flag, + * java64 -d64, LLP_64 is relevant, LLP_32 is ignored + */ + env.clear(); + env.put(LD_LIBRARY_PATH_64, dstServerDir.getAbsolutePath()); + run(env, v.value + 1, "Case 3: " + desc); } } return; @@ -297,9 +216,6 @@ public class Test7029048 extends TestHelper { if (errors > 0) { throw new Exception("Test7029048: FAIL: with " + errors + " errors and passes " + passes); - } else if (dualModePresent() && passes < 15) { - throw new Exception("Test7029048: FAIL: " + - "all tests did not run, expected " + 15 + " got " + passes); } else if (isSolaris && passes < 9) { throw new Exception("Test7029048: FAIL: " + "all tests did not run, expected " + 9 + " got " + passes); diff --git a/jdk/test/tools/launcher/TestHelper.java b/jdk/test/tools/launcher/TestHelper.java index 0115f057142..6f827f3ce0d 100644 --- a/jdk/test/tools/launcher/TestHelper.java +++ b/jdk/test/tools/launcher/TestHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,10 +66,10 @@ public class TestHelper { static final String JAVAHOME = System.getProperty("java.home"); static final String JAVA_BIN; + static final String JAVA_JRE_BIN; static final boolean isSDK = JAVAHOME.endsWith("jre"); static final String javaCmd; static final String javawCmd; - static final String java64Cmd; static final String javacCmd; static final String jarCmd; @@ -88,7 +88,7 @@ public class TestHelper { System.getProperty("os.name", "unknown").startsWith("SunOS"); static final boolean isLinux = System.getProperty("os.name", "unknown").startsWith("Linux"); - static final boolean isDualMode = isSolaris; + static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc"); // make a note of the golden default locale @@ -124,9 +124,12 @@ public class TestHelper { throw new RuntimeException("arch model is not 32 or 64 bit ?"); } compiler = ToolProvider.getSystemJavaCompiler(); - File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin") - : new File(JAVAHOME, "bin"); + File binDir = (isSDK) + ? new File((new File(JAVAHOME)).getParentFile(), "bin") + : new File(JAVAHOME, "bin"); JAVA_BIN = binDir.getAbsolutePath(); + JAVA_JRE_BIN = new File((new File(JAVAHOME)).getParentFile(), + (isSDK) ? "jre/bin" : "bin").getAbsolutePath(); File javaCmdFile = (isWindows) ? new File(binDir, "java.exe") : new File(binDir, "java"); @@ -165,17 +168,6 @@ public class TestHelper { throw new RuntimeException("java <" + javacCmd + "> must exist and should be executable"); } - if (isSolaris) { - File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64"); - File java64CmdFile= new File(sparc64BinDir, "java"); - if (java64CmdFile.exists() && java64CmdFile.canExecute()) { - java64Cmd = java64CmdFile.getAbsolutePath(); - } else { - java64Cmd = null; - } - } else { - java64Cmd = null; - } } void run(String[] args) throws Exception { int passed = 0, failed = 0; @@ -194,7 +186,13 @@ public class TestHelper { System.out.printf("Passed: %d, Failed: %d, ExitValue: %d%n", passed, failed, testExitValue); } catch (Throwable ex) { - System.out.printf("Test %s failed: %s %n", m, ex.getCause()); + System.out.printf("Test %s failed: %s %n", m, ex); + System.out.println("----begin detailed exceptions----"); + ex.printStackTrace(System.out); + for (Throwable t : ex.getSuppressed()) { + t.printStackTrace(System.out); + } + System.out.println("----end detailed exceptions----"); failed++; } } @@ -209,13 +207,6 @@ public class TestHelper { } } - /* - * is a dual mode available in the test jdk - */ - static boolean dualModePresent() { - return isDualMode && java64Cmd != null; - } - /* * usually the jre/lib/arch-name is the same as os.arch, except for x86. */ @@ -223,28 +214,9 @@ public class TestHelper { String arch = System.getProperty("os.arch"); return arch.equals("x86") ? "i386" : arch; } - - /* - * get the complementary jre arch ie. if sparc then return sparcv9 and - * vice-versa. - */ - static String getComplementaryJreArch() { - String arch = System.getProperty("os.arch"); - if (arch != null) { - switch (arch) { - case "sparc": - return "sparcv9"; - case "sparcv9": - return "sparc"; - case "x86": - return "amd64"; - case "amd64": - return "i386"; - } - } - return null; + static String getArch() { + return System.getProperty("os.arch"); } - static File getClassFile(File javaFile) { String s = javaFile.getAbsolutePath().replace(JAVA_FILE_EXT, CLASS_FILE_EXT); return new File(s); @@ -623,6 +595,16 @@ public class TestHelper { appendError("string <" + stringToMatch + "> not found"); return false; } + + boolean notMatches(String stringToMatch) { + for (String x : testOutput) { + if (!x.matches(stringToMatch)) { + return true; + } + } + appendError("string <" + stringToMatch + "> found"); + return false; + } } /** * Indicates that the annotated method is a test method. From b75899e391a18d1bb0278e3b74897bebce5a343b Mon Sep 17 00:00:00 2001 From: Vadim Pakhnushev Date: Mon, 30 Sep 2013 12:50:52 +0400 Subject: [PATCH 234/293] 8001119: [fingbugs] Evaluate necessity to make some arrays package protected Reviewed-by: prr, bae --- .../plugins/bmp/BMPCompressionTypes.java | 47 +++++++++++++++ .../sun/imageio/plugins/bmp/BMPConstants.java | 3 - .../imageio/plugins/bmp/BMPImageWriter.java | 59 +++++++------------ .../sun/imageio/plugins/bmp/BMPMetadata.java | 2 +- .../plugins/gif/GIFStreamMetadata.java | 7 +-- .../com/sun/imageio/plugins/jpeg/JPEG.java | 13 ++-- .../sun/imageio/plugins/png/PNGMetadata.java | 24 ++++---- .../plugins/bmp/BMPImageWriteParam.java | 3 +- 8 files changed, 90 insertions(+), 68 deletions(-) create mode 100644 jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPCompressionTypes.java diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPCompressionTypes.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPCompressionTypes.java new file mode 100644 index 00000000000..c61beeeb789 --- /dev/null +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPCompressionTypes.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.imageio.plugins.bmp; + +public class BMPCompressionTypes { + + private static final String[] compressionTypeNames = + {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"}; + + static int getType(String typeString) { + for (int i = 0; i < compressionTypeNames.length; i++) + if (compressionTypeNames[i].equals(typeString)) + return i; + return 0; + } + + static String getName(int type) { + return compressionTypeNames[type]; + } + + public static String[] getCompressionTypes() { + return compressionTypeNames.clone(); + } +} diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java index 7934eaf17c0..b99d28484a7 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java @@ -47,7 +47,4 @@ public interface BMPConstants { static final int BI_BITFIELDS = 3; static final int BI_JPEG = 4; static final int BI_PNG = 5; - - static final String[] compressionTypeNames = - {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"}; } diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java index bfed710d1fc..5d1241ec53f 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java @@ -25,7 +25,6 @@ package com.sun.imageio.plugins.bmp; -import java.awt.Point; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.ComponentSampleModel; @@ -42,7 +41,6 @@ import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; -import java.awt.image.WritableRaster; import java.awt.image.BufferedImage; import java.io.IOException; @@ -51,22 +49,16 @@ import java.nio.ByteOrder; import java.util.Iterator; import javax.imageio.IIOImage; -import javax.imageio.IIOException; import javax.imageio.ImageIO; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataNode; -import javax.imageio.metadata.IIOMetadataFormatImpl; -import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.stream.ImageOutputStream; import javax.imageio.event.IIOWriteProgressListener; import javax.imageio.event.IIOWriteWarningListener; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import javax.imageio.plugins.bmp.BMPImageWriteParam; import com.sun.imageio.plugins.common.ImageUtil; @@ -129,7 +121,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { meta.compression = getPreferredCompressionType(imageType); if (param != null && param.getCompressionMode() == ImageWriteParam.MODE_EXPLICIT) { - meta.compression = getCompressionType(param.getCompressionType()); + meta.compression = BMPCompressionTypes.getType(param.getCompressionType()); } meta.bitsPerPixel = (short)imageType.getColorModel().getPixelSize(); return meta; @@ -308,7 +300,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { switch(bmpParam.getCompressionMode()) { case ImageWriteParam.MODE_EXPLICIT: - compressionType = getCompressionType(bmpParam.getCompressionType()); + compressionType = BMPCompressionTypes.getType(bmpParam.getCompressionType()); break; case ImageWriteParam.MODE_COPY_FROM_METADATA: compressionType = bmpImageMetadata.compression; @@ -323,12 +315,12 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { if (!canEncodeImage(compressionType, colorModel, sampleModel)) { throw new IOException("Image can not be encoded with compression type " - + compressionTypeNames[compressionType]); + + BMPCompressionTypes.getName(compressionType)); } byte r[] = null, g[] = null, b[] = null, a[] = null; - if (compressionType == BMPConstants.BI_BITFIELDS) { + if (compressionType == BI_BITFIELDS) { bitsPerPixel = DataBuffer.getDataTypeSize(sampleModel.getDataType()); @@ -372,7 +364,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { // an exception related to unsupported image format throw new IOException("Image can not be encoded with " + "compression type " + - compressionTypeNames[compressionType]); + BMPCompressionTypes.getName(compressionType)); } } writeMaskToPalette(rmask, 0, r, g, b, a); @@ -511,8 +503,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { * Images with any other compression type must be wrote in the * bottom-up layout. */ - if (compressionType == BMPConstants.BI_RGB || - compressionType == BMPConstants.BI_BITFIELDS) + if (compressionType == BI_RGB || + compressionType == BI_BITFIELDS) { isTopDown = bmpParam.isTopDown(); } else { @@ -543,7 +535,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { if (isPalette == true) { // write palette - if (compressionType == BMPConstants.BI_BITFIELDS) { + if (compressionType == BI_BITFIELDS) { // write masks for red, green and blue components. for (int i=0; i<3; i++) { int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000); @@ -571,8 +563,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { int l; - if (compressionType == BMPConstants.BI_JPEG || - compressionType == BMPConstants.BI_PNG) { + if (compressionType == BI_JPEG || + compressionType == BI_PNG) { // prepare embedded buffer embedded_stream = new ByteArrayOutputStream(); @@ -657,7 +649,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { pos = sppsm.getOffset(startX, startY); } - if (compressionType == BMPConstants.BI_RGB || compressionType == BMPConstants.BI_BITFIELDS){ + if (compressionType == BI_RGB || compressionType == BI_BITFIELDS){ switch(dataType) { case DataBuffer.TYPE_BYTE: byte[] bdata = @@ -687,7 +679,7 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { for(int k=0; kColorSpaceType node - public static final String[] colorSpaceTypeNames = { + static final String[] colorSpaceTypeNames = { "GRAY", null, "RGB", "RGB", "GRAY", null, "RGB" }; diff --git a/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java b/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java index de35f5fe11e..230f7203fc4 100644 --- a/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java +++ b/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java @@ -29,6 +29,7 @@ import java.util.Locale; import javax.imageio.ImageWriteParam; import com.sun.imageio.plugins.bmp.BMPConstants; +import com.sun.imageio.plugins.bmp.BMPCompressionTypes; /** * A subclass of ImageWriteParam for encoding images in @@ -78,7 +79,7 @@ public class BMPImageWriteParam extends ImageWriteParam { super(locale); // Set compression types ("BI_RGB" denotes uncompressed). - compressionTypes = BMPConstants.compressionTypeNames.clone(); + compressionTypes = BMPCompressionTypes.getCompressionTypes(); // Set compression flag. canWriteCompressed = true; From 2722c5d966b290c2443127adce7074aff34cd734 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Mon, 30 Sep 2013 11:39:07 +0200 Subject: [PATCH 235/293] 8025226: TestPerfCountersAndMemoryPools.java fails with -Xmixed or -Xcomp Reviewed-by: brutisso, mgerdin --- .../TestPerfCountersAndMemoryPools.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java index e26aa6eee57..ac708bf7701 100644 --- a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java +++ b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java @@ -29,10 +29,11 @@ import static com.oracle.java.testlibrary.Asserts.*; /* @test TestPerfCountersAndMemoryPools * @bug 8023476 + * @library /testlibrary * @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace * report the same data. - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools */ public class TestPerfCountersAndMemoryPools { public static void main(String[] args) throws Exception { @@ -43,11 +44,11 @@ public class TestPerfCountersAndMemoryPools { } } - private static MemoryUsage getMemoryUsage(String memoryPoolName) { + private static MemoryPoolMXBean getMemoryPool(String memoryPoolName) { List pools = ManagementFactory.getMemoryPoolMXBeans(); for (MemoryPoolMXBean pool : pools) { if (pool.getName().equals(memoryPoolName)) { - return pool.getUsage(); + return pool; } } @@ -57,19 +58,18 @@ public class TestPerfCountersAndMemoryPools { private static void checkMemoryUsage(String memoryPoolName, String perfNS) throws Exception { - // Need to do a gc before each comparison to update the perf counters + MemoryPoolMXBean pool = getMemoryPool(memoryPoolName); + // Must do a GC to update performance counters System.gc(); - MemoryUsage mu = getMemoryUsage(memoryPoolName); - assertEQ(getMinCapacity(perfNS), mu.getInit()); + assertEQ(getMinCapacity(perfNS), pool.getUsage().getInit()); + // Must do a second GC to update the perfomance counters again, since + // the call pool.getUsage().getInit() could have allocated some + // metadata. System.gc(); - mu = getMemoryUsage(memoryPoolName); - assertEQ(getUsed(perfNS), mu.getUsed()); - - System.gc(); - mu = getMemoryUsage(memoryPoolName); - assertEQ(getCapacity(perfNS), mu.getCommitted()); + assertEQ(getUsed(perfNS), pool.getUsage().getUsed()); + assertEQ(getCapacity(perfNS), pool.getUsage().getCommitted()); } private static long getMinCapacity(String ns) throws Exception { From f144f37f49874361ac8f29946493213450b0ab16 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 30 Sep 2013 12:43:59 +0200 Subject: [PATCH 236/293] 8025441: G1: assert "assert(thread < _num_vtimes) failed: just checking" fails when G1ConcRefinementThreads > ParallelGCThreads The initialization for the remembered set summary data structures used the wrong thread count, i.e. number of worker threads instead of number of refinement threads. Reviewed-by: brutisso --- .../vm/gc_implementation/g1/g1RemSet.cpp | 8 +- .../gc_implementation/g1/g1RemSetSummary.cpp | 4 +- .../gc_implementation/g1/g1RemSetSummary.hpp | 2 +- .../gc/g1/TestSummarizeRSetStatsThreads.java | 83 +++++++++++++++++++ 4 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp index 0e06c472ffa..0ed37e6c5a5 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -83,7 +83,9 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs) for (uint i = 0; i < n_workers(); i++) { _cset_rs_update_cl[i] = NULL; } - _prev_period_summary.initialize(this, n_workers()); + if (G1SummarizeRSetStats) { + _prev_period_summary.initialize(this); + } } G1RemSet::~G1RemSet() { @@ -728,7 +730,7 @@ bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i, void G1RemSet::print_periodic_summary_info(const char* header) { G1RemSetSummary current; - current.initialize(this, n_workers()); + current.initialize(this); _prev_period_summary.subtract_from(¤t); print_summary_info(&_prev_period_summary, header); @@ -738,7 +740,7 @@ void G1RemSet::print_periodic_summary_info(const char* header) { void G1RemSet::print_summary_info() { G1RemSetSummary current; - current.initialize(this, n_workers()); + current.initialize(this); print_summary_info(¤t, " Cumulative RS summary"); } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp index 02e90d65103..cbf9e8e7fd3 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp @@ -77,12 +77,12 @@ double G1RemSetSummary::rs_thread_vtime(uint thread) const { return _rs_threads_vtimes[thread]; } -void G1RemSetSummary::initialize(G1RemSet* remset, uint num_workers) { +void G1RemSetSummary::initialize(G1RemSet* remset) { assert(_rs_threads_vtimes == NULL, "just checking"); assert(remset != NULL, "just checking"); _remset = remset; - _num_vtimes = num_workers; + _num_vtimes = ConcurrentG1Refine::thread_num(); _rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC); memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp index 7f5f377637a..9c019d99e13 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp @@ -84,7 +84,7 @@ public: void subtract_from(G1RemSetSummary* other); // initialize and get the first sampling - void initialize(G1RemSet* remset, uint num_workers); + void initialize(G1RemSet* remset); void print_on(outputStream* out); diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java b/hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java new file mode 100644 index 00000000000..99014e0cdf1 --- /dev/null +++ b/hotspot/test/gc/g1/TestSummarizeRSetStatsThreads.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestSummarizeRSetStatsThreads + * @bug 8025441 + * @summary Ensure that various values of worker threads/concurrent + * refinement threads do not crash the VM. + * @key gc + * @library /testlibrary + */ + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class TestSummarizeRSetStatsThreads { + + private static void runTest(int refinementThreads, int workerThreads) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+G1SummarizeRSetStats", + "-XX:G1ConcRefinementThreads=" + refinementThreads, + "-XX:ParallelGCThreads=" + workerThreads, + "-version"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + // check output to contain the string "Concurrent RS threads times (s)" followed by + // the correct number of values in the next line. + + // a zero in refinement thread numbers indicates that the value in ParallelGCThreads should be used. + // Additionally use at least one thread. + int expectedNumRefinementThreads = refinementThreads == 0 ? workerThreads : refinementThreads; + expectedNumRefinementThreads = Math.max(1, expectedNumRefinementThreads); + // create the pattern made up of n copies of a floating point number pattern + String numberPattern = String.format("%0" + expectedNumRefinementThreads + "d", 0) + .replace("0", "\\s+\\d+\\.\\d+"); + String pattern = "Concurrent RS threads times \\(s\\)$" + numberPattern + "$"; + Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout()); + + if (!m.find()) { + throw new Exception("Could not find correct output for concurrent RS threads times in stdout," + + " should match the pattern \"" + pattern + "\", but stdout is \n" + output.getStdout()); + } + output.shouldHaveExitValue(0); + } + + public static void main(String[] args) throws Exception { + if (!TestSummarizeRSetStatsTools.testingG1GC()) { + return; + } + // different valid combinations of number of refinement and gc worker threads + runTest(0, 0); + runTest(0, 5); + runTest(5, 0); + runTest(10, 10); + runTest(1, 2); + runTest(4, 3); + } +} From ac3d3445145a910229f8ddc8973f0c594c090b46 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Tue, 1 Oct 2013 07:52:52 +0200 Subject: [PATCH 237/293] 8025605: G1: Heap expansion logging misleading for fully expanded heap Reviewed-by: tschatzl, jwilhelm, jmasa --- .../share/vm/gc_implementation/g1/g1CollectedHeap.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index b5ea461690c..0976b0a1d2a 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -1772,7 +1772,6 @@ void G1CollectedHeap::update_committed_space(HeapWord* old_end, } bool G1CollectedHeap::expand(size_t expand_bytes) { - size_t old_mem_size = _g1_storage.committed_size(); size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); aligned_expand_bytes = align_size_up(aligned_expand_bytes, HeapRegion::GrainBytes); @@ -1782,6 +1781,13 @@ bool G1CollectedHeap::expand(size_t expand_bytes) { ergo_format_byte("attempted expansion amount"), expand_bytes, aligned_expand_bytes); + if (_g1_storage.uncommitted_size() == 0) { + ergo_verbose0(ErgoHeapSizing, + "did not expand the heap", + ergo_format_reason("heap already fully expanded")); + return false; + } + // First commit the memory. HeapWord* old_end = (HeapWord*) _g1_storage.high(); bool successful = _g1_storage.expand_by(aligned_expand_bytes); @@ -1840,7 +1846,6 @@ bool G1CollectedHeap::expand(size_t expand_bytes) { } void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { - size_t old_mem_size = _g1_storage.committed_size(); size_t aligned_shrink_bytes = ReservedSpace::page_align_size_down(shrink_bytes); aligned_shrink_bytes = align_size_down(aligned_shrink_bytes, From a5369d4610261977e87e1874a811d8a5a4c6b0a0 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 1 Oct 2013 10:58:24 +0200 Subject: [PATCH 238/293] 8006661: Use LC_ALL=C instead of LANG=C compare.sh Reviewed-by: tbell --- common/bin/compare.sh | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/common/bin/compare.sh b/common/bin/compare.sh index aacdc718b6f..732c6757fc7 100644 --- a/common/bin/compare.sh +++ b/common/bin/compare.sh @@ -76,13 +76,13 @@ diff_text() { TMP=1 if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then - TMP=$(LANG=C $DIFF $OTHER_FILE $THIS_FILE | \ + TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>] Ant-Version: Apache Ant .*/d' \ -e '/[<>] Created-By: .* (Oracle Corporation).*/d') fi if test "x$SUFFIX" = "xjava"; then - TMP=$(LANG=C $DIFF $OTHER_FILE $THIS_FILE | \ + TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \ $GREP '^[<>]' | \ $SED -e '/[<>] \* from.*\.idl/d' \ -e '/[<>] \*.*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \ @@ -121,8 +121,8 @@ diff_text() { # | $SED -e '/^#/d' -e '/^$/d' \ # -e :a -e '/\\$/N; s/\\\n//; ta' \ # -e 's/^[ \t]*//;s/[ \t]*$//' \ -# -e 's/\\=/=/' | LANG=C $SORT > $OTHER_FILE.cleaned - TMP=$(LANG=C $DIFF $OTHER_FILE.cleaned $THIS_FILE) +# -e 's/\\=/=/' | LC_ALL=C $SORT > $OTHER_FILE.cleaned + TMP=$(LC_ALL=C $DIFF $OTHER_FILE.cleaned $THIS_FILE) fi if test -n "$TMP"; then echo Files $OTHER_FILE and $THIS_FILE differ @@ -410,11 +410,11 @@ compare_zip_file() { CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff # On solaris, there is no -q option. if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then - LANG=C $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \ + LC_ALL=C $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \ | $GREP -v -e "^<" -e "^>" -e "^Common subdirectories:" \ > $CONTENTS_DIFF_FILE else - LANG=C $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE + LC_ALL=C $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE fi ONLY_OTHER=$($GREP "^Only in $OTHER_UNZIPDIR" $CONTENTS_DIFF_FILE) @@ -459,11 +459,11 @@ compare_zip_file() { if [ -n "$SHOW_DIFFS" ]; then for i in $(cat $WORK_DIR/$ZIP_FILE.difflist) ; do if [ -f "${OTHER_UNZIPDIR}/$i.javap" ]; then - LANG=C $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap + LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap elif [ -f "${OTHER_UNZIPDIR}/$i.cleaned" ]; then - LANG=C $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i + LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i else - LANG=C $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i + LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i fi done fi @@ -703,7 +703,7 @@ compare_bin_file() { $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this fi - LANG=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff + LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff if [ -s $WORK_FILE_BASE.symbols.diff ]; then SYM_MSG=" diff " if [[ "$ACCEPTED_SYM_DIFF" != *"$BIN_FILE"* ]]; then @@ -732,8 +732,8 @@ compare_bin_file() { (cd $FILE_WORK_DIR && $CP $THIS_FILE . && $LDD_CMD $NAME 2 $WORK_FILE_BASE.deps.this.uniq) (cd $FILE_WORK_DIR && $RM -f $NAME) - LANG=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff - LANG=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq + LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this > $WORK_FILE_BASE.deps.diff + LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq > $WORK_FILE_BASE.deps.diff.uniq if [ -s $WORK_FILE_BASE.deps.diff ]; then if [ -s $WORK_FILE_BASE.deps.diff.uniq ]; then @@ -768,7 +768,7 @@ compare_bin_file() { if [ -n "$FULLDUMP_CMD" ] && [ -z "$SKIP_FULLDUMP_DIFF" ]; then $FULLDUMP_CMD $OTHER_FILE > $WORK_FILE_BASE.fulldump.other 2>&1 $FULLDUMP_CMD $THIS_FILE > $WORK_FILE_BASE.fulldump.this 2>&1 - LANG=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff + LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this > $WORK_FILE_BASE.fulldump.diff if [ -s $WORK_FILE_BASE.fulldump.diff ]; then ELF_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.fulldump.diff | awk '{print $5}') @@ -802,7 +802,7 @@ compare_bin_file() { $DIS_CMD $OTHER_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.other 2>&1 $DIS_CMD $THIS_FILE | $GREP -v $NAME | $DIS_DIFF_FILTER > $WORK_FILE_BASE.dis.this 2>&1 - LANG=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff + LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff if [ -s $WORK_FILE_BASE.dis.diff ]; then DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}') From 91c55cc45ee0c3d6063459eac6d6900e4f362869 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 1 Oct 2013 11:08:23 +0200 Subject: [PATCH 239/293] 8019219: Fix typo in jdk/makefiles "default" targets Reviewed-by: erikj --- jdk/makefiles/CompileLaunchers.gmk | 2 +- jdk/makefiles/CompileNativeLibraries.gmk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk index ec96b53a83c..d4ce031cd7f 100644 --- a/jdk/makefiles/CompileLaunchers.gmk +++ b/jdk/makefiles/CompileLaunchers.gmk @@ -23,7 +23,7 @@ # questions. # -defalt: all +default: all include $(SPEC) include MakeBase.gmk diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 8c59cecc4f7..52b02f15ef0 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -23,7 +23,7 @@ # questions. # -defalt: all +default: all include $(SPEC) include MakeBase.gmk From 71a3a55630eb9f0bd45b086f8485d37fe41f7473 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Tue, 1 Oct 2013 08:10:42 -0400 Subject: [PATCH 240/293] 8011311: Private interface methods. Default conflicts:ICCE. no erased_super_default Reviewed-by: coleenp, bharadwaj, minqi --- .../share/vm/classfile/classFileParser.cpp | 4 +- .../src/share/vm/classfile/defaultMethods.cpp | 216 ++--------------- .../src/share/vm/classfile/defaultMethods.hpp | 12 +- .../src/share/vm/interpreter/linkResolver.cpp | 222 ++++++++++++++---- hotspot/src/share/vm/oops/instanceKlass.cpp | 4 +- hotspot/src/share/vm/oops/klassVtable.cpp | 10 +- 6 files changed, 200 insertions(+), 268 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 70662d3e8b8..68a3eb4bd11 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -2545,7 +2545,9 @@ Array* ClassFileParser::parse_methods(bool is_interface, if (method->is_final()) { *has_final_method = true; } - if (is_interface && !method->is_abstract() && !method->is_static()) { + if (is_interface && !(*has_default_methods) + && !method->is_abstract() && !method->is_static() + && !method->is_private()) { // default method *has_default_methods = true; } diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index 99a45b55b6d..df3878a1ea1 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -325,6 +325,7 @@ class MethodFamily : public ResourceObj { Method* _selected_target; // Filled in later, if a unique target exists Symbol* _exception_message; // If no unique target is found + Symbol* _exception_name; // If no unique target is found bool contains_method(Method* method) { int* lookup = _member_index.get(method); @@ -350,7 +351,7 @@ class MethodFamily : public ResourceObj { public: MethodFamily() - : _selected_target(NULL), _exception_message(NULL) {} + : _selected_target(NULL), _exception_message(NULL), _exception_name(NULL) {} void set_target_if_empty(Method* m) { if (_selected_target == NULL && !m->is_overpass()) { @@ -383,6 +384,7 @@ class MethodFamily : public ResourceObj { Method* get_selected_target() { return _selected_target; } Symbol* get_exception_message() { return _exception_message; } + Symbol* get_exception_name() { return _exception_name; } // Either sets the target or the exception error message void determine_target(InstanceKlass* root, TRAPS) { @@ -400,15 +402,18 @@ class MethodFamily : public ResourceObj { if (qualified_methods.length() == 0) { _exception_message = generate_no_defaults_message(CHECK); + _exception_name = vmSymbols::java_lang_AbstractMethodError(); } else if (qualified_methods.length() == 1) { Method* method = qualified_methods.at(0); if (method->is_abstract()) { _exception_message = generate_abstract_method_message(method, CHECK); + _exception_name = vmSymbols::java_lang_AbstractMethodError(); } else { _selected_target = qualified_methods.at(0); } } else { _exception_message = generate_conflicts_message(&qualified_methods,CHECK); + _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); } assert((has_target() ^ throws_exception()) == 1, @@ -459,8 +464,9 @@ class MethodFamily : public ResourceObj { void print_exception(outputStream* str, int indent) { assert(throws_exception(), "Should be called otherwise"); + assert(_exception_name != NULL, "exception_name should be set"); streamIndentor si(str, indent * 2); - str->indent().print_cr("%s", _exception_message->as_C_string()); + str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string()); } #endif // ndef PRODUCT }; @@ -670,7 +676,10 @@ class FindMethodsByErasedSig : public HierarchyVisitor { InstanceKlass* iklass = current_class(); Method* m = iklass->find_method(_method_name, _method_signature); - if (m != NULL) { + // private interface methods are not candidates for default methods + // invokespecial to private interface methods doesn't use default method logic + // future: take access controls into account for superclass methods + if (m != NULL && (!iklass->is_interface() || m->is_public())) { if (_family == NULL) { _family = new StatefulMethodFamily(); } @@ -782,200 +791,7 @@ void DefaultMethods::generate_default_methods( #endif // ndef PRODUCT } -/** - * Interface inheritance rules were used to find a unique default method - * candidate for the resolved class. This - * method is only viable if it would also be in the set of default method - * candidates if we ran a full analysis on the current class. - * - * The only reason that the method would not be in the set of candidates for - * the current class is if that there's another matching method - * which is "more specific" than the found method -- i.e., one could find a - * path in the interface hierarchy in which the matching method appears - * before we get to '_target'. - * - * In order to determine this, we examine all of the implemented - * interfaces. If we find path that leads to the '_target' interface, then - * we examine that path to see if there are any methods that would shadow - * the selected method along that path. - */ -class ShadowChecker : public HierarchyVisitor { - protected: - Thread* THREAD; - InstanceKlass* _target; - - Symbol* _method_name; - InstanceKlass* _method_holder; - bool _found_shadow; - - - public: - - ShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, - InstanceKlass* target) - : THREAD(thread), _method_name(name), _method_holder(holder), - _target(target), _found_shadow(false) {} - - void* new_node_data(InstanceKlass* cls) { return NULL; } - void free_node_data(void* data) { return; } - - bool visit() { - InstanceKlass* ik = current_class(); - if (ik == _target && current_depth() == 1) { - return false; // This was the specified super -- no need to search it - } - if (ik == _method_holder || ik == _target) { - // We found a path that should be examined to see if it shadows _method - if (path_has_shadow()) { - _found_shadow = true; - cancel_iteration(); - } - return false; // no need to continue up hierarchy - } - return true; - } - - virtual bool path_has_shadow() = 0; - bool found_shadow() { return _found_shadow; } -}; - -// Used for Invokespecial. -// Invokespecial is allowed to invoke a concrete interface method -// and can be used to disambuiguate among qualified candidates, -// which are methods in immediate superinterfaces, -// but may not be used to invoke a candidate that would be shadowed -// from the perspective of the caller. -// Invokespecial is also used in the overpass generation today -// We re-run the shadowchecker because we can't distinguish this case, -// but it should return the same answer, since the overpass target -// is now the invokespecial caller. -class ErasedShadowChecker : public ShadowChecker { - private: - bool path_has_shadow() { - - for (int i = current_depth() - 1; i > 0; --i) { - InstanceKlass* ik = class_at_depth(i); - - if (ik->is_interface()) { - int end; - int start = ik->find_method_by_name(_method_name, &end); - if (start != -1) { - return true; - } - } - } - return false; - } - public: - - ErasedShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, - InstanceKlass* target) - : ShadowChecker(thread, name, holder, target) {} -}; - -// Find the unique qualified candidate from the perspective of the super_class -// which is the resolved_klass, which must be an immediate superinterface -// of klass -Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* super_class, Symbol* method_name, Symbol* sig, TRAPS) { - - FindMethodsByErasedSig visitor(method_name, sig); - visitor.run(super_class); // find candidates from resolved_klass - - MethodFamily* family; - visitor.get_discovered_family(&family); - - if (family != NULL) { - family->determine_target(current_class, CHECK_NULL); // get target from current_class - - if (family->has_target()) { - Method* target = family->get_selected_target(); - InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); - - // Verify that the identified method is valid from the context of - // the current class, which is the caller class for invokespecial - // link resolution, i.e. ensure there it is not shadowed. - // You can use invokespecial to disambiguate interface methods, but - // you can not use it to skip over an interface method that would shadow it. - ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); - checker.run(current_class); - - if (checker.found_shadow()) { -#ifndef PRODUCT - if (TraceDefaultMethods) { - tty->print_cr(" Only candidate found was shadowed."); - } -#endif // ndef PRODUCT - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - "Accessible default method not found", NULL); - } else { -#ifndef PRODUCT - if (TraceDefaultMethods) { - family->print_sig_on(tty, target->signature(), 1); - } -#endif // ndef PRODUCT - return target; - } - } else { - assert(family->throws_exception(), "must have target or throw"); - THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), - family->get_exception_message()->as_C_string(), NULL); - } - } else { - // no method found - ResourceMark rm(THREAD); - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), - Method::name_and_sig_as_C_string(current_class, - method_name, sig), NULL); - } -} -// This is called during linktime when we find an invokespecial call that -// refers to a direct superinterface. It indicates that we should find the -// default method in the hierarchy of that superinterface, and if that method -// would have been a candidate from the point of view of 'this' class, then we -// return that method. -// This logic assumes that the super is a direct superclass of the caller -Method* DefaultMethods::find_super_default( - Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) { - - ResourceMark rm(THREAD); - - assert(cls != NULL && super != NULL, "Need real classes"); - - InstanceKlass* current_class = InstanceKlass::cast(cls); - InstanceKlass* super_class = InstanceKlass::cast(super); - - // Keep entire hierarchy alive for the duration of the computation - KeepAliveRegistrar keepAlive(THREAD); - KeepAliveVisitor loadKeepAlive(&keepAlive); - loadKeepAlive.run(current_class); // get hierarchy from current class - -#ifndef PRODUCT - if (TraceDefaultMethods) { - tty->print_cr("Finding super default method %s.%s%s from %s", - super_class->name()->as_C_string(), - method_name->as_C_string(), sig->as_C_string(), - current_class->name()->as_C_string()); - } -#endif // ndef PRODUCT - - assert(super_class->is_interface(), "only call for default methods"); - - Method* target = NULL; - target = find_erased_super_default(current_class, super_class, - method_name, sig, CHECK_NULL); - -#ifndef PRODUCT - if (target != NULL) { - if (TraceDefaultMethods) { - tty->print(" Returning "); - print_method(tty, target, true); - tty->print_cr(""); - } - } -#endif // ndef PRODUCT - return target; -} #ifndef PRODUCT // Return true is broad type is a covariant return of narrow type @@ -1035,10 +851,9 @@ static int assemble_redirect( return parameter_count; } -static int assemble_abstract_method_error( - BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* message, TRAPS) { +static int assemble_method_error( + BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) { - Symbol* errorName = vmSymbols::java_lang_AbstractMethodError(); Symbol* init = vmSymbols::object_initializer_name(); Symbol* sig = vmSymbols::string_void_signature(); @@ -1150,8 +965,7 @@ static void create_overpasses( &bpool, &buffer, slot->signature(), selected, CHECK); } } else if (method->throws_exception()) { - max_stack = assemble_abstract_method_error( - &bpool, &buffer, method->get_exception_message(), CHECK); + max_stack = assemble_method_error(&bpool, &buffer, method->get_exception_name(), method->get_exception_message(), CHECK); } if (max_stack != 0) { AccessFlags flags = accessFlags_from( diff --git a/hotspot/src/share/vm/classfile/defaultMethods.hpp b/hotspot/src/share/vm/classfile/defaultMethods.hpp index 8a31eee6b45..9c7470aa944 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.hpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,15 +44,5 @@ class DefaultMethods : AllStatic { // the class. static void generate_default_methods( InstanceKlass* klass, GrowableArray* mirandas, TRAPS); - - - // Called during linking when an invokespecial to an direct interface - // method is found. Selects and returns a method if there is a unique - // default method in the 'super_iface' part of the hierarchy which is - // also a candidate default for 'this_klass'. Otherwise throws an AME. - static Method* find_super_default( - Klass* this_klass, Klass* super_iface, - Symbol* method_name, Symbol* method_sig, TRAPS); }; - #endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp index 3f9d0d19336..a12b68b2f83 100644 --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp @@ -1,5 +1,4 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -573,6 +572,16 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, } if (check_access) { + // JDK8 adds non-public interface methods, and accessability check requirement + assert(current_klass.not_null() , "current_klass should not be null"); + + // check if method can be accessed by the referring class + check_method_accessability(current_klass, + resolved_klass, + KlassHandle(THREAD, resolved_method->method_holder()), + resolved_method, + CHECK); + HandleMark hm(THREAD); Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); @@ -604,6 +613,20 @@ void LinkResolver::resolve_interface_method(methodHandle& resolved_method, } } } + + if (TraceItables && Verbose) { + ResourceMark rm(THREAD); + tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", + (current_klass.is_null() ? "" : current_klass->internal_name()), + (resolved_klass.is_null() ? "" : resolved_klass->internal_name()), + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + resolved_method->method_holder()->internal_name() + ); + resolved_method->access_flags().print_on(tty); + tty->cr(); + } } //------------------------------------------------------------------------------------------------------------------------ @@ -795,26 +818,12 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { - if (resolved_klass->is_interface() && current_klass() != NULL) { - // If the target class is a direct interface, treat this as a "super" - // default call. - // - // If the current method is an overpass that happens to call a direct - // super-interface's method, then we'll end up rerunning the default method - // analysis even though we don't need to, but that's ok since it will end - // up with the same answer. - InstanceKlass* ik = InstanceKlass::cast(current_klass()); - Array* interfaces = ik->local_interfaces(); - int num_interfaces = interfaces->length(); - for (int index = 0; index < num_interfaces; index++) { - if (interfaces->at(index) == resolved_klass()) { - Method* method = DefaultMethods::find_super_default(current_klass(), - resolved_klass(), method_name, method_signature, CHECK); - resolved_method = methodHandle(THREAD, method); - return; - } - } - } + // Invokespecial is called for multiple special reasons: + // + // local private method invocation, for classes and interfaces + // superclass.method, which can also resolve to a default method + // and the selected method is recalculated relative to the direct superclass + // superinterface.method, which explicitly does not check shadowing resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); @@ -844,6 +853,26 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method resolved_method->signature())); THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } + if (TraceItables && Verbose) { + ResourceMark rm(THREAD); + tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", + (current_klass.is_null() ? "" : current_klass->internal_name()), + (resolved_klass.is_null() ? "" : resolved_klass->internal_name()), + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + resolved_method->method_holder()->internal_name() + ); + resolved_method->access_flags().print_on(tty); + if (resolved_method->method_holder()->is_interface() && + !resolved_method->is_abstract()) { + tty->print("default"); + } + if (resolved_method->is_overpass()) { + tty->print("overpass"); + } + tty->cr(); + } } // throws runtime exceptions @@ -851,23 +880,24 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle KlassHandle current_klass, bool check_access, TRAPS) { // resolved method is selected method unless we have an old-style lookup + // for a superclass method + // Invokespecial for a superinterface, resolved method is selected method, + // no checks for shadowing methodHandle sel_method(THREAD, resolved_method()); // check if this is an old-style super call and do a new lookup if so { KlassHandle method_klass = KlassHandle(THREAD, resolved_method->method_holder()); - const bool direct_calling_default_method = - resolved_klass() != NULL && resolved_method() != NULL && - resolved_klass->is_interface() && !resolved_method->is_abstract(); - - if (!direct_calling_default_method && - check_access && + if (check_access && // a) check if ACC_SUPER flag is set for the current class (current_klass->is_super() || !AllowNonVirtualCalls) && - // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) - current_klass->is_subtype_of(method_klass()) && - current_klass() != method_klass() && + // b) check if the class of the resolved_klass is a superclass + // (not supertype in order to exclude interface classes) of the current class. + // This check is not performed for super.invoke for interface methods + // in super interfaces. + current_klass->is_subclass_of(resolved_klass()) && + current_klass() != resolved_klass() && // c) check if the method is not resolved_method->name() != vmSymbols::object_initializer_name()) { // Lookup super method @@ -905,6 +935,23 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle sel_method->signature())); } + if (TraceItables && Verbose) { + ResourceMark rm(THREAD); + tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ", + (resolved_klass.is_null() ? "" : resolved_klass->internal_name()), + Method::name_and_sig_as_C_string(resolved_klass(), + sel_method->name(), + sel_method->signature()), + sel_method->method_holder()->internal_name() + ); + sel_method->access_flags().print_on(tty); + if (sel_method->method_holder()->is_interface() && + !sel_method->is_abstract()) { + tty->print("default"); + } + tty->cr(); + } + // setup result result.set_static(resolved_klass, sel_method, CHECK); } @@ -927,6 +974,18 @@ void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); + // check if private interface method + if (resolved_klass->is_interface() && resolved_method->is_private()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s", + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + (current_klass.is_null() ? "" : current_klass->internal_name())); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + // check if not static if (resolved_method->is_static()) { ResourceMark rm(THREAD); @@ -936,6 +995,27 @@ void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method resolved_method->signature())); THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); } + + if (PrintVtables && Verbose) { + ResourceMark rm(THREAD); + tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", + (current_klass.is_null() ? "" : current_klass->internal_name()), + (resolved_klass.is_null() ? "" : resolved_klass->internal_name()), + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + resolved_method->method_holder()->internal_name() + ); + resolved_method->access_flags().print_on(tty); + if (resolved_method->method_holder()->is_interface() && + !resolved_method->is_abstract()) { + tty->print("default"); + } + if (resolved_method->is_overpass()) { + tty->print("overpass"); + } + tty->cr(); + } } // throws runtime exceptions @@ -1012,6 +1092,27 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, selected_method->signature())); } + if (PrintVtables && Verbose) { + ResourceMark rm(THREAD); + tty->print("invokevirtual selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, vtable_index:%d, access_flags: ", + (recv_klass.is_null() ? "" : recv_klass->internal_name()), + (resolved_klass.is_null() ? "" : resolved_klass->internal_name()), + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + selected_method->method_holder()->internal_name(), + vtable_index + ); + selected_method->access_flags().print_on(tty); + if (selected_method->method_holder()->is_interface() && + !selected_method->is_abstract()) { + tty->print("default"); + } + if (resolved_method->is_overpass()) { + tty->print("overpass"); + } + tty->cr(); + } // setup result result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); } @@ -1042,6 +1143,17 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand THROW(vmSymbols::java_lang_NullPointerException()); } + // check if private interface method + if (resolved_klass->is_interface() && resolved_method->is_private()) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s", + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature())); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + // check if receiver klass implements the resolved interface if (!recv_klass->is_subtype_of(resolved_klass())) { ResourceMark rm(THREAD); @@ -1071,28 +1183,15 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand resolved_method->signature())); } // check access - if (sel_method->method_holder()->is_interface()) { - // Method holder is an interface. Throw Illegal Access Error if sel_method - // is neither public nor private. - if (!(sel_method->is_public() || sel_method->is_private())) { - ResourceMark rm(THREAD); - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), - Method::name_and_sig_as_C_string(recv_klass(), - sel_method->name(), - sel_method->signature())); - } - } - else { - // Method holder is a class. Throw Illegal Access Error if sel_method - // is not public. - if (!sel_method->is_public()) { - ResourceMark rm(THREAD); - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), - Method::name_and_sig_as_C_string(recv_klass(), - sel_method->name(), - sel_method->signature())); - } + // Throw Illegal Access Error if sel_method is not public. + if (!sel_method->is_public()) { + ResourceMark rm(THREAD); + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), + Method::name_and_sig_as_C_string(recv_klass(), + sel_method->name(), + sel_method->signature())); } + // check if abstract if (check_null_and_abstract && sel_method->is_abstract()) { ResourceMark rm(THREAD); @@ -1109,6 +1208,27 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand return; } int itable_index = resolved_method()->itable_index(); + + if (TraceItables && Verbose) { + ResourceMark rm(THREAD); + tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ", + (recv_klass.is_null() ? "" : recv_klass->internal_name()), + (resolved_klass.is_null() ? "" : resolved_klass->internal_name()), + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + sel_method->method_holder()->internal_name() + ); + sel_method->access_flags().print_on(tty); + if (sel_method->method_holder()->is_interface() && + !sel_method->is_abstract()) { + tty->print("default"); + } + if (resolved_method->is_overpass()) { + tty->print("overpass"); + } + tty->cr(); + } result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK); } diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp index 859c6aa3ee6..82997ed6d15 100644 --- a/hotspot/src/share/vm/oops/instanceKlass.cpp +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp @@ -1419,6 +1419,8 @@ Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) c } // lookup a method in all the interfaces that this class implements +// Do NOT return private or static methods, new in JDK8 which are not externally visible +// They should only be found in the initial InterfaceMethodRef Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const { Array* all_ifs = transitive_interfaces(); @@ -1427,7 +1429,7 @@ Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name, for (int i = 0; i < num_ifs; i++) { ik = InstanceKlass::cast(all_ifs->at(i)); Method* m = ik->lookup_method(name, signature); - if (m != NULL) { + if (m != NULL && m->is_public() && !m->is_static()) { return m; } } diff --git a/hotspot/src/share/vm/oops/klassVtable.cpp b/hotspot/src/share/vm/oops/klassVtable.cpp index 7105368840f..6788c619ca5 100644 --- a/hotspot/src/share/vm/oops/klassVtable.cpp +++ b/hotspot/src/share/vm/oops/klassVtable.cpp @@ -292,9 +292,10 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar return allocate_new; } - // private methods always have a new entry in the vtable + // private methods in classes always have a new entry in the vtable // specification interpretation since classic has // private methods not overriding + // JDK8 adds private methods in interfaces which require invokespecial if (target_method()->is_private()) { return allocate_new; } @@ -442,9 +443,10 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, return true; } - // private methods always have a new entry in the vtable + // private methods in classes always have a new entry in the vtable // specification interpretation since classic has // private methods not overriding + // JDK8 adds private methods in interfaces which require invokespecial if (target_method()->is_private()) { return true; } @@ -520,7 +522,7 @@ bool klassVtable::is_miranda_entry_at(int i) { Klass* method_holder = m->method_holder(); InstanceKlass *mhk = InstanceKlass::cast(method_holder); - // miranda methods are interface methods in a class's vtable + // miranda methods are public abstract instance interface methods in a class's vtable if (mhk->is_interface()) { assert(m->is_public(), "should be public"); assert(ik()->implements_interface(method_holder) , "this class should implement the interface"); @@ -534,6 +536,8 @@ bool klassVtable::is_miranda_entry_at(int i) { // "miranda" means not static, not defined by this class, and not defined // in super unless it is private and therefore inaccessible to this class. // the caller must make sure that the method belongs to an interface implemented by the class +// Miranda methods only include public interface instance methods +// Not private methods, not static methods, not default = concrete abstract bool klassVtable::is_miranda(Method* m, Array* class_methods, Klass* super) { if (m->is_static()) { return false; From fb39220608701579589f9cf6e58c21bac835d3d2 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 1 Oct 2013 08:54:05 -0400 Subject: [PATCH 241/293] 8022187: Missing ResourceMark crash when assertion using FormatBufferResource fails Uses stack for the format buffer instead of resource memory Reviewed-by: kvn, coleenp --- hotspot/src/share/vm/utilities/array.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/utilities/array.hpp b/hotspot/src/share/vm/utilities/array.hpp index fb32f5ca8fd..9f8e45f3243 100644 --- a/hotspot/src/share/vm/utilities/array.hpp +++ b/hotspot/src/share/vm/utilities/array.hpp @@ -353,9 +353,9 @@ protected: // sort the array. bool contains(const T& x) const { return index_of(x) >= 0; } - T at(int i) const { assert(i >= 0 && i< _length, err_msg_res("oob: 0 <= %d < %d", i, _length)); return _data[i]; } - void at_put(const int i, const T& x) { assert(i >= 0 && i< _length, err_msg_res("oob: 0 <= %d < %d", i, _length)); _data[i] = x; } - T* adr_at(const int i) { assert(i >= 0 && i< _length, err_msg_res("oob: 0 <= %d < %d", i, _length)); return &_data[i]; } + T at(int i) const { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return _data[i]; } + void at_put(const int i, const T& x) { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); _data[i] = x; } + T* adr_at(const int i) { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return &_data[i]; } int find(const T& x) { return index_of(x); } T at_acquire(const int which) { return OrderAccess::load_acquire(adr_at(which)); } From e5459d3feca22d44e784c25b81b2feed75379fce Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Tue, 1 Oct 2013 15:13:16 +0200 Subject: [PATCH 242/293] 8016024: Remove solaris path from FillCacheFind Reviewed-by: erikj --- jdk/makefiles/Tools.gmk | 1 - 1 file changed, 1 deletion(-) diff --git a/jdk/makefiles/Tools.gmk b/jdk/makefiles/Tools.gmk index 3b4e72c16d9..9a7b2997b86 100644 --- a/jdk/makefiles/Tools.gmk +++ b/jdk/makefiles/Tools.gmk @@ -25,7 +25,6 @@ # Cache all finds needed for this file. Only used on windows. $(eval $(call FillCacheFind,$(JDK_TOPDIR)/make/tools \ - $(JDK_TOPDIR)/src/solaris/classes \ $(JDK_TOPDIR)/makefiles/sun)) TOOLS_SRC:=$(JDK_TOPDIR)/make/tools/src \ From ce8f16808b262ac6543058b715c2d2306470f487 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Tue, 1 Oct 2013 15:21:14 +0200 Subject: [PATCH 243/293] 8025313: MetaspaceMemoryPool incorrectly reports undefined size for max Reviewed-by: stefank, tschatzl --- .../src/share/vm/memory/collectorPolicy.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 0728997b769..283db680bb0 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -64,19 +64,21 @@ void CollectorPolicy::initialize_flags() { vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); } - if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) { - FLAG_SET_ERGO(uintx, MaxMetaspaceSize, - restricted_align_down(MaxMetaspaceSize, max_alignment())); - } + // Do not use FLAG_SET_ERGO to update MaxMetaspaceSize, since this will + // override if MaxMetaspaceSize was set on the command line or not. + // This information is needed later to conform to the specification of the + // java.lang.management.MemoryUsage API. + // + // Ideally, we would be able to set the default value of MaxMetaspaceSize in + // globals.hpp to the aligned value, but this is not possible, since the + // alignment depends on other flags being parsed. + MaxMetaspaceSize = restricted_align_down(MaxMetaspaceSize, max_alignment()); if (MetaspaceSize > MaxMetaspaceSize) { - FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize); + MetaspaceSize = MaxMetaspaceSize; } - if (!is_size_aligned(MetaspaceSize, min_alignment())) { - FLAG_SET_ERGO(uintx, MetaspaceSize, - restricted_align_down(MetaspaceSize, min_alignment())); - } + MetaspaceSize = restricted_align_down(MetaspaceSize, min_alignment()); assert(MetaspaceSize <= MaxMetaspaceSize, "Must be"); From 4ff41501d152a237e0719c53ac70bf4796f31ba5 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Tue, 1 Oct 2013 15:36:53 -0700 Subject: [PATCH 244/293] 8007386: On physical machine (video card is Intel Q45) the text is blank Reviewed-by: prr, jchen --- .../sun/awt/X11GraphicsEnvironment.java | 9 ++++- .../native/sun/java2d/x11/XRBackendNative.c | 39 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java index 4e1c816fd18..47449f25c91 100644 --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java @@ -96,6 +96,7 @@ public class X11GraphicsEnvironment // Now check for XRender system property boolean xRenderRequested = true; + boolean xRenderIgnoreLinuxVersion = false; String xProp = System.getProperty("sun.java2d.xrender"); if (xProp != null) { if (xProp.equals("false") || xProp.equals("f")) { @@ -104,6 +105,10 @@ public class X11GraphicsEnvironment xRenderRequested = true; xRenderVerbose = true; } + + if(xProp.equalsIgnoreCase("t") || xProp.equalsIgnoreCase("true")) { + xRenderIgnoreLinuxVersion = true; + } } // initialize the X11 display connection @@ -121,7 +126,7 @@ public class X11GraphicsEnvironment // only attempt to initialize Xrender if it was requested if (xRenderRequested) { - xRenderAvailable = initXRender(xRenderVerbose); + xRenderAvailable = initXRender(xRenderVerbose, xRenderIgnoreLinuxVersion); if (xRenderVerbose && !xRenderAvailable) { System.out.println( "Could not enable XRender pipeline"); @@ -159,7 +164,7 @@ public class X11GraphicsEnvironment private static boolean xRenderVerbose; private static boolean xRenderAvailable; - private static native boolean initXRender(boolean verbose); + private static native boolean initXRender(boolean verbose, boolean ignoreLinuxVersion); public static boolean isXRenderAvailable() { return xRenderAvailable; } diff --git a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c index cbcf0c357e3..c015abb8b07 100644 --- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c +++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c @@ -31,6 +31,10 @@ #include +#ifdef __linux__ + #include +#endif + /* On Solaris 10 updates 8, 9, the render.h file defines these * protocol values but does not define the structs in Xrender.h. * Thus in order to get these always defined on Solaris 10 @@ -131,7 +135,7 @@ static #define MAX_PAYLOAD (262140u - 36u) #define MAXUINT (0xffffffffu) -static jboolean IsXRenderAvailable(jboolean verbose) { +static jboolean IsXRenderAvailable(jboolean verbose, jboolean ignoreLinuxVersion) { void *xrenderlib; @@ -253,6 +257,31 @@ static jboolean IsXRenderAvailable(jboolean verbose) { } #endif +#ifdef __linux__ + /* + * Check for Linux >= 3.5 (Ubuntu 12.04.02 LTS) to avoid hitting + * https://bugs.freedesktop.org/show_bug.cgi?id=48045 + */ + struct utsname utsbuf; + if(uname(&utsbuf) >= 0) { + int major, minor, revision; + if(sscanf(utsbuf.release, "%i.%i.%i", &major, &minor, &revision) == 3) { + if(major < 3 || (major == 3 && minor < 5)) { + if(!ignoreLinuxVersion) { + available = JNI_FALSE; + } + else if(verbose) { + printf("WARNING: Linux < 3.5 detected.\n" + "The pipeline will be enabled, but graphical " + "artifacts can occur with old graphic drivers.\n" + "See the release notes for more details.\n"); + fflush(stdout); + } + } + } + } +#endif // __linux__ + return available; } /* @@ -262,7 +291,7 @@ static jboolean IsXRenderAvailable(jboolean verbose) { */ JNIEXPORT jboolean JNICALL Java_sun_awt_X11GraphicsEnvironment_initXRender -(JNIEnv *env, jclass x11ge, jboolean verbose) +(JNIEnv *env, jclass x11ge, jboolean verbose, jboolean ignoreLinuxVersion) { #ifndef HEADLESS static jboolean xrenderAvailable = JNI_FALSE; @@ -277,7 +306,7 @@ Java_sun_awt_X11GraphicsEnvironment_initXRender } #endif AWT_LOCK(); - xrenderAvailable = IsXRenderAvailable(verbose); + xrenderAvailable = IsXRenderAvailable(verbose, ignoreLinuxVersion); AWT_UNLOCK(); firstTime = JNI_FALSE; } @@ -294,9 +323,11 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) { XImage* defaultImg; jfieldID maskImgID; jlong fmt8; + jlong fmt24; jlong fmt32; jfieldID a8ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_A8", "J"); + jfieldID rgb24ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB24", "J"); jfieldID argb32ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB32", "J"); if (awt_display == (Display *)NULL) { @@ -304,9 +335,11 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) { } fmt8 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardA8)); + fmt24 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardRGB24)); fmt32 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardARGB32)); (*env)->SetStaticLongField(env, cls, a8ID, fmt8); + (*env)->SetStaticLongField(env, cls, rgb24ID, fmt24); (*env)->SetStaticLongField(env, cls, argb32ID, fmt32); maskData = (char *) malloc(32*32); From e5260cc5649783c1cee74d5f6bc73d1cdc1233b7 Mon Sep 17 00:00:00 2001 From: Vadim Pakhnushev Date: Wed, 2 Oct 2013 10:06:28 +0400 Subject: [PATCH 245/293] 8024343: Change different color with the "The XOR alternation color" combobox, the color of the image can not shown immediately Reviewed-by: ceisserer, prr, bae --- .../classes/sun/java2d/xr/XRSurfaceData.java | 14 +- .../sun/java2d/AcceleratedXORModeTest.java | 143 ++++++++++++++++++ 2 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 jdk/test/sun/java2d/AcceleratedXORModeTest.java diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java b/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java index fa0598774df..014a98be971 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java @@ -457,15 +457,15 @@ public abstract class XRSurfaceData extends XSurfaceData { if (sg2d != null && sg2d.compositeState == SunGraphics2D.COMP_XOR) { if (validatedXorComp != sg2d.getComposite()) { validatedXorComp = (XORComposite) sg2d.getComposite(); - int xorpixelmod = validatedXorComp.getXorPixel(); renderQueue.setGCMode(xgc, false); + } - // validate pixel - int pixel = sg2d.pixel; - if (validatedGCForegroundPixel != pixel) { - renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod); - validatedGCForegroundPixel = pixel; - } + // validate pixel + int pixel = sg2d.pixel; + if (validatedGCForegroundPixel != pixel) { + int xorpixelmod = validatedXorComp.getXorPixel(); + renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod); + validatedGCForegroundPixel = pixel; } if (updateGCClip) { diff --git a/jdk/test/sun/java2d/AcceleratedXORModeTest.java b/jdk/test/sun/java2d/AcceleratedXORModeTest.java new file mode 100644 index 00000000000..e255cc39d48 --- /dev/null +++ b/jdk/test/sun/java2d/AcceleratedXORModeTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* +* @test +* @bug 8024343 +* @summary Test verifies that accelerated pipelines +* correctly draws primitives in XOR mode. +* @run main/othervm -Dsun.java2d.xrender=True AcceleratedXORModeTest +*/ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class AcceleratedXORModeTest { + public static void main(String argv[]) { + String fileName = argv.length > 0 ? argv[0] : null; + new AcceleratedXORModeTest(fileName).test(); + } + + static final Color backColor = Color.red; + static final Color color1 = Color.green; + static final Color color2 = Color.yellow; + static final Color xorColor1 = Color.blue; + static final Color xorColor2 = Color.white; + + static final int width = 700, height = 300; + + VolatileImage vImg = null; + String fileName; + + public AcceleratedXORModeTest(String fileName) { + this.fileName = fileName; + } + + void draw(Graphics2D g) { + g.setColor(backColor); + g.fillRect(0, 0, width, height); + g.setXORMode(xorColor1); + drawPattern(g, 100); + g.setXORMode(xorColor2); + drawPattern(g, 400); + g.dispose(); + } + + void test(BufferedImage bi) { + comparePattern(bi, 150, xorColor1.getRGB()); + comparePattern(bi, 450, xorColor2.getRGB()); + } + + void comparePattern(BufferedImage bi, int startX, int xorColor) { + int[] expectedColors = { + backColor.getRGB() ^ color1.getRGB() ^ xorColor, + backColor.getRGB() ^ color1.getRGB() ^ xorColor ^ + color2.getRGB() ^ xorColor, + backColor.getRGB() ^ color2.getRGB() ^ xorColor + }; + for (int i = 0; i < 3; i++) { + int x = startX + 100 * i; + int rgb = bi.getRGB(x, 150); + if (rgb != expectedColors[i]) { + String msg = "Colors mismatch: x = " + x + + ", got " + new Color(rgb) + ", expected " + + new Color(expectedColors[i]); + System.err.println(msg); + write(bi); + throw new RuntimeException("FAILED: " + msg); + } + } + } + + void drawPattern(Graphics2D g, int x) { + g.setColor(color1); + g.fillRect(x, 0, 200, 300); + g.setColor(color2); + g.fillRect(x+100, 0, 200, 300); + } + + GraphicsConfiguration getDefaultGC() { + return GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + } + + void createVImg() { + if (vImg != null) { + vImg.flush(); + vImg = null; + } + vImg = getDefaultGC().createCompatibleVolatileImage(width, height); + } + + void write(BufferedImage bi) { + if (fileName != null) { + try { + ImageIO.write(bi, "png", new File(fileName)); + } catch (IOException e) { + System.err.println("Can't write image file " + fileName); + } + } + } + + void test() { + createVImg(); + do { + int valCode = vImg.validate(getDefaultGC()); + if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) { + createVImg(); + } + Graphics2D g = vImg.createGraphics(); + draw(g); + BufferedImage bi = vImg.getSnapshot(); + test(bi); + write(bi); + } while (vImg.contentsLost()); + } +} From 920484209321b9eb0b8e16ae2dcb01936d67daca Mon Sep 17 00:00:00 2001 From: Mikael Gerdin Date: Wed, 2 Oct 2013 14:33:32 +0200 Subject: [PATCH 246/293] 8012525: gc/metaspace/G1AddMetaspaceDependency.java Test fails a safepoint timeout assertion or hangs Reviewed-by: brutisso, tschatzl --- hotspot/test/gc/metaspace/G1AddMetaspaceDependency.java | 1 - 1 file changed, 1 deletion(-) diff --git a/hotspot/test/gc/metaspace/G1AddMetaspaceDependency.java b/hotspot/test/gc/metaspace/G1AddMetaspaceDependency.java index 39716b977ae..b8e8b1ad598 100644 --- a/hotspot/test/gc/metaspace/G1AddMetaspaceDependency.java +++ b/hotspot/test/gc/metaspace/G1AddMetaspaceDependency.java @@ -107,7 +107,6 @@ public class G1AddMetaspaceDependency { Loader f_loader = new Loader(b_name, b_bytes, a_name, a_loader); Loader g_loader = new Loader(b_name, b_bytes, a_name, a_loader); - byte[] b = new byte[20 * 2 << 20]; Class c; c = b_loader.loadClass(b_name); c = c_loader.loadClass(b_name); From 02e57a015233bc13027271446b74a85a88a2d003 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 2 Oct 2013 06:17:10 -0700 Subject: [PATCH 247/293] 8025233: Move sun.invoke.Stable into java.lang.invoke package Reviewed-by: twisti, iveresov --- hotspot/src/share/vm/classfile/classFileParser.cpp | 2 +- hotspot/src/share/vm/classfile/vmSymbols.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 70662d3e8b8..49cdb94c833 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -1787,7 +1787,7 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d if (_location != _in_method) break; // only allow for methods if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Hidden; - case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_invoke_Stable_signature): + case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_Stable_signature): if (_location != _in_field) break; // only allow for fields if (!privileged) break; // only allow in privileged code return _field_Stable; diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 941fde568bb..fe966e89eeb 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -270,7 +270,7 @@ template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \ template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \ template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \ - template(sun_invoke_Stable_signature, "Lsun/invoke/Stable;") \ + template(java_lang_invoke_Stable_signature, "Ljava/lang/invoke/Stable;") \ template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \ template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \ template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \ From d7d6a076178e6a8108377926d61d20aae9694e65 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 2 Oct 2013 11:16:07 -0700 Subject: [PATCH 248/293] 8025837: Extraneous changes in the fix for 8007386 Reviewed-by: jgodinez, jchen --- jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c index c015abb8b07..1705c28f4fb 100644 --- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c +++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c @@ -323,11 +323,9 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) { XImage* defaultImg; jfieldID maskImgID; jlong fmt8; - jlong fmt24; jlong fmt32; jfieldID a8ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_A8", "J"); - jfieldID rgb24ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB24", "J"); jfieldID argb32ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB32", "J"); if (awt_display == (Display *)NULL) { @@ -335,11 +333,9 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) { } fmt8 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardA8)); - fmt24 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardRGB24)); fmt32 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardARGB32)); (*env)->SetStaticLongField(env, cls, a8ID, fmt8); - (*env)->SetStaticLongField(env, cls, rgb24ID, fmt24); (*env)->SetStaticLongField(env, cls, argb32ID, fmt32); maskData = (char *) malloc(32*32); From e43112a8ad8a4e3706b20929dfedcac81d4d0e86 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 2 Oct 2013 11:22:07 -0700 Subject: [PATCH 249/293] 7179526: xrender : closed/sun/java2d/volatileImage/LineClipTest.java failed since jdk8b36 Reviewed-by: prr, jchen --- .../sun/java2d/xr/GrowableRectArray.java | 14 + .../classes/sun/java2d/xr/MaskTile.java | 92 ---- .../sun/java2d/xr/MaskTileManager.java | 39 +- .../classes/sun/java2d/xr/XRDrawLine.java | 425 +++++++++++++++ .../classes/sun/java2d/xr/XRRenderer.java | 56 +- jdk/test/java/awt/Graphics/LineClipTest.java | 504 ++++++++++++++++++ 6 files changed, 988 insertions(+), 142 deletions(-) create mode 100644 jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java create mode 100644 jdk/test/java/awt/Graphics/LineClipTest.java diff --git a/jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java b/jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java index ee5bd62bd84..7defecfdadf 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java @@ -38,6 +38,20 @@ public class GrowableRectArray extends GrowableIntArray { super(RECT_SIZE, initialSize); } + public final void pushRectValues(int x, int y, int width, int height) { + int currSize = size; + size += RECT_SIZE; + + if (size >= array.length) { + growArray(); + } + + array[currSize] = x; + array[currSize + 1] = y; + array[currSize + 2] = width; + array[currSize + 3] = height; + } + public final void setX(int index, int x) { array[getCellIndex(index)] = x; } diff --git a/jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java b/jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java index 25d110fe7d2..c3315fac3b3 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java @@ -41,98 +41,6 @@ public class MaskTile { dirtyArea = new DirtyRegion(); } - public void addRect(int x, int y, int width, int height) { - int index = rects.getNextIndex(); - rects.setX(index, x); - rects.setY(index, y); - rects.setWidth(index, width); - rects.setHeight(index, height); - } - - public void addLine(int x1, int y1, int x2, int y2) { - /* - * EXA is not able to accalerate diagonal lines, we try to "guide" it a - * bit to avoid excessive migration See project documentation for an - * detailed explanation - */ - DirtyRegion region = new DirtyRegion(); - region.setDirtyLineRegion(x1, y1, x2, y2); - int xDiff = region.x2 - region.x; - int yDiff = region.y2 - region.y; - - if (xDiff == 0 || yDiff == 0) { - addRect(region.x, region.y, - region.x2 - region.x + 1, region.y2 - region.y + 1); - } else if (xDiff == 1 && yDiff == 1) { - addRect(x1, y1, 1, 1); - addRect(x2, y2, 1, 1); - } else { - lineToRects(x1, y1, x2, y2); - } - } - - private void lineToRects(int xstart, int ystart, int xend, int yend) { - int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; - - /* Entfernung in beiden Dimensionen berechnen */ - dx = xend - xstart; - dy = yend - ystart; - - /* Vorzeichen des Inkrements bestimmen */ - incx = dx > 0 ? 1 : (dx < 0) ? -1 : 0; - incy = dy > 0 ? 1 : (dy < 0) ? -1 : 0; - if (dx < 0) - dx = -dx; - if (dy < 0) - dy = -dy; - - /* feststellen, welche Entfernung groesser ist */ - if (dx > dy) { - /* x ist schnelle Richtung */ - pdx = incx; - pdy = 0; /* pd. ist Parallelschritt */ - ddx = incx; - ddy = incy; /* dd. ist Diagonalschritt */ - es = dy; - el = dx; /* Fehlerschritte schnell, langsam */ - } else { - /* y ist schnelle Richtung */ - pdx = 0; - pdy = incy; /* pd. ist Parallelschritt */ - ddx = incx; - ddy = incy; /* dd. ist Diagonalschritt */ - es = dx; - el = dy; /* Fehlerschritte schnell, langsam */ - } - - /* Initialisierungen vor Schleifenbeginn */ - x = xstart; - y = ystart; - err = el / 2; - addRect(x, y, 1, 1); - - /* Pixel berechnen */ - for (t = 0; t < el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */ - { - /* Aktualisierung Fehlerterm */ - err -= es; - if (err < 0) { - /* Fehlerterm wieder positiv (>=0) machen */ - err += el; - /* Schritt in langsame Richtung, Diagonalschritt */ - x += ddx; - y += ddy; - } else { - /* Schritt in schnelle Richtung, Parallelschritt */ - x += pdx; - y += pdy; - } - addRect(x, y, 1, 1); - // SetPixel(x,y); - // System.out.println(x+":"+y); - } - } - public void calculateDirtyAreas() { for (int i=0; i < rects.getSize(); i++) { diff --git a/jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java b/jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java index b7baf36ceba..9b2be2744fb 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java @@ -54,10 +54,6 @@ public class MaskTileManager { int maskPixmap; int maskPicture; long maskGC; - int lineMaskPixmap; - int lineMaskPicture; - long drawLineGC; - long clearLineGC; public MaskTileManager(XRCompositeManager xrMgr, int parentXid) { tileList = new ArrayList(); @@ -71,34 +67,6 @@ public class MaskTileManager { 0, 0, MASK_SIZE, MASK_SIZE); maskGC = con.createGC(maskPixmap); con.setGCExposures(maskGC, false); - - lineMaskPixmap = con.createPixmap(parentXid, 8, MASK_SIZE, MASK_SIZE); - lineMaskPicture = - con.createPicture(lineMaskPixmap, XRUtils.PictStandardA8); - con.renderRectangle(lineMaskPicture, XRUtils.PictOpClear, - new XRColor(Color.black), 0, 0, MASK_SIZE, MASK_SIZE); - - drawLineGC = con.createGC(lineMaskPixmap); - con.setGCExposures(drawLineGC, false); - con.setGCForeground(drawLineGC, 255); - - clearLineGC = con.createGC(lineMaskPixmap); - con.setGCExposures(clearLineGC, false); - con.setGCForeground(clearLineGC, 0); - } - - /** - * Adds a rectangle to the mask. - */ - public void addRect(int x, int y, int width, int height) { - mainTile.addRect(x, y, width, height); - } - - /** - * Adds a line to the mask. - */ - public void addLine(int x1, int y1, int x2, int y2) { - mainTile.addLine(x1, y1, x2, y2); } /** @@ -324,4 +292,11 @@ public class MaskTileManager { rects.setY(index, 0); } } + + /** + * @return MainTile to which rectangles are added before composition. + */ + public MaskTile getMainTile() { + return mainTile; + } } diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java b/jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java new file mode 100644 index 00000000000..66b595e9455 --- /dev/null +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + + + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Bresenham line-drawing implementation decomposing line segments + * into a series of rectangles. + * This is required, because xrender doesn't support line primitives directly. + * The code here is an almost 1:1 port of the existing C-source contained in + * sun/java2d/loop/DrawLine.c and sun/java2d/loop/LoopMacros.h + */ +package sun.java2d.xr; + +public class XRDrawLine { + static final int BIG_MAX = ((1 << 29) - 1); + static final int BIG_MIN = (-(1 << 29)); + + static final int OUTCODE_TOP = 1; + static final int OUTCODE_BOTTOM = 2; + static final int OUTCODE_LEFT = 4; + static final int OUTCODE_RIGHT = 8; + + int x1, y1, x2, y2; + int ucX1, ucY1, ucX2, ucY2; + + DirtyRegion region = new DirtyRegion(); + + protected void rasterizeLine(GrowableRectArray rectBuffer, int _x1, + int _y1, int _x2, int _y2, int cxmin, int cymin, int cxmax, + int cymax, boolean clip, boolean overflowCheck) { + float diagF; + int error; + int steps; + int errminor, errmajor; + boolean xmajor; + int dx, dy, ax, ay; + + initCoordinates(_x1, _y1, _x2, _y2, overflowCheck); + + dx = x2 - x1; + dy = y2 - y1; + ax = Math.abs(dx); + ay = Math.abs(dy); + xmajor = (ax >= ay); + diagF = ((float) ax) / ay; + + if (clip + && !clipCoordinates(cxmin, cymin, cxmax, cymax, xmajor, dx, dy, + ax, ay)) { + // whole line was clipped away + return; + } + + region.setDirtyLineRegion(x1, y1, x2, y2); + int xDiff = region.x2 - region.x; + int yDiff = region.y2 - region.y; + + if (xDiff == 0 || yDiff == 0) { + // horizontal / diagonal lines can be represented by a single + // rectangle + rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x + + 1, region.y2 - region.y + 1); + return; + } + + // Setup bresenham + if (xmajor) { + errmajor = ay * 2; + errminor = ax * 2; + ax = -ax; /* For clipping adjustment below */ + steps = x2 - x1; + } else { + errmajor = ax * 2; + errminor = ay * 2; + ay = -ay; /* For clipping adjustment below */ + steps = y2 - y1; + } + + if ((steps = (Math.abs(steps) + 1)) == 0) { + return; + } + + error = -(errminor / 2); + + if (y1 != ucY1) { + int ysteps = y1 - ucY1; + if (ysteps < 0) { + ysteps = -ysteps; + } + error += ysteps * ax * 2; + } + + if (x1 != ucX1) { + int xsteps = x1 - ucX1; + if (xsteps < 0) { + xsteps = -xsteps; + } + error += xsteps * ay * 2; + } + error += errmajor; + errminor -= errmajor; + + int xStep = (dx > 0 ? 1 : -1); + int yStep = (dy > 0 ? 1 : -1); + int orthogonalXStep = xmajor ? xStep : 0; + int orthogonalYStep = !xmajor ? yStep : 0; + + /* + * For lines which proceed in one direction faster, we try to generate + * rectangles instead of points. Otherwise we try to avoid the extra + * work... + */ + if (diagF <= 0.9 || diagF >= 1.1) { + lineToRects(rectBuffer, steps, error, errmajor, errminor, xStep, + yStep, orthogonalXStep, orthogonalYStep); + } else { + lineToPoints(rectBuffer, steps, error, errmajor, errminor, xStep, + yStep, orthogonalXStep, orthogonalYStep); + } + } + + private void lineToPoints(GrowableRectArray rectBuffer, int steps, + int error, int errmajor, int errminor, int xStep, int yStep, + int orthogonalXStep, int orthogonalYStep) { + int x = x1, y = y1; + + do { + rectBuffer.pushRectValues(x, y, 1, 1); + + // "Traditional" Bresenham line drawing + if (error < 0) { + error += errmajor; + x += orthogonalXStep; + y += orthogonalYStep; + } else { + error -= errminor; + x += xStep; + y += yStep; + } + } while (--steps > 0); + } + + private void lineToRects(GrowableRectArray rectBuffer, int steps, + int error, int errmajor, int errminor, int xStep, int yStep, + int orthogonalXStep, int orthogonalYStep) { + int x = x1, y = y1; + int rectX = Integer.MIN_VALUE, rectY = 0; + int rectW = 0, rectH = 0; + + do { + // Combine the resulting rectangles + // for steps performed in a single direction. + if (y == rectY) { + if (x == (rectX + rectW)) { + rectW++; + } else if (x == (rectX - 1)) { + rectX--; + rectW++; + } + } else if (x == rectX) { + if (y == (rectY + rectH)) { + rectH++; + } else if (y == (rectY - 1)) { + rectY--; + rectH++; + } + } else { + // Diagonal step: add the previous rectangle to the list, + // iff it was "real" (= not initialized before the first + // iteration) + if (rectX != Integer.MIN_VALUE) { + rectBuffer.pushRectValues(rectX, rectY, rectW, rectH); + } + rectX = x; + rectY = y; + rectW = rectH = 1; + } + + // "Traditional" Bresenham line drawing + if (error < 0) { + error += errmajor; + x += orthogonalXStep; + y += orthogonalYStep; + } else { + error -= errminor; + x += xStep; + y += yStep; + } + } while (--steps > 0); + + // Add last rectangle which isn't handled by the combination-code + // anymore + rectBuffer.pushRectValues(rectX, rectY, rectW, rectH); + } + + private boolean clipCoordinates(int cxmin, int cymin, int cxmax, int cymax, + boolean xmajor, int dx, int dy, int ax, int ay) { + int outcode1, outcode2; + + outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); + outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); + + while ((outcode1 | outcode2) != 0) { + int xsteps = 0, ysteps = 0; + + if ((outcode1 & outcode2) != 0) { + return false; + } + + if (outcode1 != 0) { + if ((outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM)) != 0) { + if ((outcode1 & OUTCODE_TOP) != 0) { + y1 = cymin; + } else { + y1 = cymax; + } + ysteps = y1 - ucY1; + if (ysteps < 0) { + ysteps = -ysteps; + } + xsteps = 2 * ysteps * ax + ay; + if (xmajor) { + xsteps += ay - ax - 1; + } + xsteps = xsteps / (2 * ay); + if (dx < 0) { + xsteps = -xsteps; + } + x1 = ucX1 + (int) xsteps; + } else if ((outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT)) != 0) { + if ((outcode1 & OUTCODE_LEFT) != 0) { + x1 = cxmin; + } else { + x1 = cxmax; + } + xsteps = x1 - ucX1; + if (xsteps < 0) { + xsteps = -xsteps; + } + ysteps = 2 * xsteps * ay + ax; + if (!xmajor) { + ysteps += ax - ay - 1; + } + ysteps = ysteps / (2 * ax); + if (dy < 0) { + ysteps = -ysteps; + } + y1 = ucY1 + (int) ysteps; + } + outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); + } else { + if ((outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM)) != 0) { + if ((outcode2 & OUTCODE_TOP) != 0) { + y2 = cymin; + } else { + y2 = cymax; + } + ysteps = y2 - ucY2; + if (ysteps < 0) { + ysteps = -ysteps; + } + xsteps = 2 * ysteps * ax + ay; + if (xmajor) { + xsteps += ay - ax; + } else { + xsteps -= 1; + } + xsteps = xsteps / (2 * ay); + if (dx > 0) { + xsteps = -xsteps; + } + x2 = ucX2 + (int) xsteps; + } else if ((outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT)) != 0) { + if ((outcode2 & OUTCODE_LEFT) != 0) { + x2 = cxmin; + } else { + x2 = cxmax; + } + xsteps = x2 - ucX2; + if (xsteps < 0) { + xsteps = -xsteps; + } + ysteps = 2 * xsteps * ay + ax; + if (xmajor) { + ysteps -= 1; + } else { + ysteps += ax - ay; + } + ysteps = ysteps / (2 * ax); + if (dy > 0) { + ysteps = -ysteps; + } + y2 = ucY2 + (int) ysteps; + } + outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); + } + } + + return true; + } + + private void initCoordinates(int x1, int y1, int x2, int y2, + boolean checkOverflow) { + /* + * Part of calculating the Bresenham parameters for line stepping + * involves being able to store numbers that are twice the magnitude of + * the biggest absolute difference in coordinates. Since we want the + * stepping parameters to be stored in jints, we then need to avoid any + * absolute differences more than 30 bits. Thus, we need to preprocess + * the coordinates to reduce their range to 30 bits regardless of + * clipping. We need to cut their range back before we do the clipping + * because the Bresenham stepping values need to be calculated based on + * the "unclipped" coordinates. + * + * Thus, first we perform a "pre-clipping" stage to bring the + * coordinates within the 30-bit range and then we proceed to the + * regular clipping procedure, pretending that these were the original + * coordinates all along. Since this operation occurs based on a + * constant "pre-clip" rectangle of +/- 30 bits without any + * consideration for the final clip, the rounding errors that occur here + * will depend only on the line coordinates and be invariant with + * respect to the particular device/user clip rectangles in effect at + * the time. Thus, rendering a given large-range line will be consistent + * under a variety of clipping conditions. + */ + if (checkOverflow + && (OverflowsBig(x1) || OverflowsBig(y1) || OverflowsBig(x2) || OverflowsBig(y2))) { + /* + * Use doubles to get us into range for "Big" arithmetic. + * + * The math of adjusting an endpoint for clipping can involve an + * intermediate result with twice the number of bits as the original + * coordinate range. Since we want to maintain as much as 30 bits of + * precision in the resulting coordinates, we will get roundoff here + * even using IEEE double-precision arithmetic which cannot carry 60 + * bits of mantissa. Since the rounding errors will be consistent + * for a given set of input coordinates the potential roundoff error + * should not affect the consistency of our rendering. + */ + double x1d = x1; + double y1d = y1; + double x2d = x2; + double y2d = y2; + double dxd = x2d - x1d; + double dyd = y2d - y1d; + + if (x1 < BIG_MIN) { + y1d = y1 + (BIG_MIN - x1) * dyd / dxd; + x1d = BIG_MIN; + } else if (x1 > BIG_MAX) { + y1d = y1 - (x1 - BIG_MAX) * dyd / dxd; + x1d = BIG_MAX; + } + /* Use Y1d instead of _y1 for testing now as we may have modified it */ + if (y1d < BIG_MIN) { + x1d = x1 + (BIG_MIN - y1) * dxd / dyd; + y1d = BIG_MIN; + } else if (y1d > BIG_MAX) { + x1d = x1 - (y1 - BIG_MAX) * dxd / dyd; + y1d = BIG_MAX; + } + if (x2 < BIG_MIN) { + y2d = y2 + (BIG_MIN - x2) * dyd / dxd; + x2d = BIG_MIN; + } else if (x2 > BIG_MAX) { + y2d = y2 - (x2 - BIG_MAX) * dyd / dxd; + x2d = BIG_MAX; + } + /* Use Y2d instead of _y2 for testing now as we may have modified it */ + if (y2d < BIG_MIN) { + x2d = x2 + (BIG_MIN - y2) * dxd / dyd; + y2d = BIG_MIN; + } else if (y2d > BIG_MAX) { + x2d = x2 - (y2 - BIG_MAX) * dxd / dyd; + y2d = BIG_MAX; + } + + x1 = (int) x1d; + y1 = (int) y1d; + x2 = (int) x2d; + y2 = (int) y2d; + } + + this.x1 = ucX1 = x1; + this.y1 = ucY1 = y1; + this.x2 = ucX2 = x2; + this.y2 = ucY2 = y2; + } + + private boolean OverflowsBig(int v) { + return ((v) != (((v) << 2) >> 2)); + } + + private int out(int v, int vmin, int vmax, int cmin, int cmax) { + return ((v < vmin) ? cmin : ((v > vmax) ? cmax : 0)); + } + + private int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) { + return out(y, ymin, ymax, OUTCODE_TOP, OUTCODE_BOTTOM) + | out(x, xmin, xmax, OUTCODE_LEFT, OUTCODE_RIGHT); + } +} diff --git a/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java b/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java index 933f5452378..bad9e837f28 100644 --- a/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java @@ -53,10 +53,15 @@ import static sun.java2d.xr.XRUtils.clampToUShort; public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { XRDrawHandler drawHandler; MaskTileManager tileManager; + XRDrawLine lineGen; + GrowableRectArray rectBuffer; public XRRenderer(MaskTileManager tileManager) { this.tileManager = tileManager; + this.rectBuffer = tileManager.getMainTile().getRects(); + this.drawHandler = new XRDrawHandler(); + this.lineGen = new XRDrawLine(); } /** @@ -77,19 +82,15 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { int transX2 = Region.clipAdd(x2, sg2d.transX); int transY2 = Region.clipAdd(y2, sg2d.transY); - // Non clipped fast path - if (compClip.contains(transX1, transY1) - && compClip.contains(transX2, transY2)) { - SunToolkit.awtLock(); - try { - validateSurface(sg2d); - tileManager.addLine(transX1, transY1, transX2, transY2); - tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); - } finally { - SunToolkit.awtUnlock(); - } - } else { - draw(sg2d, new Line2D.Float(x1, y1, x2, y2)); + SunToolkit.awtLock(); + try { + validateSurface(sg2d); + lineGen.rasterizeLine(rectBuffer, transX1, transY1, + transX2, transY2, compClip.getLoX(), compClip.getLoY(), + compClip.getHiX(), compClip.getHiY(), true, true); + tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); + } finally { + SunToolkit.awtUnlock(); } } @@ -148,7 +149,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { SunToolkit.awtLock(); try { validateSurface(sg2d); - tileManager.addRect(x, y, width, height); + rectBuffer.pushRectValues(x, y, width, height); tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); } finally { SunToolkit.awtUnlock(); @@ -199,11 +200,13 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { } private class XRDrawHandler extends ProcessPath.DrawHandler { + DirtyRegion region; XRDrawHandler() { // these are bogus values; the caller will use validate() // to ensure that they are set properly prior to each usage super(0, 0, 0, 0); + this.region = new DirtyRegion(); } /** @@ -218,15 +221,32 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { } public void drawLine(int x1, int y1, int x2, int y2) { - tileManager.addLine(x1, y1, x2, y2); + region.setDirtyLineRegion(x1, y1, x2, y2); + int xDiff = region.x2 - region.x; + int yDiff = region.y2 - region.y; + + if (xDiff == 0 || yDiff == 0) { + // horizontal / diagonal lines can be represented by a single + // rectangle + rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x + + 1, region.y2 - region.y + 1); + } else if (xDiff == 1 && yDiff == 1) { + // fast path for pattern commonly generated by + // ProcessPath.DrawHandler + rectBuffer.pushRectValues(x1, y1, 1, 1); + rectBuffer.pushRectValues(x2, y2, 1, 1); + } else { + lineGen.rasterizeLine(rectBuffer, x1, y1, x2, y2, 0, 0, + 0, 0, false, false); + } } public void drawPixel(int x, int y) { - tileManager.addRect(x, y, 1, 1); + rectBuffer.pushRectValues(x, y, 1, 1); } public void drawScanline(int x1, int x2, int y) { - tileManager.addRect(x1, y, x2 - x1 + 1, 1); + rectBuffer.pushRectValues(x1, y, x2 - x1 + 1, 1); } } @@ -263,7 +283,7 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { validateSurface(sg2d); int[] spanBox = new int[4]; while (si.nextSpan(spanBox)) { - tileManager.addRect(spanBox[0] + transx, + rectBuffer.pushRectValues(spanBox[0] + transx, spanBox[1] + transy, spanBox[2] - spanBox[0], spanBox[3] - spanBox[1]); diff --git a/jdk/test/java/awt/Graphics/LineClipTest.java b/jdk/test/java/awt/Graphics/LineClipTest.java new file mode 100644 index 00000000000..43410f9dad8 --- /dev/null +++ b/jdk/test/java/awt/Graphics/LineClipTest.java @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 4780022 4862193 7179526 + * @summary Tests that clipped lines are drawn over the same pixels + * as unclipped lines (within the clip bounds) + * @run main/timeout=600/othervm -Dsun.java2d.ddforcevram=true LineClipTest + * @run main/timeout=600/othervm LineClipTest + */ + + +/** + * This app tests whether we are drawing clipped lines the same + * as unclipped lines. The problem occurred when we started + * clipping d3d lines using simple integer clipping, which did not + * account for sub-pixel precision and ended up drawing very different + * pixels than the same line drawn unclipped. A supposed fix + * to that problem used floating-point clipping instead, but there + * was some problem with very limited precision inside of d3d + * (presumably in hardware) that caused some variation in pixels. + * We decided that whatever the fix was, we needed a serious + * line check test to make sure that all kinds of different + * lines would be drawn exactly the same inside the clip area, + * regardless of whether clipping was enabled. This test should + * check all kinds of different cases, such as lines that fall + * completely outside, completely inside, start outside and + * end inside, etc., and lines should end and originate in + * all quadrants of the space divided up by the clip box. + * + * The test works as follows: + * We create nine quadrants using the spaces bisected by the + * edges of the clip bounds (note that only one of these + * quadrants is actually visible when clipping is enabled). + * We create several points in each of these quadrants + * (three in each of the invisible quadrants, nine in the + * center/visible quadrant). Our resulting grid looks like + * this: + * + * x x|x x x|x x + * | | + * | | + * | | + * | | + * | | + * x | | x + * ----------------------------------- + * x |x x x| x + * | | + * | | + * x |x x x| x + * | | + * | | + * x |x x x| x + * ----------------------------------- + * x | | x + * | | + * | | + * | | + * | | + * | | + * x x|x x x|x x + * + * The test then draws lines from every point to every other + * point. First, we draw unclipped lines in blue and + * then we draw clipped lines in red. + * At certain times (after every point during the default + * test, after every quadrant of lines if you run with the -quick + * option), we check for errors and draw the current image + * to the screen. Error checking consists of copying the + * VolatileImage to a BufferedImage (because we need access + * to the pixels directly) and checking every pixel in the + * image. The check is simple: everything outside the + * clip bounds should be blue (or the background color) and + * everything inside the clip bounds should be red (or the + * background color). So any blue pixel inside or red + * pixel outside means that there was a drawing error and + * the test fails. + * There are 4 modes that the test can run in (dynamic mode is + * exclusive to the other modes, but the other modes are combinable): + * + * (default): the clip is set + * to a default size (100x100) and the test is run. + * + * -quick: The error + * check is run only after every quadrant of lines is + * drawn. This speeds up the test considerably with + * some less accuracy in error checking (because pixels + * from some lines may overdrawn pixels from other lines + * before we have verified the correctness of those + * pixels). + * + * -dynamic: There is no error checking, but this version + * of the test automatically resizes the clip bounds and + * reruns the test over and over. Nothing besides the + * visual check verifies that the test is running correctly. + * + * -rect: Instead of drawing lines, the test draws rectangles + * to/from all points in all quadrants. This tests similar + * clipping functionality for drawRect(). + * + * n (where "n" is a number): sets the clip size to the + * given value. Just like the default test except that + * the clip size is as specified. + * + * Note: this test must be run with the -Dsun.java2d.ddforcevram=true + * option to force the test image to stay in VRAM. We currently + * punt VRAM images to system memory when we detect lots of + * reads. Since we read the whole buffer on every error check + * to copy it to the BufferedImage), this causes us to punt the + * buffer. A system memory surface will have no d3d capabilities, + * thus we are not testing the d3d line quality when this happens. + * By using the ddforcevram flag, we make sure the buffer + * stays put in VRAM and d3d is used to draw the lines. + */ + +import javax.swing.*; +import java.awt.*; +import java.awt.image.*; + + +public class LineClipTest extends Component implements Runnable { + + int clipBumpVal = 5; + static int clipSize = 100; + int clipX1; + int clipY1; + static final int NUM_QUADS = 9; + Point quadrants[][] = new Point[NUM_QUADS][]; + static boolean dynamic = false; + BufferedImage imageChecker = null; + Color unclippedColor = Color.blue; + Color clippedColor = Color.red; + int testW = -1, testH = -1; + VolatileImage testImage = null; + static boolean keepRunning = false; + static boolean quickTest = false; + static boolean rectTest = false; + static boolean runTestDone = false; + static Frame f = null; + + /** + * Check for errors in the grid. This error check consists of + * copying the buffer into a BufferedImage and reading all pixels + * in that image. No pixel outside the clip bounds should be + * of the color clippedColor and no pixel inside should be + * of the color unclippedColor. Any wrong color returns an error. + */ + boolean gridError(Graphics g) { + boolean error = false; + if (imageChecker == null || (imageChecker.getWidth() != testW) || + (imageChecker.getHeight() != testH)) + { + // Recreate BufferedImage as necessary + GraphicsConfiguration gc = getGraphicsConfiguration(); + ColorModel cm = gc.getColorModel(); + WritableRaster wr = + cm.createCompatibleWritableRaster(getWidth(), getHeight()); + imageChecker = + new BufferedImage(cm, wr, + cm.isAlphaPremultiplied(), null); + } + // Copy buffer to BufferedImage + Graphics gChecker = imageChecker.getGraphics(); + gChecker.drawImage(testImage, 0, 0, this); + + // Set up pixel colors to check against + int clippedPixelColor = clippedColor.getRGB(); + int unclippedPixelColor = unclippedColor.getRGB(); + int wrongPixelColor = clippedPixelColor; + boolean insideClip = false; + for (int row = 0; row < getHeight(); ++row) { + for (int col = 0; col < getWidth(); ++col) { + if (row >= clipY1 && row < (clipY1 + clipSize) && + col >= clipX1 && col < (clipX1 + clipSize)) + { + // Inside clip bounds - should not see unclipped color + wrongPixelColor = unclippedPixelColor; + } else { + // Outside clip - should not see clipped color + wrongPixelColor = clippedPixelColor; + } + int pixel = imageChecker.getRGB(col, row); + if (pixel == wrongPixelColor) { + System.out.println("FAILED: pixel = " + + Integer.toHexString(pixel) + + " at (x, y) = " + col + ", " + row); + // Draw magenta rectangle around problem pixel in buffer + // for visual feedback to user + g.setColor(Color.magenta); + g.drawRect(col - 1, row - 1, 2, 2); + error = true; + } + } + } + return error; + } + + /** + * Draw all test lines and check for errors (unless running + * with -dynamic option) + */ + void drawLineGrid(Graphics screenGraphics, Graphics g) { + // Fill buffer with background color + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + + // Now, iterate through all quadrants + for (int srcQuad = 0; srcQuad < NUM_QUADS; ++srcQuad) { + // Draw lines to all other quadrants + for (int dstQuad = 0; dstQuad < NUM_QUADS; ++dstQuad) { + for (int srcPoint = 0; + srcPoint < quadrants[srcQuad].length; + ++srcPoint) + { + // For every point in the source quadrant + int sx = quadrants[srcQuad][srcPoint].x; + int sy = quadrants[srcQuad][srcPoint].y; + for (int dstPoint = 0; + dstPoint < quadrants[dstQuad].length; + ++dstPoint) + { + int dx = quadrants[dstQuad][dstPoint].x; + int dy = quadrants[dstQuad][dstPoint].y; + if (!rectTest) { + // Draw unclipped/clipped lines to every + // point in the dst quadrant + g.setColor(unclippedColor); + g.drawLine(sx, sy, dx, dy); + g.setClip(clipX1, clipY1, clipSize, clipSize); + g.setColor(clippedColor); + g.drawLine(sx,sy, dx, dy); + } else { + // Draw unclipped/clipped rectangles to every + // point in the dst quadrant + g.setColor(unclippedColor); + int w = dx - sx; + int h = dy - sy; + g.drawRect(sx, sy, w, h); + g.setClip(clipX1, clipY1, clipSize, clipSize); + g.setColor(clippedColor); + g.drawRect(sx, sy, w, h); + } + g.setClip(null); + } + if (!dynamic) { + // Draw screen update for visual feedback + screenGraphics.drawImage(testImage, 0, 0, this); + // On default test, check for errors after every + // src point + if (!quickTest && gridError(g)) { + throw new java.lang.RuntimeException("Failed"); + } + } + } + } + if (!dynamic && quickTest && gridError(g)) { + // On quick test, check for errors only after every + // src quadrant + throw new java.lang.RuntimeException("Failed"); + //return; + } + } + if (!dynamic) { + System.out.println("PASSED"); + if (!keepRunning) { + f.dispose(); + } + } + } + + /** + * If we have not yet run the test, or if the window size has + * changed, or if we are running the test in -dynamic mode, + * run the test. Then draw the test buffer to the screen + */ + public void paint(Graphics g) { + if (dynamic || testImage == null || + getWidth() != testW || getHeight() != testH) + { + runTest(g); + } + if (testImage != null) { + g.drawImage(testImage, 0, 0, this); + } + } + + /* + * Create the quadrant of points and run the test to draw all the lines + */ + public void runTest(Graphics screenGraphics) { + if (getWidth() == 0 || getHeight() == 0) { + // May get here before window is really ready + return; + } + clipX1 = (getWidth() - clipSize) / 2; + clipY1 = (getHeight() - clipSize) / 2; + int clipX2 = clipX1 + clipSize; + int clipY2 = clipY1 + clipSize; + int centerX = getWidth()/2; + int centerY = getHeight()/2; + int leftX = 0; + int topY = 0; + int rightX = getWidth() - 1; + int bottomY = getHeight() - 1; + int quadIndex = 0; + // Offsets are used to force diagonal (versus hor/vert) lines + int xOffset = 0; + int yOffset = 0; + + if (quadrants[0] == null) { + for (int i = 0; i < 9; ++i) { + int numPoints = (i == 4) ? 9 : 3; + quadrants[i] = new Point[numPoints]; + } + } + // Upper-left + quadrants[quadIndex] = new Point[] { + new Point(leftX + xOffset, clipY1 - 1 - yOffset), + new Point(leftX + xOffset, topY + yOffset), + new Point(clipX1 - 1 - xOffset, topY + yOffset), + }; + + quadIndex++; + yOffset++; + // Upper-middle + quadrants[quadIndex] = new Point[] { + new Point(clipX1 + 1 + xOffset, topY + yOffset), + new Point(centerX + xOffset, topY + yOffset), + new Point(clipX2 - 1 - xOffset, topY + yOffset), + }; + + quadIndex++; + ++yOffset; + // Upper-right + quadrants[quadIndex] = new Point[] { + new Point(clipX2 + 1 + xOffset, topY + yOffset), + new Point(rightX - xOffset, topY + yOffset), + new Point(rightX - xOffset, clipY1 - 1 - yOffset), + }; + + quadIndex++; + yOffset = 0; + ++xOffset; + // Middle-left + quadrants[quadIndex] = new Point[] { + new Point(leftX + xOffset, clipY1 + 1 + yOffset), + new Point(leftX + xOffset, centerY + yOffset), + new Point(leftX + xOffset, clipY2 - 1 - yOffset), + }; + + quadIndex++; + ++yOffset; + // Middle-middle + quadrants[quadIndex] = new Point[] { + new Point(clipX1 + 1 + xOffset, clipY1 + 1 + yOffset), + new Point(centerX + xOffset, clipY1 + 1 + yOffset), + new Point(clipX2 - 1 - xOffset, clipY1 + 1 + yOffset), + new Point(clipX1 + 1 + xOffset, centerY + yOffset), + new Point(centerX + xOffset, centerY + yOffset), + new Point(clipX2 - 1 - xOffset, centerY + yOffset), + new Point(clipX1 + 1 + xOffset, clipY2 - 1 - yOffset), + new Point(centerX + xOffset, clipY2 - 1 - yOffset), + new Point(clipX2 - 1 - xOffset, clipY2 - 1 - yOffset), + }; + + quadIndex++; + ++yOffset; + // Middle-right + quadrants[quadIndex] = new Point[] { + new Point(rightX - xOffset, clipY1 + 1 + yOffset), + new Point(rightX - xOffset, centerY + yOffset), + new Point(rightX - xOffset, clipY2 - 1 - yOffset), + }; + + quadIndex++; + yOffset = 0; + ++xOffset; + // Lower-left + quadrants[quadIndex] = new Point[] { + new Point(leftX + xOffset, clipY2 + 1 + yOffset), + new Point(leftX + xOffset, bottomY - yOffset), + new Point(clipX1 - 1 - xOffset, bottomY - yOffset), + }; + + quadIndex++; + ++yOffset; + // Lower-middle + quadrants[quadIndex] = new Point[] { + new Point(clipX1 + 1 + xOffset, bottomY - yOffset), + new Point(centerX + xOffset, bottomY - yOffset), + new Point(clipX2 - 1 - xOffset, bottomY - yOffset), + }; + + quadIndex++; + ++yOffset; + // Lower-right + quadrants[quadIndex] = new Point[] { + new Point(clipX2 + 1 + xOffset, bottomY - yOffset), + new Point(rightX - xOffset, bottomY - yOffset), + new Point(rightX - xOffset, clipY2 + 1 + yOffset), + }; + + + if (testImage != null) { + testImage.flush(); + } + testW = getWidth(); + testH = getHeight(); + testImage = createVolatileImage(testW, testH); + Graphics g = testImage.getGraphics(); + do { + int valCode = testImage.validate(getGraphicsConfiguration()); + if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) { + testImage.flush(); + testImage = createVolatileImage(testW, testH); + g = testImage.getGraphics(); + } + drawLineGrid(screenGraphics, g); + } while (testImage.contentsLost()); + if (dynamic) { + // Draw clip box if dynamic + g.setClip(null); + g.setColor(Color.black); + g.drawRect(clipX1, clipY1, clipSize, clipSize); + screenGraphics.drawImage(testImage, 0, 0, this); + } + runTestDone = true; + } + + /** + * When running -dynamic, resize the clip bounds and run the test + * over and over + */ + public void run() { + while (true) { + clipSize += clipBumpVal; + if (clipSize > getWidth() || clipSize < 0) { + clipBumpVal = -clipBumpVal; + clipSize += clipBumpVal; + } + update(getGraphics()); + try { + Thread.sleep(50); + } catch (Exception e) {} + } + } + + public static void main(String args[]) { + for (int i = 0; i < args.length; ++i) { + if (args[i].equals("-dynamic")) { + dynamic = true; + } else if (args[i].equals("-rect")) { + rectTest = true; + } else if (args[i].equals("-quick")) { + quickTest = true; + } else if (args[i].equals("-keep")) { + keepRunning = true; + } else { + // could be clipSize + try { + clipSize = Integer.parseInt(args[i]); + } catch (Exception e) {} + } + } + f = new Frame(); + f.setSize(500, 500); + LineClipTest test = new LineClipTest(); + f.add(test); + if (dynamic) { + Thread t = new Thread(test); + t.start(); + } + f.setVisible(true); + while (!runTestDone) { + // need to make sure jtreg doesn't exit before the + // test is done... + try { + Thread.sleep(50); + } catch (Exception e) {} + } + } +} From dd6a63a0874447c8cb2dc4b85da00299fe3785aa Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:25 -0700 Subject: [PATCH 250/293] Added tag jdk8-b110 for changeset 6766207925ff --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 8ee790af31a..959ca071886 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -231,3 +231,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 9286a6e61291246d88af713f1ef79adeea30fe2e jdk8-b108 91f47e8da5c60de58ed195e9b57f3bf192a18f83 jdk8-b109 +4faa09c7fe555de086dd9048d3c5cc92317d6f45 jdk8-b110 From b6c2a8b1353db48831841d16a206af91a4acbde3 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:26 -0700 Subject: [PATCH 251/293] Added tag jdk8-b110 for changeset 14f8ce49437e --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index fac06acf758..adcc8f82d99 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -231,3 +231,4 @@ d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107 a4bb3b4500164748a9c33b2283cfda76d89f25ab jdk8-b108 428428cf5e06163322144cfb5367e1faa86acf20 jdk8-b109 +3d2b7ce93c5c2e3db748f29c3d29620a8b3b748a jdk8-b110 From 360b472d7f54713b3aca94d35ab762a35832891e Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:31 -0700 Subject: [PATCH 252/293] Added tag jdk8-b110 for changeset 5feed41054de --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 3432d8a4113..3d453534c10 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -381,3 +381,4 @@ a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 566db1b0e6efca31f181456e54c8911d0192410d hs25-b51 c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109 58043478c26d4e8bf48700acea5f97aba8b417d4 hs25-b52 +6209b0ed51c086d4127bac0e086c8f326d1764d7 jdk8-b110 From dcf803b6fe022724a5034a9341429b733017e2d5 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:39 -0700 Subject: [PATCH 253/293] Added tag jdk8-b110 for changeset 8bf1be227a28 --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index bb0b1c00ce9..ded6be1331d 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -231,3 +231,4 @@ d3be8e3b429df917e72c1c23e7920c651219b587 jdk8-b106 d6a32e3831aab20a9a3bc78cdc0a60aaad725c6c jdk8-b107 8ade3eed63da87067a7137c111f684a821e9e531 jdk8-b108 02bfab2aa93899e0f02584f1e85537485a196553 jdk8-b109 +4c84c5b447b09aff27f3b72667ab3a5401e85968 jdk8-b110 From 844ccf771ba9eb8be55402e6d1028e55bdd1ebde Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:41 -0700 Subject: [PATCH 254/293] Added tag jdk8-b110 for changeset f5f4a0ff651d --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 75a5d5b556a..d022629f5c0 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -231,3 +231,4 @@ b1fb4612a2caea52b5661b87509e560fa044b194 jdk8-b98 e3c9328f75638289a342ce15fbe532f05078946e jdk8-b107 d1ea68556fd7925a3c7078dd9f77c6ca73d5aa9e jdk8-b108 df5d4d01642572e77fd3c01e4c8703ed3f6eec87 jdk8-b109 +cc682329886be2fc26220fc30597ee4e5bba43ed jdk8-b110 From 78e2738c5a0b4a81c7f0d4cf2cdcd0073a9205b5 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:45 -0700 Subject: [PATCH 255/293] Added tag jdk8-b110 for changeset e78392f8a04b --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 1d544d7f3d3..cdae1de11aa 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -231,3 +231,4 @@ c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108 946f3fd5f8bf0ccd180c258d25e5837fa1bf004c jdk8-b109 +54e099776f08430d3a7f4feabd9f2ba886b55320 jdk8-b110 From 31995e22bae60a7791e31890eabf0ee87360a1af Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:54 -0700 Subject: [PATCH 256/293] Added tag jdk8-b110 for changeset f5f4ff5ce376 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index cd1913f9ccb..4b927fb6bdb 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -231,3 +231,4 @@ fcd768844b9926c5f994292ec6350c20cc7c0f76 jdk8-b106 3f274927ec1863544b8214262ab02b7de2970da6 jdk8-b107 252f872b8a2f81a416f9127e77924ca56a4578b0 jdk8-b108 985abf1cd327169a317d4ff4f318a8162a5cd47d jdk8-b109 +41541097533aa3933a018c8c1c426c1871dfd76e jdk8-b110 From 62f7e57e935828b8b10e6aa9e637af410265fe43 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Wed, 2 Oct 2013 13:26:56 -0700 Subject: [PATCH 257/293] Added tag jdk8-b110 for changeset 95df1088d4af --- nashorn/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/nashorn/.hgtags b/nashorn/.hgtags index f56727e2010..efd1502e0c8 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -219,3 +219,4 @@ bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106 f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107 445ad3f6d3b4ba62ebc483323e1919110a304053 jdk8-b108 6ec2f9e5ed5bd60c2900976e6a54fdcac2f37e9e jdk8-b109 +d49a8c2173f5f90c9a39cc4af8e03cfa8f35ee4c jdk8-b110 From 88a74de88a919d445d8498dab14d442fbb040f68 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Thu, 3 Oct 2013 11:28:37 +0400 Subject: [PATCH 258/293] 8022632: Reading a PNG file fails because of WBMPImageReaderSpi.canDecodeInput() Reviewed-by: prr, jgodinez --- .../plugins/wbmp/WBMPImageReaderSpi.java | 68 ++++++------- .../imageio/plugins/wbmp/StreamResetTest.java | 97 +++++++++++++++++++ 2 files changed, 131 insertions(+), 34 deletions(-) create mode 100644 jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java diff --git a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java index 38fb6d78b36..95d572ff7fd 100644 --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java @@ -85,42 +85,42 @@ public class WBMPImageReaderSpi extends ImageReaderSpi { ImageInputStream stream = (ImageInputStream)source; stream.mark(); - int type = stream.readByte(); // TypeField - int fixHeaderField = stream.readByte(); - // check WBMP "header" - if (type != 0 || fixHeaderField != 0) { - // while WBMP reader does not support ext WBMP headers + try { + int type = stream.readByte(); // TypeField + int fixHeaderField = stream.readByte(); + // check WBMP "header" + if (type != 0 || fixHeaderField != 0) { + // while WBMP reader does not support ext WBMP headers + return false; + } + + int width = ReaderUtil.readMultiByteInteger(stream); + int height = ReaderUtil.readMultiByteInteger(stream); + // check image dimension + if (width <= 0 || height <= 0) { + return false; + } + + long dataLength = stream.length(); + if (dataLength == -1) { + // We can't verify that amount of data in the stream + // corresponds to image dimension because we do not know + // the length of the data stream. + // Assuming that wbmp image are used for mobile devices, + // let's introduce an upper limit for image dimension. + // In case if exact amount of raster data is unknown, + // let's reject images with dimension above the limit. + return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT); + } + + dataLength -= stream.getStreamPosition(); + + long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1); + + return (dataLength == scanSize * height); + } finally { stream.reset(); - return false; } - - int width = ReaderUtil.readMultiByteInteger(stream); - int height = ReaderUtil.readMultiByteInteger(stream); - // check image dimension - if (width <= 0 || height <= 0) { - stream.reset(); - return false; - } - - long dataLength = stream.length(); - if (dataLength == -1) { - // We can't verify that amount of data in the stream - // corresponds to image dimension because we do not know - // the length of the data stream. - // Assuming that wbmp image are used for mobile devices, - // let's introduce an upper limit for image dimension. - // In case if exact amount of raster data is unknown, - // let's reject images with dimension above the limit. - stream.reset(); - return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT); - } - - dataLength -= stream.getStreamPosition(); - stream.reset(); - - long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1); - - return (dataLength == scanSize * height); } public ImageReader createReaderInstance(Object extension) diff --git a/jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java b/jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java new file mode 100644 index 00000000000..a51880e67fb --- /dev/null +++ b/jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8022632 + * @summary Test verifies that SPI of WBMP image reader + * restores the stream position if an IOException + * occurs during processing of image header. + * @run main StreamResetTest + */ + + +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStreamImpl; + +public class StreamResetTest { + + public static void main(String[] args) { + IOException expectedException = null; + TestStream iis = new TestStream(); + + ImageReader wbmp = ImageIO.getImageReadersByFormatName("WBMP").next(); + if (wbmp == null) { + System.out.println("No WBMP reader: skip the test"); + return; + } + + ImageReaderSpi spi = wbmp.getOriginatingProvider(); + + iis.checkPosition(); + + try { + spi.canDecodeInput(iis); + } catch (IOException e) { + expectedException = e; + } + + if (expectedException == null) { + throw new RuntimeException("Test FAILED: stream was not used"); + } + + iis.checkPosition(); + + System.out.println("Test PASSED"); + + } + + private static class TestStream extends ImageInputStreamImpl { + private final int errorPos = 1; + + @Override + public int read() throws IOException { + if (streamPos == errorPos) { + throw new IOException("Test exception"); + } + streamPos++; + + return 0x03; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + streamPos += len; + return len; + } + + public void checkPosition() { + if (streamPos != 0) { + throw new RuntimeException("Test FAILED"); + } + } + } +} From 46ad112b4d861ba841b364254d311cc296811a4f Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 3 Oct 2013 11:26:11 +0200 Subject: [PATCH 259/293] 8008944: Correct typos Reviewed-by: tbell, erikj --- NewMakefile.gmk | 2 +- common/autoconf/generated-configure.sh | 4 ++-- common/autoconf/jdk-options.m4 | 2 +- common/makefiles/JavaCompilation.gmk | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/NewMakefile.gmk b/NewMakefile.gmk index e15330f5d6b..030675e96ff 100644 --- a/NewMakefile.gmk +++ b/NewMakefile.gmk @@ -66,7 +66,7 @@ else else # We are building multiple configurations. # First, find out the valid targets - # Run the makefile with an arbitraty SPEC using -p -q (quiet dry-run and dump rules) to find + # Run the makefile with an arbitrary SPEC using -p -q (quiet dry-run and dump rules) to find # available PHONY targets. Use this list as valid targets to pass on to the repeated calls. all_phony_targets=$(filter-out $(global_targets) bundles-only, $(strip $(shell \ $(MAKE) -p -q -f common/makefiles/Main.gmk FRC SPEC=$(firstword $(SPEC)) | \ diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 7a65a92ecc4..adf6e10e4ba 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -3818,7 +3818,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1379504921 +DATE_WHEN_GENERATED=1380792206 ############################################################################### # @@ -10935,7 +10935,7 @@ BUILD_HEADLESS="BUILD_HEADLESS:=true" if test "x$SUPPORT_HEADFUL" = xyes; then # We are building both headful and headless. - headful_msg="inlude support for both headful and headless" + headful_msg="include support for both headful and headless" fi if test "x$SUPPORT_HEADFUL" = xno; then diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index b1c99bbe7dc..f52f74d0574 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -316,7 +316,7 @@ BUILD_HEADLESS="BUILD_HEADLESS:=true" if test "x$SUPPORT_HEADFUL" = xyes; then # We are building both headful and headless. - headful_msg="inlude support for both headful and headless" + headful_msg="include support for both headful and headless" fi if test "x$SUPPORT_HEADFUL" = xno; then diff --git a/common/makefiles/JavaCompilation.gmk b/common/makefiles/JavaCompilation.gmk index 50b05865f00..ecc59e3532f 100644 --- a/common/makefiles/JavaCompilation.gmk +++ b/common/makefiles/JavaCompilation.gmk @@ -159,7 +159,7 @@ define SetupArchive endif endif - # Utility macros, to make the shell script receipt somewhat easier to dechipher. + # Utility macros, to make the shell script receipt somewhat easier to decipher. # The capture contents macro finds all files (matching the patterns, typically # .class and .prp) that are newer than the jar-file, ie the new content to be put into the jar. @@ -520,7 +520,7 @@ define SetupJavaCompilation # Using plain javac to batch compile everything. $1 := $$($1_ALL_COPY_TARGETS) $$($1_ALL_COPY_CLEAN_TARGETS) $$($1_BIN)/_the.batch - # When buliding in batch, put headers in a temp dir to filter out those that actually + # When building in batch, put headers in a temp dir to filter out those that actually # changed before copying them to the real header dir. ifneq (,$$($1_HEADERS)) $1_HEADERS_ARG := -h $$($1_HEADERS).tmp From 0d88315d61f351460989a8b0e6fe248ddee97358 Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Thu, 3 Oct 2013 11:27:16 +0200 Subject: [PATCH 260/293] 8024522: java.time packages missing from src.zip Reviewed-by: tbell --- jdk/makefiles/CreateJars.gmk | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index be721548d04..abef9a6dd0b 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -863,26 +863,13 @@ SRC_ZIP_INCLUDES = \ com/sun/java_cup \ com/sun/javadoc \ com/sun/java/swing \ - com/sun/jlex \ com/sun/jmx \ com/sun/naming \ com/sun/org/apache \ com/sun/security/auth \ com/sun/security/jgss \ com/sun/source \ - java/applet \ - java/awt \ - java/beans \ - java/io \ - java/lang \ - java/math \ - java/net \ - java/nio \ - java/rmi \ - java/security \ - java/sql \ - java/text \ - java/util \ + java \ javax/accessibility \ javax/annotation \ javax/imageio \ @@ -902,7 +889,7 @@ SRC_ZIP_INCLUDES = \ org/omg \ org/w3c/dom \ org/xml/sax \ - sunw + # SRC_ZIP_SRCS = $(JDK_TOPDIR)/src/share/classes $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes SRC_ZIP_SRCS += $(JDK_OUTPUTDIR)/gensrc From ed022aded1da01567edd6d2b8a213da0f434c7ff Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Thu, 3 Oct 2013 13:19:19 +0200 Subject: [PATCH 261/293] 8025855: Simplify GenRemSet code slightly Remove a few redundant switch-statements Reviewed-by: jcoomes, tschatzl --- hotspot/src/share/vm/memory/collectorPolicy.cpp | 11 ++--------- hotspot/src/share/vm/memory/genRemSet.cpp | 9 ++------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp index 283db680bb0..99025bcb2b3 100644 --- a/hotspot/src/share/vm/memory/collectorPolicy.cpp +++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp @@ -137,15 +137,8 @@ bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) { GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap, int max_covered_regions) { - switch (rem_set_name()) { - case GenRemSet::CardTable: { - CardTableRS* res = new CardTableRS(whole_heap, max_covered_regions); - return res; - } - default: - guarantee(false, "unrecognized GenRemSet::Name"); - return NULL; - } + assert(rem_set_name() == GenRemSet::CardTable, "unrecognized GenRemSet::Name"); + return new CardTableRS(whole_heap, max_covered_regions); } void CollectorPolicy::cleared_all_soft_refs() { diff --git a/hotspot/src/share/vm/memory/genRemSet.cpp b/hotspot/src/share/vm/memory/genRemSet.cpp index 95a08e1370b..c496deafc03 100644 --- a/hotspot/src/share/vm/memory/genRemSet.cpp +++ b/hotspot/src/share/vm/memory/genRemSet.cpp @@ -32,13 +32,8 @@ // enumeration.) uintx GenRemSet::max_alignment_constraint(Name nm) { - switch (nm) { - case GenRemSet::CardTable: - return CardTableRS::ct_max_alignment_constraint(); - default: - guarantee(false, "Unrecognized GenRemSet type."); - return (0); // Make Windows compiler happy - } + assert(nm == GenRemSet::CardTable, "Unrecognized GenRemSet type."); + return CardTableRS::ct_max_alignment_constraint(); } class HasAccumulatedModifiedOopsClosure : public KlassClosure { From 11da59e5068198890b3490a5e908106d8b5f8519 Mon Sep 17 00:00:00 2001 From: Jesper Wilhelmsson Date: Thu, 3 Oct 2013 17:16:23 +0200 Subject: [PATCH 262/293] 8025853: Remove unnecessary uses of GenerationSizer Removed stray includes and some minor cleanup of GenerationSizer Reviewed-by: tschatzl, jcoomes --- .../vm/gc_implementation/parallelScavenge/generationSizer.hpp | 4 +--- .../parallelScavenge/psAdaptiveSizePolicy.cpp | 1 - .../parallelScavenge/psAdaptiveSizePolicy.hpp | 1 - .../vm/gc_implementation/parallelScavenge/psMarkSweep.cpp | 1 - .../gc_implementation/parallelScavenge/psParallelCompact.cpp | 1 - .../vm/gc_implementation/parallelScavenge/psScavenge.cpp | 1 - 6 files changed, 1 insertion(+), 8 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp index e5637687e84..f7be7671ff9 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp @@ -40,10 +40,8 @@ class GenerationSizer : public TwoGenerationCollectorPolicy { void initialize_flags() { // Do basic sizing work - this->TwoGenerationCollectorPolicy::initialize_flags(); + TwoGenerationCollectorPolicy::initialize_flags(); - // If the user hasn't explicitly set the number of worker - // threads, set the count. assert(UseSerialGC || !FLAG_IS_DEFAULT(ParallelGCThreads) || (ParallelGCThreads > 0), diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp index 7fba4f35813..8d411811b3c 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp @@ -23,7 +23,6 @@ */ #include "precompiled.hpp" -#include "gc_implementation/parallelScavenge/generationSizer.hpp" #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" #include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp" #include "gc_implementation/parallelScavenge/psScavenge.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp index b0cb8c7efbf..d88af2bf6ef 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp @@ -53,7 +53,6 @@ // Forward decls class elapsedTimer; -class GenerationSizer; class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { friend class PSGCAdaptivePolicyCounters; diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index dcdc21806af..5cbd2b4f66a 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -26,7 +26,6 @@ #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" -#include "gc_implementation/parallelScavenge/generationSizer.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index 27a42de95a6..bd3be226773 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -27,7 +27,6 @@ #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" -#include "gc_implementation/parallelScavenge/generationSizer.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" #include "gc_implementation/parallelScavenge/pcTasks.hpp" #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index 60c0267bbe3..026b1a09506 100644 --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -27,7 +27,6 @@ #include "code/codeCache.hpp" #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" -#include "gc_implementation/parallelScavenge/generationSizer.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" From 85c942f353bb02c7b7fca533e1cc81b6c73900b5 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 3 Oct 2013 13:16:31 -0700 Subject: [PATCH 263/293] 8025280: [parfait] warnings from b107 for jdk.src.share.native.sun.java2d.loops: JNI exception pending, JNI critical region violation Reviewed-by: prr, jgodinez --- jdk/src/share/native/sun/java2d/loops/Blit.c | 5 +- .../share/native/sun/java2d/loops/BlitBg.c | 5 +- .../share/native/sun/java2d/loops/DrawPath.c | 36 ++++++++---- .../native/sun/java2d/loops/DrawPolygons.c | 9 ++- .../share/native/sun/java2d/loops/FillPath.c | 38 +++++++++---- .../sun/java2d/loops/GraphicsPrimitiveMgr.c | 57 ++++++++++--------- .../share/native/sun/java2d/loops/MaskBlit.c | 12 +++- .../share/native/sun/java2d/loops/MaskFill.c | 5 ++ .../native/sun/java2d/loops/ScaledBlit.c | 5 +- .../native/sun/java2d/loops/TransformHelper.c | 7 ++- 10 files changed, 121 insertions(+), 58 deletions(-) diff --git a/jdk/src/share/native/sun/java2d/loops/Blit.c b/jdk/src/share/native/sun/java2d/loops/Blit.c index 58f2b9462a5..d6302b319c5 100644 --- a/jdk/src/share/native/sun/java2d/loops/Blit.c +++ b/jdk/src/share/native/sun/java2d/loops/Blit.c @@ -60,8 +60,11 @@ Java_sun_java2d_loops_Blit_Blit } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } diff --git a/jdk/src/share/native/sun/java2d/loops/BlitBg.c b/jdk/src/share/native/sun/java2d/loops/BlitBg.c index 9738bec7984..fe3ba39e0e0 100644 --- a/jdk/src/share/native/sun/java2d/loops/BlitBg.c +++ b/jdk/src/share/native/sun/java2d/loops/BlitBg.c @@ -60,8 +60,11 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_BlitBg_BlitBg } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } diff --git a/jdk/src/share/native/sun/java2d/loops/DrawPath.c b/jdk/src/share/native/sun/java2d/loops/DrawPath.c index 6b51eeedb62..d96c7f8f1bf 100644 --- a/jdk/src/share/native/sun/java2d/loops/DrawPath.c +++ b/jdk/src/share/native/sun/java2d/loops/DrawPath.c @@ -75,7 +75,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath CompositeInfo compInfo; jint ret; NativePrimitive *pPrim = GetNativePrim(env, self); - jint stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + jint stroke; + jboolean throwExc = JNI_FALSE; if (pPrim == NULL) { return; @@ -84,6 +85,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo); } + stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + sdOps = SurfaceData_GetOps(env, sData); if (sdOps == 0) { return; @@ -112,6 +115,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath maxCoords = (*env)->GetArrayLength(env, coordsArray); coords = (jfloat*)(*env)->GetPrimitiveArrayCritical( env, coordsArray, NULL); + if (coords == NULL) { + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); + return; + } if (ret == SD_SLOWLOCK) { GrPrim_RefineBounds(&rasInfo.bounds, transX, transY, @@ -157,22 +164,29 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath drawHandler.yMax = rasInfo.bounds.y2; drawHandler.pData = &dHData; - if (!doDrawPath(&drawHandler, NULL, transX, transY, - coords, maxCoords, types, numTypes, - (stroke == sunHints_INTVAL_STROKE_PURE)? - PH_STROKE_PURE : PH_STROKE_DEFAULT)) - { - JNU_ThrowArrayIndexOutOfBoundsException(env, - "coords array"); - } + if (types != NULL) { + if (!doDrawPath(&drawHandler, NULL, transX, transY, + coords, maxCoords, types, numTypes, + (stroke == sunHints_INTVAL_STROKE_PURE)? + PH_STROKE_PURE : PH_STROKE_DEFAULT)) + { + throwExc = JNI_TRUE; + } - (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, - JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, + JNI_ABORT); + } } } SurfaceData_InvokeRelease(env, sdOps, &rasInfo); } (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords, JNI_ABORT); + + if (throwExc) { + JNU_ThrowArrayIndexOutOfBoundsException(env, + "coords array"); + } + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); } diff --git a/jdk/src/share/native/sun/java2d/loops/DrawPolygons.c b/jdk/src/share/native/sun/java2d/loops/DrawPolygons.c index e7ab0a06f01..5cec234620c 100644 --- a/jdk/src/share/native/sun/java2d/loops/DrawPolygons.c +++ b/jdk/src/share/native/sun/java2d/loops/DrawPolygons.c @@ -186,10 +186,15 @@ Java_sun_java2d_loops_DrawPolygons_DrawPolygons } xPointsPtr = (*env)->GetPrimitiveArrayCritical(env, xPointsArray, NULL); - yPointsPtr = (*env)->GetPrimitiveArrayCritical(env, yPointsArray, NULL); - if (!xPointsPtr || !yPointsPtr) { + if (!xPointsPtr) { ok = JNI_FALSE; } + if (ok) { + yPointsPtr = (*env)->GetPrimitiveArrayCritical(env, yPointsArray, NULL); + if (!yPointsPtr) { + ok = JNI_FALSE; + } + } } if (ok) { diff --git a/jdk/src/share/native/sun/java2d/loops/FillPath.c b/jdk/src/share/native/sun/java2d/loops/FillPath.c index 3411c579aa6..a7b77c09782 100644 --- a/jdk/src/share/native/sun/java2d/loops/FillPath.c +++ b/jdk/src/share/native/sun/java2d/loops/FillPath.c @@ -64,7 +64,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath CompositeInfo compInfo; jint ret; NativePrimitive *pPrim = GetNativePrim(env, self); - jint stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + jint stroke; + jboolean throwExc = JNI_FALSE; if (pPrim == NULL) { return; @@ -73,6 +74,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo); } + stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + sdOps = SurfaceData_GetOps(env, sData); if (sdOps == 0) { return; @@ -102,6 +105,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath maxCoords = (*env)->GetArrayLength(env, coordsArray); coords = (jfloat*)(*env)->GetPrimitiveArrayCritical( env, coordsArray, NULL); + if (coords == NULL) { + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); + return; + } if (ret == SD_SLOWLOCK) { GrPrim_RefineBounds(&rasInfo.bounds, transX, transY, @@ -146,24 +153,31 @@ JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath drawHandler.yMax = rasInfo.bounds.y2; drawHandler.pData = &dHData; - if (!doFillPath(&drawHandler, - transX, transY, coords, - maxCoords, types, numTypes, - (stroke == sunHints_INTVAL_STROKE_PURE)? - PH_STROKE_PURE : PH_STROKE_DEFAULT, - fillRule)) - { - JNU_ThrowArrayIndexOutOfBoundsException(env, - "coords array"); - } + if (types != NULL) { + if (!doFillPath(&drawHandler, + transX, transY, coords, + maxCoords, types, numTypes, + (stroke == sunHints_INTVAL_STROKE_PURE)? + PH_STROKE_PURE : PH_STROKE_DEFAULT, + fillRule)) + { + throwExc = JNI_TRUE; + } - (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, + (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, JNI_ABORT); + } } } SurfaceData_InvokeRelease(env, sdOps, &rasInfo); } (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords, JNI_ABORT); + + if (throwExc) { + JNU_ThrowArrayIndexOutOfBoundsException(env, + "coords array"); + } + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); } diff --git a/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.c b/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.c index 7e323086c1a..352a5ebeeca 100644 --- a/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.c +++ b/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.c @@ -205,33 +205,36 @@ Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops RegisterFunc RegisterFourByteAbgr; RegisterFunc RegisterFourByteAbgrPre; - RegisterAnyByte(env); - RegisterByteBinary1Bit(env); - RegisterByteBinary2Bit(env); - RegisterByteBinary4Bit(env); - RegisterByteIndexed(env); - RegisterByteGray(env); - RegisterIndex8Gray(env); - RegisterIndex12Gray(env); - RegisterAnyShort(env); - RegisterUshort555Rgb(env); - RegisterUshort565Rgb(env); - RegisterUshort4444Argb(env); - RegisterUshort555Rgbx(env); - RegisterUshortGray(env); - RegisterUshortIndexed(env); - RegisterAny3Byte(env); - RegisterThreeByteBgr(env); - RegisterAnyInt(env); - RegisterIntArgb(env); - RegisterIntArgbPre(env); - RegisterIntArgbBm(env); - RegisterIntRgb(env); - RegisterIntBgr(env); - RegisterIntRgbx(env); - RegisterAny4Byte(env); - RegisterFourByteAbgr(env); - RegisterFourByteAbgrPre(env); + if (!RegisterAnyByte(env) || + !RegisterByteBinary1Bit(env) || + !RegisterByteBinary2Bit(env) || + !RegisterByteBinary4Bit(env) || + !RegisterByteIndexed(env) || + !RegisterByteGray(env) || + !RegisterIndex8Gray(env) || + !RegisterIndex12Gray(env) || + !RegisterAnyShort(env) || + !RegisterUshort555Rgb(env) || + !RegisterUshort565Rgb(env) || + !RegisterUshort4444Argb(env) || + !RegisterUshort555Rgbx(env) || + !RegisterUshortGray(env) || + !RegisterUshortIndexed(env) || + !RegisterAny3Byte(env) || + !RegisterThreeByteBgr(env) || + !RegisterAnyInt(env) || + !RegisterIntArgb(env) || + !RegisterIntArgbPre(env) || + !RegisterIntArgbBm(env) || + !RegisterIntRgb(env) || + !RegisterIntBgr(env) || + !RegisterIntRgbx(env) || + !RegisterAny4Byte(env) || + !RegisterFourByteAbgr(env) || + !RegisterFourByteAbgrPre(env)) + { + return; + } } #define _StartOf(T) ((T *) (&T##s)) diff --git a/jdk/src/share/native/sun/java2d/loops/MaskBlit.c b/jdk/src/share/native/sun/java2d/loops/MaskBlit.c index 2c023411803..3463315bcf6 100644 --- a/jdk/src/share/native/sun/java2d/loops/MaskBlit.c +++ b/jdk/src/share/native/sun/java2d/loops/MaskBlit.c @@ -60,8 +60,11 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } @@ -96,6 +99,13 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit (maskArray ? (*env)->GetPrimitiveArrayCritical(env, maskArray, 0) : 0); + if (maskArray != NULL && pMask == NULL) { + SurfaceData_InvokeRelease(env, dstOps, &dstInfo); + SurfaceData_InvokeRelease(env, srcOps, &srcInfo); + SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); + SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); + return; + } jint savesx = srcInfo.bounds.x1; jint savedx = dstInfo.bounds.x1; Region_StartIteration(env, &clipInfo); diff --git a/jdk/src/share/native/sun/java2d/loops/MaskFill.c b/jdk/src/share/native/sun/java2d/loops/MaskFill.c index 0003675d43c..2e5d3ed4e12 100644 --- a/jdk/src/share/native/sun/java2d/loops/MaskFill.c +++ b/jdk/src/share/native/sun/java2d/loops/MaskFill.c @@ -84,6 +84,11 @@ Java_sun_java2d_loops_MaskFill_MaskFill (maskArray ? (*env)->GetPrimitiveArrayCritical(env, maskArray, 0) : 0); + if (maskArray != NULL && pMask == NULL) { + SurfaceData_InvokeRelease(env, sdOps, &rasInfo); + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); + return; + } maskoff += ((rasInfo.bounds.y1 - y) * maskscan + (rasInfo.bounds.x1 - x)); (*pPrim->funcs.maskfill)(pDst, diff --git a/jdk/src/share/native/sun/java2d/loops/ScaledBlit.c b/jdk/src/share/native/sun/java2d/loops/ScaledBlit.c index 625c3662f3c..486a9842b60 100644 --- a/jdk/src/share/native/sun/java2d/loops/ScaledBlit.c +++ b/jdk/src/share/native/sun/java2d/loops/ScaledBlit.c @@ -296,8 +296,11 @@ Java_sun_java2d_loops_ScaledBlit_Scale } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } diff --git a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c index 72334550250..6d53054ab9c 100644 --- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c +++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c @@ -326,8 +326,11 @@ Java_sun_java2d_loops_TransformHelper_Transform } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } @@ -411,7 +414,7 @@ Java_sun_java2d_loops_TransformHelper_Transform } if (pEdges == NULL) { - if (numedges > 0) { + if (!(*env)->ExceptionCheck(env) && numedges > 0) { JNU_ThrowInternalError(env, "Unable to allocate edge list"); } SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); From fa90ce8bf8195e34d089d4678b1d70b0f47407b7 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 3 Oct 2013 13:26:45 -0700 Subject: [PATCH 264/293] 8025480: [parfait] "JNI exception pending" warnings from b107 for jdk.src.share.native.sun.java2d Reviewed-by: prr, jgodinez --- jdk/src/share/native/sun/java2d/Disposer.c | 9 ++++++--- jdk/src/share/native/sun/java2d/SurfaceData.c | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/native/sun/java2d/Disposer.c b/jdk/src/share/native/sun/java2d/Disposer.c index 5379df637a4..611631732d8 100644 --- a/jdk/src/share/native/sun/java2d/Disposer.c +++ b/jdk/src/share/native/sun/java2d/Disposer.c @@ -38,10 +38,9 @@ Java_sun_java2d_Disposer_initIDs(JNIEnv *env, jclass disposerClass) { addRecordMID = (*env)->GetStaticMethodID(env, disposerClass, "addRecord", "(Ljava/lang/Object;JJ)V"); - if (addRecordMID == 0) { - JNU_ThrowNoSuchMethodError(env, "Disposer.addRecord"); + if (addRecordMID != 0) { + dispClass = (*env)->NewGlobalRef(env, disposerClass); } - dispClass = (*env)->NewGlobalRef(env, disposerClass); } JNIEXPORT void JNICALL @@ -50,6 +49,10 @@ Disposer_AddRecord(JNIEnv *env, jobject obj, GeneralDisposeFunc disposer, jlong if (dispClass == NULL) { /* Needed to initialize the Disposer class as it may be not yet referenced */ jclass clazz = (*env)->FindClass(env, "sun/java2d/Disposer"); + if ((*env)->ExceptionCheck(env)) { + // If there's exception pending, we'll just return. + return; + } } (*env)->CallStaticVoidMethod(env, dispClass, addRecordMID, diff --git a/jdk/src/share/native/sun/java2d/SurfaceData.c b/jdk/src/share/native/sun/java2d/SurfaceData.c index 73d43adf798..d72fa284f8a 100644 --- a/jdk/src/share/native/sun/java2d/SurfaceData.c +++ b/jdk/src/share/native/sun/java2d/SurfaceData.c @@ -237,7 +237,9 @@ SurfaceDataOps *SurfaceData_InitOps(JNIEnv *env, jobject sData, int opsSize) SurfaceData_SetOps(env, sData, ops); if (ops != NULL) { memset(ops, 0, opsSize); - ops->sdObject = (*env)->NewWeakGlobalRef(env, sData); + if (!(*env)->ExceptionCheck(env)) { + ops->sdObject = (*env)->NewWeakGlobalRef(env, sData); + } } return ops; } From 3a01c9493eef71c063fb0e2acf5d976146ef1ed7 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 3 Oct 2013 13:35:26 -0700 Subject: [PATCH 265/293] 8025309: [parfait] JNI-related warnings from b107 for jdk.src.share.native.sun.java2d.pipe Reviewed-by: prr, jgodinez --- .../sun/java2d/pipe/BufferedRenderPipe.c | 6 ++- jdk/src/share/native/sun/java2d/pipe/Region.c | 4 ++ .../sun/java2d/pipe/ShapeSpanIterator.c | 11 +++-- .../native/sun/java2d/pipe/SpanClipRenderer.c | 45 +++++++++++++++---- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/native/sun/java2d/pipe/BufferedRenderPipe.c b/jdk/src/share/native/sun/java2d/pipe/BufferedRenderPipe.c index 62cc5ef2c7c..849fd2adcc5 100644 --- a/jdk/src/share/native/sun/java2d/pipe/BufferedRenderPipe.c +++ b/jdk/src/share/native/sun/java2d/pipe/BufferedRenderPipe.c @@ -53,6 +53,7 @@ Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans unsigned char *bbuf; jint *ibuf; jint ipos; + jboolean hasException; J2dTraceLn2(J2D_TRACE_INFO, "BufferedRenderPipe_fillSpans: bpos=%d limit=%d", @@ -104,7 +105,10 @@ Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans ibuf[1] = spanCount; // flush the queue - JNU_CallMethodByName(env, NULL, rq, "flushNow", "(I)V", bpos); + JNU_CallMethodByName(env, &hasException, rq, "flushNow", "(I)V", bpos); + if (hasException) { + break; + } // now start a new operation ibuf = (jint *)bbuf; diff --git a/jdk/src/share/native/sun/java2d/pipe/Region.c b/jdk/src/share/native/sun/java2d/pipe/Region.c index 97c682cf0e3..4bafa105ed6 100644 --- a/jdk/src/share/native/sun/java2d/pipe/Region.c +++ b/jdk/src/share/native/sun/java2d/pipe/Region.c @@ -260,6 +260,10 @@ RegionToYXBandedRectangles(JNIEnv *env, /* return; REMIND: What to do here? */ } Region_StartIteration(env, &clipInfo); + if ((*env)->ExceptionCheck(env)) { + return 0; + } + numrects = Region_CountIterationRects(&clipInfo); if ((unsigned long)numrects > initialBufferSize) { *pRect = (RECT_T *) SAFE_SIZE_ARRAY_ALLOC(malloc, numrects, sizeof(RECT_T)); diff --git a/jdk/src/share/native/sun/java2d/pipe/ShapeSpanIterator.c b/jdk/src/share/native/sun/java2d/pipe/ShapeSpanIterator.c index e8580273955..2462307ab9b 100644 --- a/jdk/src/share/native/sun/java2d/pipe/ShapeSpanIterator.c +++ b/jdk/src/share/native/sun/java2d/pipe/ShapeSpanIterator.c @@ -653,12 +653,15 @@ Java_sun_java2d_pipe_ShapeSpanIterator_appendPoly pd->curx = x; pd->cury = y; } + (*env)->ReleasePrimitiveArrayCritical(env, yArray, + yPoints, JNI_ABORT); } - (*env)->ReleasePrimitiveArrayCritical(env, yArray, - yPoints, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, xArray, + xPoints, JNI_ABORT); + } + if (xPoints == NULL || yPoints == NULL) { + return; } - (*env)->ReleasePrimitiveArrayCritical(env, xArray, - xPoints, JNI_ABORT); } if (!oom) { HANDLEENDPATH(pd, {oom = JNI_TRUE;}); diff --git a/jdk/src/share/native/sun/java2d/pipe/SpanClipRenderer.c b/jdk/src/share/native/sun/java2d/pipe/SpanClipRenderer.c index ad53574bdeb..2b5190fada0 100644 --- a/jdk/src/share/native/sun/java2d/pipe/SpanClipRenderer.c +++ b/jdk/src/share/native/sun/java2d/pipe/SpanClipRenderer.c @@ -44,21 +44,27 @@ Java_sun_java2d_pipe_SpanClipRenderer_initIDs { /* Region fields */ pBandsArrayID = (*env)->GetFieldID(env, rc, "bands", "[I"); + if (pBandsArrayID == NULL) { + return; + } pEndIndexID = (*env)->GetFieldID(env, rc, "endIndex", "I"); + if (pEndIndexID == NULL) { + return; + } /* RegionIterator fields */ pRegionID = (*env)->GetFieldID(env, ric, "region", "Lsun/java2d/pipe/Region;"); + if (pRegionID == NULL) { + return; + } pCurIndexID = (*env)->GetFieldID(env, ric, "curIndex", "I"); + if (pCurIndexID == NULL) { + return; + } pNumXbandsID = (*env)->GetFieldID(env, ric, "numXbands", "I"); - - if((pBandsArrayID == NULL) - || (pEndIndexID == NULL) - || (pRegionID == NULL) - || (pCurIndexID == NULL) - || (pNumXbandsID == NULL)) - { - JNU_ThrowInternalError(env, "NULL field ID"); + if (pNumXbandsID == NULL) { + return; } } @@ -129,10 +135,14 @@ Java_sun_java2d_pipe_SpanClipRenderer_fillTile if ((*env)->GetArrayLength(env, boxArray) < 4) { JNU_ThrowArrayIndexOutOfBoundsException(env, "band array"); + return; } alphalen = (*env)->GetArrayLength(env, alphaTile); box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0); + if (box == NULL) { + return; + } w = box[2] - box[0]; h = box[3] - box[1]; @@ -140,9 +150,14 @@ Java_sun_java2d_pipe_SpanClipRenderer_fillTile if (alphalen < offset || (alphalen - offset) / tsize < h) { (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array"); + return; } alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0); + if (alpha == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); + return; + } fill(alpha, offset, tsize, 0, 0, w, h, (jbyte) 0xff); @@ -182,6 +197,7 @@ Java_sun_java2d_pipe_SpanClipRenderer_eraseTile if ((*env)->GetArrayLength(env, boxArray) < 4) { JNU_ThrowArrayIndexOutOfBoundsException(env, "band array"); + return; } alphalen = (*env)->GetArrayLength(env, alphaTile); @@ -196,6 +212,9 @@ Java_sun_java2d_pipe_SpanClipRenderer_eraseTile } box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0); + if (box == NULL) { + return; + } lox = box[0]; loy = box[1]; @@ -207,10 +226,20 @@ Java_sun_java2d_pipe_SpanClipRenderer_eraseTile (alphalen - offset - (hix-lox)) / tsize < (hiy - loy - 1)) { (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array"); + return; } bands = (*env)->GetPrimitiveArrayCritical(env, bandsArray, 0); + if (bands == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); + return; + } alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0); + if (alpha == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, bandsArray, bands, 0); + (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); + return; + } curIndex = saveCurIndex; numXbands = saveNumXbands; From 3c27e706c7a3cab21b2a30d2c583d76dda132c55 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 3 Oct 2013 13:41:53 -0700 Subject: [PATCH 266/293] 8025664: [parfait] warnings from b62 for jdk.src.share.native.sun.font Reviewed-by: prr, jgodinez --- .../share/native/sun/font/freetypeScaler.c | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/jdk/src/share/native/sun/font/freetypeScaler.c b/jdk/src/share/native/sun/font/freetypeScaler.c index 7e82c4da555..c562f546275 100644 --- a/jdk/src/share/native/sun/font/freetypeScaler.c +++ b/jdk/src/share/native/sun/font/freetypeScaler.c @@ -252,7 +252,6 @@ Java_sun_font_FreetypeFontScaler_initNativeScaler( JNIEnv *env, jobject scaler, jobject font2D, jint type, jint indexInCollection, jboolean supportsCJK, jint filesize) { FTScalerInfo* scalerInfo = NULL; - FT_Stream ftstream; FT_Open_Args ft_open_args; int error; jobject bBuffer; @@ -309,34 +308,36 @@ Java_sun_font_FreetypeFontScaler_initNativeScaler( } } else { /* Truetype */ scalerInfo->fontData = (unsigned char*) malloc(FILEDATACACHESIZE); - ftstream = (FT_Stream) calloc(1, sizeof(FT_StreamRec)); - if (ftstream != NULL && scalerInfo->fontData != NULL) { - scalerInfo->directBuffer = (*env)->NewDirectByteBuffer(env, - scalerInfo->fontData, - FILEDATACACHESIZE); - if (scalerInfo->directBuffer != NULL) { - scalerInfo->directBuffer = (*env)->NewGlobalRef(env, - scalerInfo->directBuffer); - ftstream->base = NULL; - ftstream->size = filesize; - ftstream->pos = 0; - ftstream->read = (FT_Stream_IoFunc) ReadTTFontFileFunc; - ftstream->close = (FT_Stream_CloseFunc) CloseTTFontFileFunc; - ftstream->pathname.pointer = (void *) scalerInfo; + if (scalerInfo->fontData != NULL) { + FT_Stream ftstream = (FT_Stream) calloc(1, sizeof(FT_StreamRec)); + if (ftstream != NULL) { + scalerInfo->directBuffer = (*env)->NewDirectByteBuffer(env, + scalerInfo->fontData, + FILEDATACACHESIZE); + if (scalerInfo->directBuffer != NULL) { + scalerInfo->directBuffer = (*env)->NewGlobalRef(env, + scalerInfo->directBuffer); + ftstream->base = NULL; + ftstream->size = filesize; + ftstream->pos = 0; + ftstream->read = (FT_Stream_IoFunc) ReadTTFontFileFunc; + ftstream->close = (FT_Stream_CloseFunc) CloseTTFontFileFunc; + ftstream->pathname.pointer = (void *) scalerInfo; - memset(&ft_open_args, 0, sizeof(FT_Open_Args)); - ft_open_args.flags = FT_OPEN_STREAM; - ft_open_args.stream = ftstream; + memset(&ft_open_args, 0, sizeof(FT_Open_Args)); + ft_open_args.flags = FT_OPEN_STREAM; + ft_open_args.stream = ftstream; - error = FT_Open_Face(scalerInfo->library, - &ft_open_args, - indexInCollection, - &scalerInfo->face); - } - if (error || scalerInfo->directBuffer == NULL) { - free(ftstream); - } + error = FT_Open_Face(scalerInfo->library, + &ft_open_args, + indexInCollection, + &scalerInfo->face); + } + if (error || scalerInfo->directBuffer == NULL) { + free(ftstream); + } + } } } From 7b490635eab23904992fd4bd7faf86e49bb769f6 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Thu, 3 Oct 2013 13:49:52 -0700 Subject: [PATCH 267/293] 8025294: [parfait] JNI-related warnings from b107 for jdk.src.solaris.native.sun.java2d.x11 Reviewed-by: prr, jgodinez --- .../solaris/native/sun/java2d/x11/X11Renderer.c | 17 ++++++----------- .../native/sun/java2d/x11/X11SurfaceData.c | 8 ++++++-- .../native/sun/java2d/x11/XRBackendNative.c | 10 ++++++++++ .../native/sun/java2d/x11/XRSurfaceData.c | 6 ++++++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/jdk/src/solaris/native/sun/java2d/x11/X11Renderer.c b/jdk/src/solaris/native/sun/java2d/x11/X11Renderer.c index cfae03c92dd..bbe32a07ba2 100644 --- a/jdk/src/solaris/native/sun/java2d/x11/X11Renderer.c +++ b/jdk/src/solaris/native/sun/java2d/x11/X11Renderer.c @@ -465,9 +465,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XDrawPoly points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy, pTmp, (int *)&npoints, isclosed); - if (points == 0) { - JNU_ThrowOutOfMemoryError(env, "translated coordinate array"); - } else { + if (points != 0) { if (npoints == 2) { /* * Some X11 implementations fail to draw anything for @@ -588,6 +586,7 @@ Java_sun_java2d_x11_X11Renderer_XDoPath NULL }; PHStroke stroke; + jboolean ok = JNI_TRUE; if (xsdo == NULL) { return; @@ -625,8 +624,6 @@ Java_sun_java2d_x11_X11Renderer_XDoPath types = (jbyte*) (*env)->GetPrimitiveArrayCritical(env, typesArray, NULL); if (types != NULL) { - jboolean ok; - if (isFill) { drawHandler.pDrawScanline = &drawScanline; ok = doFillPath(&drawHandler, @@ -643,14 +640,14 @@ Java_sun_java2d_x11_X11Renderer_XDoPath types, numTypes, stroke); } - if (!ok) { - JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array"); - } (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, JNI_ABORT); } (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords, JNI_ABORT); + if (!ok) { + JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array"); + } } XDHD_FREE_POINTS(&dHData); @@ -893,9 +890,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_x11_X11Renderer_XFillPoly points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy, pTmp, (int *)&npoints, JNI_FALSE); - if (points == 0) { - JNU_ThrowOutOfMemoryError(env, "translated coordinate array"); - } else { + if (points != 0) { if (npoints > 2) { XFillPolygon(awt_display, xsdo->drawable, (GC) xgc, points, npoints, Complex, CoordModeOrigin); diff --git a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c index f944cff7ee9..a35d6fd3065 100644 --- a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c +++ b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c @@ -227,7 +227,7 @@ Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable(JNIEnv *env, jobject this) #if defined(HEADLESS) || !defined(MITSHM) return JNI_FALSE; #else - return useMitShmPixmaps; + return (jboolean)useMitShmPixmaps; #endif /* HEADLESS, MITSHM */ } @@ -258,6 +258,7 @@ Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd, { #ifndef HEADLESS X11SDOps *xsdo = (X11SDOps*)SurfaceData_InitOps(env, xsd, sizeof(X11SDOps)); + jboolean hasException; if (xsdo == NULL) { JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); return; @@ -270,7 +271,10 @@ Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd, xsdo->ReleasePixmapWithBg = X11SD_ReleasePixmapWithBg; xsdo->widget = NULL; if (peer != NULL) { - xsdo->drawable = JNU_CallMethodByName(env, NULL, peer, "getWindow", "()J").j; + xsdo->drawable = JNU_CallMethodByName(env, &hasException, peer, "getWindow", "()J").j; + if (hasException) { + return; + } } else { xsdo->drawable = 0; } diff --git a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c index 1705c28f4fb..3a5c9caca80 100644 --- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c +++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c @@ -326,7 +326,13 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) { jlong fmt32; jfieldID a8ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_A8", "J"); + if (a8ID == NULL) { + return; + } jfieldID argb32ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB32", "J"); + if (argb32ID == NULL) { + return; + } if (awt_display == (Display *)NULL) { return; @@ -346,6 +352,10 @@ Java_sun_java2d_xr_XRBackendNative_initIDs(JNIEnv *env, jclass cls) { defaultImg = XCreateImage(awt_display, NULL, 8, ZPixmap, 0, maskData, 32, 32, 8, 0); defaultImg->data = maskData; //required? maskImgID = (*env)->GetStaticFieldID(env, cls, "MASK_XIMG", "J"); + if (maskImgID == NULL) { + return; + } + (*env)->SetStaticLongField(env, cls, maskImgID, ptr_to_jlong(defaultImg)); } diff --git a/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c b/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c index b598a22ab95..a9c762f87c1 100644 --- a/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c +++ b/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c @@ -88,7 +88,13 @@ Java_sun_java2d_xr_XRSurfaceData_initIDs(JNIEnv *env, jclass xsd) J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initIDs"); pictID = (*env)->GetFieldID(env, xsd, "picture", "I"); + if (pictID == NULL) { + return; + } xidID = (*env)->GetFieldID(env, xsd, "xid", "I"); + if (xidID == NULL) { + return; + } XShared_initIDs(env, JNI_FALSE); #endif /* !HEADLESS */ From f718e1fa54737338e7a104622fac94b86c74b11a Mon Sep 17 00:00:00 2001 From: Robert Field Date: Fri, 4 Oct 2013 09:54:43 -0700 Subject: [PATCH 268/293] 8021186: jdk/lambda/vm/DefaultMethodsTest.java fails Remove DefaultMethodsTest from jdk/test/problemList.txt Reviewed-by: mduigou --- jdk/test/ProblemList.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index c8279529c28..484fbc70081 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -166,9 +166,6 @@ demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java generic-all # 7027502 demo/jvmti/hprof/MonitorTest.java generic-all -# 8021186 -jdk/lambda/vm/DefaultMethodsTest.java generic-all - # 8024423 - JVMTI: GetLoadedClasses doesn't enumerate anonymous classes demo/jvmti/hprof/HeapAllTest.java generic-all demo/jvmti/hprof/HeapBinaryFormatTest.java generic-all From c8559006231f529e61698e4c611eb913618c7637 Mon Sep 17 00:00:00 2001 From: Bhavesh Patel Date: Fri, 4 Oct 2013 15:25:18 -0700 Subject: [PATCH 269/293] 8025741: Fix jdk/make/docs/Makefile to point to correct docs URL for JDK 8 Reviewed-by: tbell --- jdk/make/docs/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/make/docs/Makefile b/jdk/make/docs/Makefile index 66810971f72..ad9a2c55be5 100644 --- a/jdk/make/docs/Makefile +++ b/jdk/make/docs/Makefile @@ -50,6 +50,7 @@ BUG_SUBMIT_LINE = Submit a bug or feature DEV_DOCS_URL-5 = http://java.sun.com/j2se/1.5.0/docs/index.html DEV_DOCS_URL-6 = http://download.oracle.com/javase/6/docs/index.html DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html +DEV_DOCS_URL-8 = http://download.oracle.com/javase/8/docs/index.html DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION)) DOCS_BASE_URL = http://download.oracle.com/javase/7/docs From 1d4c1c6ee535827bc533053bede27f3e19e01e13 Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Fri, 4 Oct 2013 16:27:12 +0100 Subject: [PATCH 270/293] 8016271: wsimport -clientjar does not create portable jars on Windows due to hardcoded backslash Reviewed-by: mkos, chegar --- .../javax/xml/ws/clientjar/TestService.java | 39 +++++ .../javax/xml/ws/clientjar/TestWsImport.java | 151 ++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 jdk/test/javax/xml/ws/clientjar/TestService.java create mode 100644 jdk/test/javax/xml/ws/clientjar/TestWsImport.java diff --git a/jdk/test/javax/xml/ws/clientjar/TestService.java b/jdk/test/javax/xml/ws/clientjar/TestService.java new file mode 100644 index 00000000000..94646e7698c --- /dev/null +++ b/jdk/test/javax/xml/ws/clientjar/TestService.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.jws.WebService; + +@WebService(serviceName ="TestService", targetNamespace = "http://test/jaxws/sample/") +public class TestService { + public void foo() { + try { + bar(); + } catch (Exception e) { + throw new AssertionError(e); + } + } + + private void bar() { + // nothing done + } +} diff --git a/jdk/test/javax/xml/ws/clientjar/TestWsImport.java b/jdk/test/javax/xml/ws/clientjar/TestWsImport.java new file mode 100644 index 00000000000..add1c2a7ed7 --- /dev/null +++ b/jdk/test/javax/xml/ws/clientjar/TestWsImport.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8016271 + * @summary wsimport -clientjar does not create portable jar on windows due to hardcoded '\' + * @run main/othervm TestWsImport + */ + +import javax.xml.namespace.QName; +import javax.xml.ws.Endpoint; +import javax.xml.ws.Service; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.BufferedReader; +import java.io.File; +import java.net.InetSocketAddress; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.FileVisitResult; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import static java.nio.file.FileVisitResult.*; +import java.util.Enumeration; +import java.util.jar.JarFile; + +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpServer; + +public class TestWsImport { + + public static void main(String[] args) throws IOException { + + String javaHome = System.getProperty("java.home"); + if (javaHome.endsWith("jre")) { + javaHome = new File(javaHome).getParent(); + } + String wsimport = javaHome + File.separator + "bin" + File.separator + "wsimport"; + if (System.getProperty("os.name").startsWith("Windows")) { + wsimport = wsimport.concat(".exe"); + } + + Endpoint endpoint = Endpoint.create(new TestService()); + HttpServer httpServer = null; + try { + // Manually create HttpServer here using ephemeral address for port + // so as to not end up with attempt to bind to an in-use port + httpServer = HttpServer.create(new InetSocketAddress(0), 0); + HttpContext httpContext = httpServer.createContext("/hello"); + int port = httpServer.getAddress().getPort(); + System.out.println("port = " + port); + httpServer.start(); + endpoint.publish(httpContext); + String address = "http://localhost:" + port + "/hello"; + + Service service = Service.create(new URL(address + "?wsdl"), + new QName("http://test/jaxws/sample/", + "TestService")); + + String[] wsargs = { + wsimport, + "-p", + "wstest", + "-J-Djavax.xml.accessExternalSchema=all", + address + "?wsdl", + "-clientjar", + "wsjar.jar" + }; + ProcessBuilder pb = new ProcessBuilder(wsargs); + pb.redirectErrorStream(true); + Process p = pb.start(); + BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream())); + String s = r.readLine(); + while (s != null) { + System.out.println(s.trim()); + s = r.readLine(); + } + p.waitFor(); + p.destroy(); + + try (JarFile jarFile = new JarFile("wsjar.jar")) { + for (Enumeration em = jarFile.entries(); em.hasMoreElements();) { + String fileName = em.nextElement().toString(); + if (fileName.contains("\\")) { + throw new RuntimeException("\"\\\" character detected in jar file: " + fileName); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } finally { + endpoint.stop(); + if (httpServer != null) { + httpServer.stop(0); + } + Path p = Paths.get("wsjar.jar"); + Files.deleteIfExists(p); + p = Paths.get("wstest"); + if (Files.exists(p)) { + try { + Files.walkFileTree(p, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) throws IOException { + + Files.delete(file); + return CONTINUE; + } + @Override + public FileVisitResult postVisitDirectory(Path dir, + IOException exc) throws IOException { + + if (exc == null) { + Files.delete(dir); + return CONTINUE; + } else { + throw exc; + } + } + }); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + } + } +} From 91b6c6cb5f61cc4e6876065419bd6e737a3302a9 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 4 Oct 2013 14:10:09 -0700 Subject: [PATCH 271/293] Added tag hs25-b53 for changeset 2e003ae41242 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 3d453534c10..b21447baec0 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -382,3 +382,4 @@ a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 c81dd5393a5e333df7cb1f6621f5897ada6522b5 jdk8-b109 58043478c26d4e8bf48700acea5f97aba8b417d4 hs25-b52 6209b0ed51c086d4127bac0e086c8f326d1764d7 jdk8-b110 +562a3d356de67670b4172b82aca2d30743449e04 hs25-b53 From c1c21c0ff1d4934931f72f31799c65d1703f2d99 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Fri, 4 Oct 2013 16:17:59 -0700 Subject: [PATCH 272/293] 8025940: Windows build fails after the fix for 8025280 Reviewed-by: prr, jgodinez --- jdk/src/share/native/sun/java2d/loops/MaskBlit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/native/sun/java2d/loops/MaskBlit.c b/jdk/src/share/native/sun/java2d/loops/MaskBlit.c index 3463315bcf6..83f9493d74b 100644 --- a/jdk/src/share/native/sun/java2d/loops/MaskBlit.c +++ b/jdk/src/share/native/sun/java2d/loops/MaskBlit.c @@ -99,6 +99,8 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit (maskArray ? (*env)->GetPrimitiveArrayCritical(env, maskArray, 0) : 0); + jint savesx = srcInfo.bounds.x1; + jint savedx = dstInfo.bounds.x1; if (maskArray != NULL && pMask == NULL) { SurfaceData_InvokeRelease(env, dstOps, &dstInfo); SurfaceData_InvokeRelease(env, srcOps, &srcInfo); @@ -106,8 +108,6 @@ Java_sun_java2d_loops_MaskBlit_MaskBlit SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); return; } - jint savesx = srcInfo.bounds.x1; - jint savedx = dstInfo.bounds.x1; Region_StartIteration(env, &clipInfo); while (Region_NextIteration(&clipInfo, &span)) { void *pSrc = PtrCoord(srcInfo.rasBase, From 62ee211c8dc2cb4f503145ee27ca8d2885a07bb0 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:38 -0700 Subject: [PATCH 273/293] 8024761: JSR 292 improve performance of generic invocation Use a per-MH one element cache for MH.asType to speed up MH.invoke; also cache enough MH constants to cache LMF.metafactory Reviewed-by: twisti --- .../java/lang/invoke/BoundMethodHandle.java | 5 + .../classes/java/lang/invoke/CallSite.java | 48 +++- .../java/lang/invoke/InvokeGeneric.java | 148 ----------- .../classes/java/lang/invoke/Invokers.java | 239 +++++++++--------- .../classes/java/lang/invoke/LambdaForm.java | 31 ++- .../classes/java/lang/invoke/MemberName.java | 75 ++++-- .../java/lang/invoke/MethodHandle.java | 22 +- .../java/lang/invoke/MethodHandleImpl.java | 23 +- .../java/lang/invoke/MethodHandleNatives.java | 42 +-- .../java/lang/invoke/MethodHandles.java | 93 +++++-- .../java/lang/invoke/MethodTypeForm.java | 19 +- 11 files changed, 395 insertions(+), 350 deletions(-) delete mode 100644 jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java diff --git a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java index 846920a59a9..9aaafd7c7f1 100644 --- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java @@ -360,6 +360,10 @@ import jdk.internal.org.objectweb.asm.Type; return new Name(mh, mhName); } + NamedFunction getterFunction(int i) { + return new NamedFunction(getters[i]); + } + static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class); private SpeciesData(String types, Class clazz) { @@ -394,6 +398,7 @@ import jdk.internal.org.objectweb.asm.Type; private boolean isPlaceholder() { return clazz == null; } private static final HashMap CACHE = new HashMap<>(); + static { CACHE.put("", EMPTY); } // make bootstrap predictable private static final boolean INIT_DONE; // set after finishes... SpeciesData extendWithType(char type) { diff --git a/jdk/src/share/classes/java/lang/invoke/CallSite.java b/jdk/src/share/classes/java/lang/invoke/CallSite.java index d83464155fd..e08f1db4733 100644 --- a/jdk/src/share/classes/java/lang/invoke/CallSite.java +++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java @@ -261,7 +261,7 @@ public class CallSite { Object info, // Caller information: Class callerClass) { - Object caller = IMPL_LOOKUP.in(callerClass); + MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass); CallSite site; try { Object binding; @@ -273,14 +273,44 @@ public class CallSite { } else { Object[] argv = (Object[]) info; maybeReBoxElements(argv); - if (3 + argv.length > 255) - throw new BootstrapMethodError("too many bootstrap method arguments"); - MethodType bsmType = bootstrapMethod.type(); - if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class) - binding = bootstrapMethod.invoke(caller, name, type, argv); - else - binding = MethodHandles.spreadInvoker(bsmType, 3) - .invoke(bootstrapMethod, caller, name, type, argv); + switch (argv.length) { + case 0: + binding = bootstrapMethod.invoke(caller, name, type); + break; + case 1: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0]); + break; + case 2: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1]); + break; + case 3: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2]); + break; + case 4: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2], argv[3]); + break; + case 5: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2], argv[3], argv[4]); + break; + case 6: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + break; + default: + final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type) + if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY) + throw new BootstrapMethodError("too many bootstrap method arguments"); + MethodType bsmType = bootstrapMethod.type(); + MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length); + MethodHandle typedBSM = bootstrapMethod.asType(invocationType); + MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT); + binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv); + } } //System.out.println("BSM for "+name+type+" => "+binding); if (binding instanceof CallSite) { diff --git a/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java b/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java deleted file mode 100644 index 81f663bec4b..00000000000 --- a/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.lang.invoke; - -import sun.invoke.util.*; -import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; - -/** - * Adapters which manage inexact MethodHandle.invoke calls. - * The JVM calls one of these when the exact type match fails. - * @author jrose - */ -class InvokeGeneric { - // erased type for the call, which originates from an inexact invoke site - private final MethodType erasedCallerType; - // an invoker of type (MT, MH; A...) -> R - private final MethodHandle initialInvoker; - - /** Compute and cache information for this adapter, so that it can - * call out to targets of the erasure-family of the given erased type. - */ - /*non-public*/ InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException { - assert(erasedCallerType.equals(erasedCallerType.erase())); - this.erasedCallerType = erasedCallerType; - this.initialInvoker = makeInitialInvoker(); - assert initialInvoker.type().equals(erasedCallerType - .insertParameterTypes(0, MethodType.class, MethodHandle.class)) - : initialInvoker.type(); - } - - private static MethodHandles.Lookup lookup() { - return IMPL_LOOKUP; - } - - /** Return the adapter information for this type's erasure. */ - /*non-public*/ static MethodHandle generalInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException { - InvokeGeneric gen = new InvokeGeneric(erasedCallerType); - return gen.initialInvoker; - } - - private MethodHandle makeInitialInvoker() throws ReflectiveOperationException { - // postDispatch = #(MH'; MT, MH; A...){MH'(MT, MH; A)} - MethodHandle postDispatch = makePostDispatchInvoker(); - MethodHandle invoker; - if (returnConversionPossible()) { - invoker = MethodHandles.foldArguments(postDispatch, - dispatcher("dispatchWithConversion")); - } else { - invoker = MethodHandles.foldArguments(postDispatch, dispatcher("dispatch")); - } - return invoker; - } - - private static final Class[] EXTRA_ARGS = { MethodType.class, MethodHandle.class }; - private MethodHandle makePostDispatchInvoker() { - // Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...). - MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS); - return invokerType.invokers().exactInvoker(); - } - private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) { - assert(targetInvoker.type().parameterType(0) == MethodHandle.class); - return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS); - } - - private MethodHandle dispatcher(String dispatchName) throws ReflectiveOperationException { - return lookup().bind(this, dispatchName, - MethodType.methodType(MethodHandle.class, - MethodType.class, MethodHandle.class)); - } - - static final boolean USE_AS_TYPE_PATH = true; - - /** Return a method handle to invoke on the callerType, target, and remaining arguments. - * The method handle must finish the call. - * This is the first look at the caller type and target. - */ - private MethodHandle dispatch(MethodType callerType, MethodHandle target) { - MethodType targetType = target.type(); - if (USE_AS_TYPE_PATH || target.isVarargsCollector()) { - MethodHandle newTarget = target.asType(callerType); - targetType = callerType; - Invokers invokers = targetType.invokers(); - MethodHandle invoker = invokers.erasedInvokerWithDrops; - if (invoker == null) { - invokers.erasedInvokerWithDrops = invoker = - dropDispatchArguments(invokers.erasedInvoker()); - } - return invoker.bindTo(newTarget); - } - throw new RuntimeException("NYI"); - } - - private MethodHandle dispatchWithConversion(MethodType callerType, MethodHandle target) { - MethodHandle finisher = dispatch(callerType, target); - if (returnConversionNeeded(callerType, target)) - finisher = addReturnConversion(finisher, callerType.returnType()); //FIXME: slow - return finisher; - } - - private boolean returnConversionPossible() { - Class needType = erasedCallerType.returnType(); - return !needType.isPrimitive(); - } - private boolean returnConversionNeeded(MethodType callerType, MethodHandle target) { - Class needType = callerType.returnType(); - if (needType == erasedCallerType.returnType()) - return false; // no conversions possible, since must be primitive or Object - Class haveType = target.type().returnType(); - if (VerifyType.isNullConversion(haveType, needType) && !needType.isInterface()) - return false; - return true; - } - private MethodHandle addReturnConversion(MethodHandle finisher, Class type) { - // FIXME: This is slow because it creates a closure node on every call that requires a return cast. - MethodType finisherType = finisher.type(); - MethodHandle caster = ValueConversions.identity(type); - caster = caster.asType(caster.type().changeParameterType(0, finisherType.returnType())); - finisher = MethodHandles.filterReturnValue(finisher, caster); - return finisher.asType(finisherType); - } - - public String toString() { - return "InvokeGeneric"+erasedCallerType; - } -} diff --git a/jdk/src/share/classes/java/lang/invoke/Invokers.java b/jdk/src/share/classes/java/lang/invoke/Invokers.java index 0ef6078b6b5..6214aad8620 100644 --- a/jdk/src/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java @@ -44,6 +44,7 @@ class Invokers { // exact invoker for the outgoing call private /*lazy*/ MethodHandle exactInvoker; + private /*lazy*/ MethodHandle basicInvoker; // invokeBasic (unchecked exact) // erased (partially untyped but with primitives) invoker for the outgoing call // FIXME: get rid of @@ -74,21 +75,7 @@ class Invokers { /*non-public*/ MethodHandle exactInvoker() { MethodHandle invoker = exactInvoker; if (invoker != null) return invoker; - MethodType mtype = targetType; - MethodType invokerType = mtype.invokerType(); - LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - MTYPE_ARG_APPENDED) { - lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_INVOKER); - invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype); - } else { - // At maximum arity, we cannot afford an extra mtype argument, - // so build a fully customized (non-cached) invoker form. - lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER); - invoker = SimpleMethodHandle.make(invokerType, lform); - } - invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invokeExact", mtype)); - assert(checkInvoker(invoker)); + invoker = makeExactOrGeneralInvoker(true); exactInvoker = invoker; return invoker; } @@ -96,43 +83,56 @@ class Invokers { /*non-public*/ MethodHandle generalInvoker() { MethodHandle invoker = generalInvoker; if (invoker != null) return invoker; - MethodType mtype = targetType; - MethodType invokerType = mtype.invokerType(); - LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - assert(GENERIC_INVOKER_SLOP >= MTYPE_ARG_APPENDED); - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - GENERIC_INVOKER_SLOP) { - prepareForGenericCall(mtype); - lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_INVOKER); - invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype); - } else { - // At maximum arity, we cannot afford an extra mtype argument, - // so build a fully customized (non-cached) invoker form. - lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER); - invoker = SimpleMethodHandle.make(invokerType, lform); - } - invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invoke", mtype)); - assert(checkInvoker(invoker)); + invoker = makeExactOrGeneralInvoker(false); generalInvoker = invoker; return invoker; } - /*non-public*/ MethodHandle makeBasicInvoker() { - MethodHandle invoker = DirectMethodHandle.make(invokeBasicMethod(targetType)); - assert(targetType == targetType.basicType()); - // Note: This is not cached here. It is cached by the calling MethodTypeForm. + private MethodHandle makeExactOrGeneralInvoker(boolean isExact) { + MethodType mtype = targetType; + MethodType invokerType = mtype.invokerType(); + int which = (isExact ? MethodTypeForm.LF_EX_INVOKER : MethodTypeForm.LF_GEN_INVOKER); + LambdaForm lform = invokeHandleForm(mtype, false, which); + MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype); + String whichName = (isExact ? "invokeExact" : "invoke"); + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype)); assert(checkInvoker(invoker)); + maybeCompileToBytecode(invoker); return invoker; } - static MemberName invokeBasicMethod(MethodType type) { - type = type.basicType(); - String name = "invokeBasic"; + /** If the target type seems to be common enough, eagerly compile the invoker to bytecodes. */ + private void maybeCompileToBytecode(MethodHandle invoker) { + final int EAGER_COMPILE_ARITY_LIMIT = 10; + if (targetType == targetType.erase() && + targetType.parameterCount() < EAGER_COMPILE_ARITY_LIMIT) { + invoker.form.compileToBytecode(); + } + } + + /*non-public*/ MethodHandle basicInvoker() { + MethodHandle invoker = basicInvoker; + if (invoker != null) return invoker; + MethodType basicType = targetType.basicType(); + if (basicType != targetType) { + // double cache; not used significantly + return basicInvoker = basicType.invokers().basicInvoker(); + } + MemberName method = invokeBasicMethod(basicType); + invoker = DirectMethodHandle.make(method); + assert(checkInvoker(invoker)); + basicInvoker = invoker; + return invoker; + } + + // This next one is called from LambdaForm.NamedFunction.. + /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) { + assert(basicType == basicType.basicType()); try { //Lookup.findVirtual(MethodHandle.class, name, type); - return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, name, type); + return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, "invokeBasic", basicType); } catch (ReflectiveOperationException ex) { - throw newInternalError("JVM cannot find invoker for "+type, ex); + throw newInternalError("JVM cannot find invoker for "+basicType, ex); } } @@ -184,6 +184,7 @@ class Invokers { vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader); } assert(vaInvoker.type().equals(spreadInvokerType.invokerType())); + maybeCompileToBytecode(vaInvoker); spreadInvokers[leadingArgCount] = vaInvoker; return vaInvoker; } @@ -231,32 +232,38 @@ class Invokers { return "Invokers"+targetType; } - static MemberName exactInvokerMethod(MethodType mtype, Object[] appendixResult) { + static MemberName methodHandleInvokeLinkerMethod(String name, + MethodType mtype, + Object[] appendixResult) { + int which; + switch (name) { + case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break; + case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break; + default: throw new InternalError("not invoker: "+name); + } LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MTYPE_ARG_APPENDED) { - lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_LINKER); + if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) { + lform = invokeHandleForm(mtype, false, which); appendixResult[0] = mtype; } else { - lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_LINKER); + lform = invokeHandleForm(mtype, true, which); } return lform.vmentry; } - static MemberName genericInvokerMethod(MethodType mtype, Object[] appendixResult) { - LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - (MTYPE_ARG_APPENDED + GENERIC_INVOKER_SLOP)) { - lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_LINKER); - appendixResult[0] = mtype; - prepareForGenericCall(mtype); - } else { - lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_LINKER); - } - return lform.vmentry; - } + // argument count to account for trailing "appendix value" (typically the mtype) + private static final int MH_LINKER_ARG_APPENDED = 1; - private static LambdaForm invokeForm(MethodType mtype, boolean customized, int which) { + /** Returns an adapter for invokeExact or generic invoke, as a MH or constant pool linker. + * If !customized, caller is responsible for supplying, during adapter execution, + * a copy of the exact mtype. This is because the adapter might be generalized to + * a basic type. + * @param mtype the caller's method type (either basic or full-custom) + * @param customized whether to use a trailing appendix argument (to carry the mtype) + * @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker"); + * 0x02 whether it is for invokeExact or generic invoke + */ + private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) { boolean isCached; if (!customized) { mtype = mtype.basicType(); // normalize Z to I, String to Object, etc. @@ -301,41 +308,24 @@ class Invokers { : Arrays.asList(mtype, customized, which, nameCursor, names.length); if (MTYPE_ARG >= INARG_LIMIT) { assert(names[MTYPE_ARG] == null); - names[MTYPE_ARG] = BoundMethodHandle.getSpeciesData("L").getterName(names[THIS_MH], 0); + NamedFunction getter = BoundMethodHandle.getSpeciesData("L").getterFunction(0); + names[MTYPE_ARG] = new Name(getter, names[THIS_MH]); // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM) } // Make the final call. If isGeneric, then prepend the result of type checking. - MethodType outCallType; - Object[] outArgs; + MethodType outCallType = mtype.basicType(); + Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class); Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]); if (!isGeneric) { names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg); // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*) - outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class); - outCallType = mtype; - } else if (customized) { - names[CHECK_TYPE] = new Name(NF_asType, names[CALL_MH], mtypeArg); - // mh.invokeGeneric(a*):R => - // let mt=TYPEOF(a*:R), tmh=asType(mh, mt); - // tmh.invokeBasic(a*) - outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class); - outCallType = mtype; } else { names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg); - // mh.invokeGeneric(a*):R => - // let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt); - // gamh.invokeBasic(mt, mh, a*) - final int PREPEND_GAMH = 0, PREPEND_MT = 1, PREPEND_COUNT = 2; - assert(GENERIC_INVOKER_SLOP == PREPEND_COUNT); - outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT + PREPEND_COUNT, Object[].class); - // prepend arguments: - System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT); - outArgs[PREPEND_GAMH] = names[CHECK_TYPE]; - outArgs[PREPEND_MT] = mtypeArg; - outCallType = mtype.insertParameterTypes(0, MethodType.class, MethodHandle.class); + // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*) + outArgs[0] = names[CHECK_TYPE]; } - names[LINKER_CALL] = new Name(invokeBasicMethod(outCallType), outArgs); + names[LINKER_CALL] = new Name(outCallType, outArgs); lform = new LambdaForm(debugName, INARG_LIMIT, names); if (isLinker) lform.compileToBytecode(); // JVM needs a real methodOop @@ -343,7 +333,6 @@ class Invokers { lform = mtype.form().setCachedLambdaForm(which, lform); return lform; } - private static final int GENERIC_INVOKER_SLOP = 2; // used elsewhere to avoid arity problems /*non-public*/ static WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) { @@ -362,47 +351,53 @@ class Invokers { throw newWrongMethodTypeException(expected, actual); } - /** Static definition of MethodHandle.invokeGeneric checking code. */ + /** Static definition of MethodHandle.invokeGeneric checking code. + * Directly returns the type-adjusted MH to invoke, as follows: + * {@code (R)MH.invoke(a*) => MH.asType(TYPEOF(a*:R)).invokeBasic(a*)} + */ /*non-public*/ static @ForceInline Object checkGenericType(Object mhObj, Object expectedObj) { MethodHandle mh = (MethodHandle) mhObj; MethodType expected = (MethodType) expectedObj; - //MethodType actual = mh.type(); - MethodHandle gamh = expected.form().genericInvoker; - if (gamh != null) return gamh; - return prepareForGenericCall(expected); - } - - /** - * Returns an adapter GA for invoking a MH with type adjustments. - * The MethodType of the generic invocation site is prepended to MH - * and its arguments as follows: - * {@code (R)MH.invoke(A*) => GA.invokeBasic(TYPEOF, MH, A*)} - */ - /*non-public*/ static MethodHandle prepareForGenericCall(MethodType mtype) { - // force any needed adapters to be preconstructed - MethodTypeForm form = mtype.form(); - MethodHandle gamh = form.genericInvoker; - if (gamh != null) return gamh; - try { - // Trigger adapter creation. - gamh = InvokeGeneric.generalInvokerOf(form.erasedType); - form.genericInvoker = gamh; - return gamh; - } catch (Exception ex) { - throw newInternalError("Exception while resolving inexact invoke", ex); - } + if (mh.type() == expected) return mh; + MethodHandle atc = mh.asTypeCache; + if (atc != null && atc.type() == expected) return atc; + return mh.asType(expected); + /* Maybe add more paths here. Possible optimizations: + * for (R)MH.invoke(a*), + * let MT0 = TYPEOF(a*:R), MT1 = MH.type + * + * if MT0==MT1 or MT1 can be safely called by MT0 + * => MH.invokeBasic(a*) + * if MT1 can be safely called by MT0[R := Object] + * => MH.invokeBasic(a*) & checkcast(R) + * if MT1 can be safely called by MT0[* := Object] + * => checkcast(A)* & MH.invokeBasic(a*) & checkcast(R) + * if a big adapter BA can be pulled out of (MT0,MT1) + * => BA.invokeBasic(MT0,MH,a*) + * if a local adapter LA can cached on static CS0 = new GICS(MT0) + * => CS0.LA.invokeBasic(MH,a*) + * else + * => MH.asType(MT0).invokeBasic(A*) + */ } static MemberName linkToCallSiteMethod(MethodType mtype) { - LambdaForm lform = callSiteForm(mtype); + LambdaForm lform = callSiteForm(mtype, false); return lform.vmentry; } - private static LambdaForm callSiteForm(MethodType mtype) { + static MemberName linkToTargetMethod(MethodType mtype) { + LambdaForm lform = callSiteForm(mtype, true); + return lform.vmentry; + } + + // skipCallSite is true if we are optimizing a ConstantCallSite + private static LambdaForm callSiteForm(MethodType mtype, boolean skipCallSite) { mtype = mtype.basicType(); // normalize Z to I, String to Object, etc. - LambdaForm lform = mtype.form().cachedLambdaForm(MethodTypeForm.LF_CS_LINKER); + final int which = (skipCallSite ? MethodTypeForm.LF_MH_LINKER : MethodTypeForm.LF_CS_LINKER); + LambdaForm lform = mtype.form().cachedLambdaForm(which); if (lform != null) return lform; // exactInvokerForm (Object,Object)Object // link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial @@ -410,24 +405,26 @@ class Invokers { final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount(); final int INARG_LIMIT = OUTARG_LIMIT + 1; int nameCursor = OUTARG_LIMIT; - final int CSITE_ARG = nameCursor++; // the last in-argument - final int CALL_MH = nameCursor++; // result of getTarget + final int APPENDIX_ARG = nameCursor++; // the last in-argument + final int CSITE_ARG = skipCallSite ? -1 : APPENDIX_ARG; + final int CALL_MH = skipCallSite ? APPENDIX_ARG : nameCursor++; // result of getTarget final int LINKER_CALL = nameCursor++; - MethodType invokerFormType = mtype.appendParameterTypes(CallSite.class); + MethodType invokerFormType = mtype.appendParameterTypes(skipCallSite ? MethodHandle.class : CallSite.class); Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType); assert(names.length == nameCursor); - assert(names[CSITE_ARG] != null); - names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]); + assert(names[APPENDIX_ARG] != null); + if (!skipCallSite) + names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]); // (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*) final int PREPEND_MH = 0, PREPEND_COUNT = 1; Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class); // prepend MH argument: System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT); outArgs[PREPEND_MH] = names[CALL_MH]; - names[LINKER_CALL] = new Name(invokeBasicMethod(mtype), outArgs); - lform = new LambdaForm("linkToCallSite", INARG_LIMIT, names); + names[LINKER_CALL] = new Name(mtype, outArgs); + lform = new LambdaForm((skipCallSite ? "linkToTargetMethod" : "linkToCallSite"), INARG_LIMIT, names); lform.compileToBytecode(); // JVM needs a real methodOop - lform = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_CS_LINKER, lform); + lform = mtype.form().setCachedLambdaForm(which, lform); return lform; } diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java index 96d83fb4705..d83fc4780a1 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java @@ -457,7 +457,7 @@ class LambdaForm { isCompiled = true; return vmentry; } catch (Error | Exception ex) { - throw newInternalError(this.toString(), ex); + throw newInternalError("compileToBytecode", ex); } } @@ -683,8 +683,9 @@ class LambdaForm { */ static void traceInterpreter(String event, Object obj, Object... args) { - if (!TRACE_INTERPRETER) return; - System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : "")); + if (TRACE_INTERPRETER) { + System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : "")); + } } static void traceInterpreter(String event, Object obj) { traceInterpreter(event, obj, (Object[])null); @@ -982,6 +983,16 @@ class LambdaForm { //resolvedHandle = eraseSubwordTypes(resolvedHandle); this.resolvedHandle = resolvedHandle; } + NamedFunction(MethodType basicInvokerType) { + assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType; + if (basicInvokerType.parameterSlotCount() < MethodType.MAX_MH_INVOKER_ARITY) { + this.resolvedHandle = basicInvokerType.invokers().basicInvoker(); + this.member = resolvedHandle.internalMemberName(); + } else { + // necessary to pass BigArityTest + this.member = Invokers.invokeBasicMethod(basicInvokerType); + } + } // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc. // Any LambdaForm containing such a member is not interpretable. @@ -1229,7 +1240,7 @@ class LambdaForm { } public String toString() { - if (member == null) return resolvedHandle.toString(); + if (member == null) return String.valueOf(resolvedHandle); return member.getDeclaringClass().getSimpleName()+"."+member.getName(); } } @@ -1279,6 +1290,10 @@ class LambdaForm { Name(MethodHandle function, Object... arguments) { this(new NamedFunction(function), arguments); } + Name(MethodType functionType, Object... arguments) { + this(new NamedFunction(functionType), arguments); + assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == 'L'); + } Name(MemberName function, Object... arguments) { this(new NamedFunction(function), arguments); } @@ -1622,4 +1637,12 @@ class LambdaForm { */ static { NamedFunction.initializeInvokers(); } + + // The following hack is necessary in order to suppress TRACE_INTERPRETER + // during execution of the static initializes of this class. + // Turning on TRACE_INTERPRETER too early will cause + // stack overflows and other misbehavior during attempts to trace events + // that occur during LambdaForm.. + // Therefore, do not move this line higher in this file, and do not remove. + private static final boolean TRACE_INTERPRETER = MethodHandleStatics.TRACE_INTERPRETER; } diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java index 05d291c25a1..5b6cecba909 100644 --- a/jdk/src/share/classes/java/lang/invoke/MemberName.java +++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java @@ -556,6 +556,9 @@ import java.util.Objects; } throw new IllegalArgumentException(this.toString()); } + /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind. + * In that case it must already be REF_invokeSpecial. + */ public MemberName asConstructor() { switch (getReferenceKind()) { case REF_invokeSpecial: return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial); @@ -563,6 +566,32 @@ import java.util.Objects; } throw new IllegalArgumentException(this.toString()); } + /** If this MN is a REF_invokeSpecial, return a clone with the "normal" kind + * REF_invokeVirtual; also switch either to REF_invokeInterface if clazz.isInterface. + * The end result is to get a fully virtualized version of the MN. + * (Note that resolving in the JVM will sometimes devirtualize, changing + * REF_invokeVirtual of a final to REF_invokeSpecial, and REF_invokeInterface + * in some corner cases to either of the previous two; this transform + * undoes that change under the assumption that it occurred.) + */ + public MemberName asNormalOriginal() { + byte normalVirtual = clazz.isInterface() ? REF_invokeInterface : REF_invokeVirtual; + byte refKind = getReferenceKind(); + byte newRefKind = refKind; + MemberName result = this; + switch (refKind) { + case REF_invokeInterface: + case REF_invokeVirtual: + case REF_invokeSpecial: + newRefKind = normalVirtual; + break; + } + if (newRefKind == refKind) + return this; + result = clone().changeReferenceKind(newRefKind, refKind); + assert(this.referenceKindIsConsistentWith(result.getReferenceKind())); + return result; + } /** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */ @SuppressWarnings("LeakingThisInConstructor") public MemberName(Constructor ctor) { @@ -660,7 +689,7 @@ import java.util.Objects; @Override public int hashCode() { - return Objects.hash(clazz, flags, name, getType()); + return Objects.hash(clazz, getReferenceKind(), name, getType()); } @Override public boolean equals(Object that) { @@ -676,13 +705,14 @@ import java.util.Objects; if (this == that) return true; if (that == null) return false; return this.clazz == that.clazz - && this.flags == that.flags + && this.getReferenceKind() == that.getReferenceKind() && Objects.equals(this.name, that.name) && Objects.equals(this.getType(), that.getType()); } // Construction from symbolic parts, for queries: - /** Create a field or type name from the given components: Declaring class, name, type, reference kind. + /** Create a field or type name from the given components: + * Declaring class, name, type, reference kind. * The declaring class may be supplied as null if this is to be a bare name and type. * The resulting name will in an unresolved state. */ @@ -706,21 +736,34 @@ import java.util.Objects; * The resulting name will in an unresolved state. */ public MemberName(Class defClass, String name, MethodType type, byte refKind) { - @SuppressWarnings("LocalVariableHidesMemberVariable") - int flags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD); - init(defClass, name, type, flagsMods(flags, 0, refKind)); + int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD); + init(defClass, name, type, flagsMods(initFlags, 0, refKind)); + initResolved(false); + } + /** Create a method, constructor, or field name from the given components: + * Reference kind, declaring class, name, type. + */ + public MemberName(byte refKind, Class defClass, String name, Object type) { + int kindFlags; + if (MethodHandleNatives.refKindIsField(refKind)) { + kindFlags = IS_FIELD; + if (!(type instanceof Class)) + throw newIllegalArgumentException("not a field type"); + } else if (MethodHandleNatives.refKindIsMethod(refKind)) { + kindFlags = IS_METHOD; + if (!(type instanceof MethodType)) + throw newIllegalArgumentException("not a method type"); + } else if (refKind == REF_newInvokeSpecial) { + kindFlags = IS_CONSTRUCTOR; + if (!(type instanceof MethodType) || + !CONSTRUCTOR_NAME.equals(name)) + throw newIllegalArgumentException("not a constructor type or name"); + } else { + throw newIllegalArgumentException("bad reference kind "+refKind); + } + init(defClass, name, type, flagsMods(kindFlags, 0, refKind)); initResolved(false); } -// /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers. -// * It will be a constructor if and only if the name is {@code "<init>"}. -// * The declaring class may be supplied as null if this is to be a bare name and type. -// * The modifier flags default to zero. -// * The resulting name will in an unresolved state. -// */ -// public MemberName(Class defClass, String name, MethodType type, Void unused) { -// this(defClass, name, type, REF_NONE); -// } - /** Query whether this member name is resolved to a non-static, non-final method. */ public boolean hasReceiverTypeDispatch() { diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index 613d223fe2a..25bb5e58537 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -420,6 +420,8 @@ public abstract class MethodHandle { private final MethodType type; /*private*/ final LambdaForm form; // form is not private so that invokers can easily fetch it + /*private*/ MethodHandle asTypeCache; + // asTypeCache is not private so that invokers can easily fetch it /** * Reports the type of this method handle. @@ -739,10 +741,24 @@ public abstract class MethodHandle { * @see MethodHandles#explicitCastArguments */ public MethodHandle asType(MethodType newType) { - if (!type.isConvertibleTo(newType)) { - throw new WrongMethodTypeException("cannot convert "+this+" to "+newType); + // Fast path alternative to a heavyweight {@code asType} call. + // Return 'this' if the conversion will be a no-op. + if (newType == type) { + return this; } - return convertArguments(newType); + // Return 'this.asTypeCache' if the conversion is already memoized. + MethodHandle atc = asTypeCache; + if (atc != null && newType == atc.type) { + return atc; + } + return asTypeUncached(newType); + } + + /** Override this to change asType behavior. */ + /*non-public*/ MethodHandle asTypeUncached(MethodType newType) { + if (!type.isConvertibleTo(newType)) + throw new WrongMethodTypeException("cannot convert "+this+" to "+newType); + return asTypeCache = convertArguments(newType); } /** diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index 6918fec1cca..f5fc1b7a707 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -314,13 +314,13 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; static class AsVarargsCollector extends MethodHandle { private final MethodHandle target; private final Class arrayType; - private MethodHandle cache; + private /*@Stable*/ MethodHandle asCollectorCache; AsVarargsCollector(MethodHandle target, MethodType type, Class arrayType) { super(type, reinvokerForm(target)); this.target = target; this.arrayType = arrayType; - this.cache = target.asCollector(arrayType, 0); + this.asCollectorCache = target.asCollector(arrayType, 0); } @Override MethodHandle reinvokerTarget() { return target; } @@ -336,18 +336,19 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } @Override - public MethodHandle asType(MethodType newType) { + public MethodHandle asTypeUncached(MethodType newType) { MethodType type = this.type(); int collectArg = type.parameterCount() - 1; int newArity = newType.parameterCount(); if (newArity == collectArg+1 && type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) { // if arity and trailing parameter are compatible, do normal thing - return asFixedArity().asType(newType); + return asTypeCache = asFixedArity().asType(newType); } // check cache - if (cache.type().parameterCount() == newArity) - return cache.asType(newType); + MethodHandle acc = asCollectorCache; + if (acc != null && acc.type().parameterCount() == newArity) + return asTypeCache = acc.asType(newType); // build and cache a collector int arrayLength = newArity - collectArg; MethodHandle collector; @@ -357,8 +358,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } catch (IllegalArgumentException ex) { throw new WrongMethodTypeException("cannot build collector", ex); } - cache = collector; - return collector.asType(newType); + asCollectorCache = collector; + return asTypeCache = collector.asType(newType); } @Override @@ -977,6 +978,12 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; return target; } @Override + public MethodHandle asTypeUncached(MethodType newType) { + // This MH is an alias for target, except for the MemberName + // Drop the MemberName if there is any conversion. + return asTypeCache = target.asType(newType); + } + @Override MemberName internalMemberName() { return member; } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java index 9a71299a031..56cb245e6ae 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -233,20 +233,19 @@ class MethodHandleNatives { } static String refKindName(byte refKind) { assert(refKindIsValid(refKind)); - return REFERENCE_KIND_NAME[refKind]; + switch (refKind) { + case REF_getField: return "getField"; + case REF_getStatic: return "getStatic"; + case REF_putField: return "putField"; + case REF_putStatic: return "putStatic"; + case REF_invokeVirtual: return "invokeVirtual"; + case REF_invokeStatic: return "invokeStatic"; + case REF_invokeSpecial: return "invokeSpecial"; + case REF_newInvokeSpecial: return "newInvokeSpecial"; + case REF_invokeInterface: return "invokeInterface"; + default: return "REF_???"; + } } - private static String[] REFERENCE_KIND_NAME = { - null, - "getField", - "getStatic", - "putField", - "putStatic", - "invokeVirtual", - "invokeStatic", - "invokeSpecial", - "newInvokeSpecial", - "invokeInterface" - }; private static native int getNamedCon(int which, Object[] name); static boolean verifyConstants() { @@ -294,12 +293,18 @@ class MethodHandleNatives { Class caller = (Class)callerObj; String name = nameObj.toString().intern(); MethodType type = (MethodType)typeObj; - appendixResult[0] = CallSite.makeSite(bootstrapMethod, + CallSite callSite = CallSite.makeSite(bootstrapMethod, name, type, staticArguments, caller); - return Invokers.linkToCallSiteMethod(type); + if (callSite instanceof ConstantCallSite) { + appendixResult[0] = callSite.dynamicInvoker(); + return Invokers.linkToTargetMethod(type); + } else { + appendixResult[0] = callSite; + return Invokers.linkToCallSiteMethod(type); + } } /** @@ -388,12 +393,7 @@ class MethodHandleNatives { Object[] appendixResult) { try { if (defc == MethodHandle.class && refKind == REF_invokeVirtual) { - switch (name) { - case "invoke": - return Invokers.genericInvokerMethod(fixMethodType(callerClass, type), appendixResult); - case "invokeExact": - return Invokers.exactInvokerMethod(fixMethodType(callerClass, type), appendixResult); - } + return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult); } } catch (Throwable ex) { if (ex instanceof LinkageError) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index f0f9447e001..a4f217f5a51 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -39,6 +39,7 @@ import sun.reflect.misc.ReflectUtil; import sun.security.util.SecurityConstants; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; +import java.util.concurrent.ConcurrentHashMap; import sun.security.util.SecurityConstants; /** @@ -1090,19 +1091,30 @@ return mh1; MemberName resolveOrFail(byte refKind, Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE + name.getClass(); // NPE + type.getClass(); // NPE return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchFieldException.class); } MemberName resolveOrFail(byte refKind, Class refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE + name.getClass(); // NPE + type.getClass(); // NPE return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchMethodException.class); } + MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException { + checkSymbolicClass(member.getDeclaringClass()); // do this before attempting to resolve + member.getName().getClass(); // NPE + member.getType().getClass(); // NPE + return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(), + ReflectiveOperationException.class); + } + void checkSymbolicClass(Class refc) throws IllegalAccessException { + refc.getClass(); // NPE Class caller = lookupClassOrNull(); if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); @@ -1348,29 +1360,74 @@ return mh1; */ /*non-public*/ MethodHandle linkMethodHandleConstant(byte refKind, Class defc, String name, Object type) throws ReflectiveOperationException { - MemberName resolved = null; - if (type instanceof MemberName) { - resolved = (MemberName) type; - if (!resolved.isResolved()) throw new InternalError("unresolved MemberName"); - assert(name == null || name.equals(resolved.getName())); + if (!(type instanceof Class || type instanceof MethodType)) + throw new InternalError("unresolved MemberName"); + MemberName member = new MemberName(refKind, defc, name, type); + MethodHandle mh = LOOKASIDE_TABLE.get(member); + if (mh != null) { + checkSymbolicClass(defc); + return mh; } + MemberName resolved = resolveOrFail(refKind, member); + mh = getDirectMethodHandle(refKind, defc, resolved); + if (mh instanceof DirectMethodHandle + && canBeCached(refKind, defc, resolved)) { + MemberName key = mh.internalMemberName(); + if (key != null) { + key = key.asNormalOriginal(); + } + if (member.equals(key)) { // better safe than sorry + LOOKASIDE_TABLE.put(key, (DirectMethodHandle) mh); + } + } + return mh; + } + private + boolean canBeCached(byte refKind, Class defc, MemberName member) { + if (refKind == REF_invokeSpecial) { + return false; + } + if (!Modifier.isPublic(defc.getModifiers()) || + !Modifier.isPublic(member.getDeclaringClass().getModifiers()) || + !member.isPublic() || + member.isCallerSensitive()) { + return false; + } + ClassLoader loader = defc.getClassLoader(); + if (!sun.misc.VM.isSystemDomainLoader(loader)) { + ClassLoader sysl = ClassLoader.getSystemClassLoader(); + boolean found = false; + while (sysl != null) { + if (loader == sysl) { found = true; break; } + sysl = sysl.getParent(); + } + if (!found) { + return false; + } + } + try { + MemberName resolved2 = publicLookup().resolveOrFail(refKind, + new MemberName(refKind, defc, member.getName(), member.getType())); + checkSecurityManager(defc, resolved2); + } catch (ReflectiveOperationException | SecurityException ex) { + return false; + } + return true; + } + private + MethodHandle getDirectMethodHandle(byte refKind, Class defc, MemberName member) throws ReflectiveOperationException { if (MethodHandleNatives.refKindIsField(refKind)) { - MemberName field = (resolved != null) ? resolved - : resolveOrFail(refKind, defc, name, (Class) type); - return getDirectField(refKind, defc, field); + return getDirectField(refKind, defc, member); } else if (MethodHandleNatives.refKindIsMethod(refKind)) { - MemberName method = (resolved != null) ? resolved - : resolveOrFail(refKind, defc, name, (MethodType) type); - return getDirectMethod(refKind, defc, method, lookupClass); + return getDirectMethod(refKind, defc, member, lookupClass); } else if (refKind == REF_newInvokeSpecial) { - assert(name == null || name.equals("")); - MemberName ctor = (resolved != null) ? resolved - : resolveOrFail(REF_newInvokeSpecial, defc, name, (MethodType) type); - return getDirectConstructor(defc, ctor); + return getDirectConstructor(defc, member); } // oops - throw new ReflectiveOperationException("bad MethodHandle constant #"+refKind+" "+name+" : "+type); + throw newIllegalArgumentException("bad MethodHandle constant #"+member); } + + static ConcurrentHashMap LOOKASIDE_TABLE = new ConcurrentHashMap<>(); } /** diff --git a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java index f279035c447..09a07b1877f 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java @@ -28,6 +28,7 @@ package java.lang.invoke; import sun.invoke.util.Wrapper; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; + import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; /** * Shared information for a group of method types, which differ @@ -74,7 +75,8 @@ final class MethodTypeForm { LF_GEN_LINKER = 11, LF_GEN_INVOKER = 12, LF_CS_LINKER = 13, // linkToCallSite_CS - LF_LIMIT = 14; + LF_MH_LINKER = 14, // linkToCallSite_MH + LF_LIMIT = 15; public MethodType erasedType() { return erasedType; @@ -97,11 +99,24 @@ final class MethodTypeForm { assert(erasedType == basicType) : "erasedType: " + erasedType + " != basicType: " + basicType; // primitives must be flattened also MethodHandle invoker = basicInvoker; if (invoker != null) return invoker; - invoker = basicType.invokers().makeBasicInvoker(); + invoker = DirectMethodHandle.make(invokeBasicMethod(basicType)); basicInvoker = invoker; return invoker; } + // This next one is called from LambdaForm.NamedFunction.. + /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) { + assert(basicType == basicType.basicType()); + try { + // Do approximately the same as this public API call: + // Lookup.findVirtual(MethodHandle.class, name, type); + // But bypass access and corner case checks, since we know exactly what we need. + return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, "invokeBasic", basicType); + } catch (ReflectiveOperationException ex) { + throw newInternalError("JVM cannot find invoker for "+basicType, ex); + } + } + /** * Build an MTF for a given type, which must have all references erased to Object. * This MTF will stand for that type and all un-erased variations. From 622186edcb3211392e4e4558e960134636ac12b7 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:38 -0700 Subject: [PATCH 274/293] 8001105: findVirtual of Object[].clone produces internal error Replicate JVM logic for access control that makes Object.clone appear public when applied to an array type. Reviewed-by: twisti --- .../java/lang/invoke/MethodHandles.java | 20 +++++++ .../java/lang/invoke/MethodHandlesTest.java | 58 +++++++++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index a4f217f5a51..730c30e7162 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -1204,6 +1204,26 @@ return mh1; int allowedModes = this.allowedModes; if (allowedModes == TRUSTED) return; int mods = m.getModifiers(); + if (Modifier.isProtected(mods) && + refKind == REF_invokeVirtual && + m.getDeclaringClass() == Object.class && + m.getName().equals("clone") && + refc.isArray()) { + // The JVM does this hack also. + // (See ClassVerifier::verify_invoke_instructions + // and LinkResolver::check_method_accessability.) + // Because the JVM does not allow separate methods on array types, + // there is no separate method for int[].clone. + // All arrays simply inherit Object.clone. + // But for access checking logic, we make Object.clone + // (normally protected) appear to be public. + // Later on, when the DirectMethodHandle is created, + // its leading argument will be restricted to the + // requested array type. + // N.B. The return type is not adjusted, because + // that is *not* the bytecode behavior. + mods ^= Modifier.PROTECTED | Modifier.PUBLIC; + } if (Modifier.isFinal(mods) && MethodHandleNatives.refKindIsSetter(refKind)) throw m.makeAccessException("unexpected set of a final field", this); diff --git a/jdk/test/java/lang/invoke/MethodHandlesTest.java b/jdk/test/java/lang/invoke/MethodHandlesTest.java index d7e3626d55c..092eeb4eeda 100644 --- a/jdk/test/java/lang/invoke/MethodHandlesTest.java +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java @@ -140,7 +140,7 @@ public class MethodHandlesTest { Object actual = calledLog.get(calledLog.size() - 1); if (expected.equals(actual) && verbosity < 9) return; System.out.println("assertCalled "+name+":"); - System.out.println("expected: "+expected); + System.out.println("expected: "+deepToString(expected)); System.out.println("actual: "+actual); System.out.println("ex. types: "+getClasses(expected)); System.out.println("act. types: "+getClasses(actual)); @@ -148,7 +148,25 @@ public class MethodHandlesTest { } static void printCalled(MethodHandle target, String name, Object... args) { if (verbosity >= 3) - System.out.println("calling MH="+target+" to "+name+Arrays.toString(args)); + System.out.println("calling MH="+target+" to "+name+deepToString(args)); + } + static String deepToString(Object x) { + if (x == null) return "null"; + if (x instanceof Collection) + x = ((Collection)x).toArray(); + if (x instanceof Object[]) { + Object[] ax = (Object[]) x; + ax = Arrays.copyOf(ax, ax.length, Object[].class); + for (int i = 0; i < ax.length; i++) + ax[i] = deepToString(ax[i]); + x = Arrays.deepToString(ax); + } + if (x.getClass().isArray()) + try { + x = Arrays.class.getMethod("toString", x.getClass()).invoke(null, x); + } catch (ReflectiveOperationException ex) { throw new Error(ex); } + assert(!(x instanceof Object[])); + return x.toString(); } static Object castToWrapper(Object value, Class dst) { @@ -230,6 +248,12 @@ public class MethodHandlesTest { { param = c; break; } } } + if (param.isArray()) { + Class ctype = param.getComponentType(); + Object arg = Array.newInstance(ctype, 2); + Array.set(arg, 0, randomArg(ctype)); + return arg; + } if (param.isInterface() && param.isAssignableFrom(List.class)) return Arrays.asList("#"+nextArg()); if (param.isInterface() || param.isAssignableFrom(String.class)) @@ -568,6 +592,16 @@ public class MethodHandlesTest { testFindVirtual(IntExample.Impl.class, IntExample.class, void.class, "Int/v0"); } + @Test + public void testFindVirtualClone() throws Throwable { + // test some ad hoc system methods + testFindVirtual(false, PUBLIC, Object.class, Object.class, "clone"); + testFindVirtual(true, PUBLIC, Object[].class, Object.class, "clone"); + testFindVirtual(true, PUBLIC, int[].class, Object.class, "clone"); + for (Class cls : new Class[]{ boolean[].class, long[].class, float[].class, char[].class }) + testFindVirtual(true, PUBLIC, cls, Object.class, "clone"); + } + void testFindVirtual(Class defc, Class ret, String name, Class... params) throws Throwable { Class rcvc = defc; testFindVirtual(rcvc, defc, ret, name, params); @@ -580,6 +614,9 @@ public class MethodHandlesTest { void testFindVirtual(Lookup lookup, Class rcvc, Class defc, Class ret, String name, Class... params) throws Throwable { testFindVirtual(true, lookup, rcvc, defc, ret, name, params); } + void testFindVirtual(boolean positive, Lookup lookup, Class defc, Class ret, String name, Class... params) throws Throwable { + testFindVirtual(positive, lookup, defc, defc, ret, name, params); + } void testFindVirtual(boolean positive, Lookup lookup, Class rcvc, Class defc, Class ret, String name, Class... params) throws Throwable { countTest(positive); String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo @@ -618,8 +655,21 @@ public class MethodHandlesTest { Object[] argsWithSelf = randomArgs(paramsWithSelf); if (selfc.isAssignableFrom(rcvc) && rcvc != selfc) argsWithSelf[0] = randomArg(rcvc); printCalled(target, name, argsWithSelf); - target.invokeWithArguments(argsWithSelf); - assertCalled(name, argsWithSelf); + Object res = target.invokeWithArguments(argsWithSelf); + if (Example.class.isAssignableFrom(defc) || IntExample.class.isAssignableFrom(defc)) { + assertCalled(name, argsWithSelf); + } else if (name.equals("clone")) { + // Ad hoc method call outside Example. For Object[].clone. + printCalled(target, name, argsWithSelf); + assertEquals(MethodType.methodType(Object.class, rcvc), target.type()); + Object orig = argsWithSelf[0]; + assertEquals(orig.getClass(), res.getClass()); + if (res instanceof Object[]) + assertArrayEquals((Object[])res, (Object[])argsWithSelf[0]); + assert(Arrays.deepEquals(new Object[]{res}, new Object[]{argsWithSelf[0]})); + } else { + assert(false) : Arrays.asList(positive, lookup, rcvc, defc, ret, name, deepToString(params)); + } if (verbosity >= 1) System.out.print(':'); } From 77dc59f6caba016234c7e7c7bc7298adc5a9e9df Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:39 -0700 Subject: [PATCH 275/293] 8019417: JSR 292 javadoc should clarify method handle arity limits Clarification of erroneous reading of spec. that led to 7194534 Reviewed-by: twisti, darcy --- .../java/lang/invoke/MethodHandle.java | 30 +++- .../java/lang/invoke/MethodHandles.java | 19 ++- jdk/test/java/lang/invoke/BigArityTest.java | 155 ++++++++++++++++-- 3 files changed, 181 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index 25bb5e58537..7bfce2d7711 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -392,7 +392,7 @@ mh.invokeExact(System.out, "Hello, world."); * Java types. *

      *
    • Method types range over all possible arities, - * from no arguments to up to 255 of arguments (a limit imposed by the JVM). + * from no arguments to up to the maximum number of allowed arguments. * Generics are not variadic, and so cannot represent this.
    • *
    • Method types can specify arguments of primitive types, * which Java generic types cannot range over.
    • @@ -402,6 +402,22 @@ mh.invokeExact(System.out, "Hello, world."); * genericity with a Java type parameter. *
    * + *

    Arity limits

    + * The JVM imposes on all methods and constructors of any kind an absolute + * limit of 255 stacked arguments. This limit can appear more restrictive + * in certain cases: + *
      + *
    • A {@code long} or {@code double} argument counts (for purposes of arity limits) as two argument slots. + *
    • A non-static method consumes an extra argument for the object on which the method is called. + *
    • A constructor consumes an extra argument for the object which is being constructed. + *
    • Since a method handle’s {@code invoke} method (or other signature-polymorphic method) is non-virtual, + * it consumes an extra argument for the method handle itself, in addition to any non-virtual receiver object. + *
    + * These limits imply that certain method handles cannot be created, solely because of the JVM limit on stacked arguments. + * For example, if a static JVM method accepts exactly 255 arguments, a method handle cannot be created for it. + * Attempts to create method handles with impossible method types lead to an {@link IllegalArgumentException}. + * In particular, a method handle’s type must not have an arity of the exact maximum 255. + * * @see MethodType * @see MethodHandles * @author John Rose, JSR 292 EG @@ -831,10 +847,12 @@ assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray * @return a new method handle which spreads its final array argument, * before calling the original method handle * @throws NullPointerException if {@code arrayType} is a null reference - * @throws IllegalArgumentException if {@code arrayType} is not an array type - * @throws IllegalArgumentException if target does not have at least + * @throws IllegalArgumentException if {@code arrayType} is not an array type, + * or if target does not have at least * {@code arrayLength} parameter types, - * or if {@code arrayLength} is negative + * or if {@code arrayLength} is negative, + * or if the resulting method handle's type would have + * too many parameters * @throws WrongMethodTypeException if the implied {@code asType} call fails * @see #asCollector */ @@ -947,7 +965,9 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123)); * @throws NullPointerException if {@code arrayType} is a null reference * @throws IllegalArgumentException if {@code arrayType} is not an array type * or {@code arrayType} is not assignable to this method handle's trailing parameter type, - * or {@code arrayLength} is not a legal array size + * or {@code arrayLength} is not a legal array size, + * or the resulting method handle's type would have + * too many parameters * @throws WrongMethodTypeException if the implied {@code asType} call fails * @see #asSpreader * @see #asVarargsCollector diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 730c30e7162..663dfb58c1f 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -245,6 +245,10 @@ public class MethodHandles { * on various grounds (see below). * By contrast, the {@code ldc} instruction is not subject to * security manager checks. + *
  • If the looked-up method has a + * very large arity, + * the method handle creation may fail, due to the method handle + * type having too many parameters. * * *

    Access checking

    @@ -1522,7 +1526,9 @@ return invoker; * @return a method handle suitable for invoking any method handle of the given type * @throws NullPointerException if {@code type} is null * @throws IllegalArgumentException if {@code leadingArgCount} is not in - * the range from 0 to {@code type.parameterCount()} inclusive + * the range from 0 to {@code type.parameterCount()} inclusive, + * or if the resulting method handle's type would have + * too many parameters */ static public MethodHandle spreadInvoker(MethodType type, int leadingArgCount) { @@ -1565,6 +1571,8 @@ publicLookup().findVirtual(MethodHandle.class, "invokeExact", type) * This method throws no reflective or security exceptions. * @param type the desired target type * @return a method handle suitable for invoking any method handle of the given type + * @throws IllegalArgumentException if the resulting method handle's type would have + * too many parameters */ static public MethodHandle exactInvoker(MethodType type) { @@ -1598,6 +1606,8 @@ publicLookup().findVirtual(MethodHandle.class, "invoke", type) * This method throws no reflective or security exceptions. * @param type the desired target type * @return a method handle suitable for invoking any method handle convertible to the given type + * @throws IllegalArgumentException if the resulting method handle's type would have + * too many parameters */ static public MethodHandle invoker(MethodType type) { @@ -1966,7 +1976,8 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z")); * or if the {@code valueTypes} array or any of its elements is null * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class}, * or if {@code pos} is negative or greater than the arity of the target, - * or if the new method handle's type would have too many parameters + * or if the new method handle's type would have + * too many parameters */ public static MethodHandle dropArguments(MethodHandle target, int pos, Class... valueTypes) { @@ -2034,7 +2045,9 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY * or if the {@code filters} array is null * @throws IllegalArgumentException if a non-null element of {@code filters} * does not match a corresponding argument type of target as described above, - * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()} + * or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}, + * or if the resulting method handle's type would have + * too many parameters */ public static MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) { diff --git a/jdk/test/java/lang/invoke/BigArityTest.java b/jdk/test/java/lang/invoke/BigArityTest.java index d9584dd6196..3744bf9443f 100644 --- a/jdk/test/java/lang/invoke/BigArityTest.java +++ b/jdk/test/java/lang/invoke/BigArityTest.java @@ -92,6 +92,65 @@ public class BigArityTest { return args; } + @Test + public void asCollectorIAE01() throws ReflectiveOperationException { + final int [] INVALID_ARRAY_LENGTHS = { + Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -2, -1, 255, 256, Integer.MAX_VALUE - 1, Integer.MAX_VALUE + }; + MethodHandle target = MethodHandles.publicLookup().findStatic(Arrays.class, + "deepToString", MethodType.methodType(String.class, Object[].class)); + int minbig = Integer.MAX_VALUE; + for (int invalidLength : INVALID_ARRAY_LENGTHS) { + if (minbig > invalidLength && invalidLength > 100) minbig = invalidLength; + try { + target.asCollector(Object[].class, invalidLength); + assert(false) : invalidLength; + } catch (IllegalArgumentException ex) { + System.out.println("OK: "+ex); + } + } + // Sizes not in the above array are good: + target.asCollector(Object[].class, minbig-1); + for (int i = 2; i <= 10; i++) + target.asCollector(Object[].class, minbig-i); + } + + @Test + public void invoker02() { + for (int i = 0; i < 255; i++) { + MethodType mt = MethodType.genericMethodType(i); + MethodType expMT = mt.insertParameterTypes(0, MethodHandle.class); + if (i < 254) { + assertEquals(expMT, MethodHandles.invoker(mt).type()); + } else { + try { + MethodHandles.invoker(mt); + assert(false) : i; + } catch (IllegalArgumentException ex) { + System.out.println("OK: "+ex); + } + } + } + } + + @Test + public void exactInvoker02() { + for (int i = 0; i < 255; i++) { + MethodType mt = MethodType.genericMethodType(i); + MethodType expMT = mt.insertParameterTypes(0, MethodHandle.class); + if (i < 254) { + assertEquals(expMT, MethodHandles.exactInvoker(mt).type()); + } else { + try { + MethodHandles.exactInvoker(mt); + assert(false) : i; + } catch (IllegalArgumentException ex) { + System.out.println("OK: "+ex); + } + } + } + } + @Test public void testBoundaryValues() throws Throwable { for (int badArity : new int[]{ -1, MAX_JVM_ARITY+1, MAX_JVM_ARITY }) { @@ -102,6 +161,37 @@ public class BigArityTest { System.out.println("OK: "+ex); } } + final int MAX_MH_ARITY = MAX_JVM_ARITY - 1; // mh.invoke(arg*[N]) + final int MAX_INVOKER_ARITY = MAX_MH_ARITY - 1; // inv.invoke(mh, arg*[N]) + for (int arity : new int[]{ 0, 1, MAX_MH_ARITY-2, MAX_MH_ARITY-1, MAX_MH_ARITY }) { + MethodHandle mh = MH_hashArguments(arity); + if (arity < MAX_INVOKER_ARITY) { + MethodHandle ximh = MethodHandles.exactInvoker(mh.type()); + MethodHandle gimh = MethodHandles.invoker(mh.type()); + MethodHandle simh = MethodHandles.spreadInvoker(mh.type(), 0); + if (arity != 0) { + simh = MethodHandles.spreadInvoker(mh.type(), 1); + } else { + try { + simh = MethodHandles.spreadInvoker(mh.type(), 1); + assert(false) : arity; + } catch (IllegalArgumentException ex) { + System.out.println("OK: "+ex); + } + } + if (arity != 0) { + simh = MethodHandles.spreadInvoker(mh.type(), arity-1); + } else { + try { + simh = MethodHandles.spreadInvoker(mh.type(), arity-1); + assert(false) : arity; + } catch (IllegalArgumentException ex) { + System.out.println("OK: "+ex); + } + } + simh = MethodHandles.spreadInvoker(mh.type(), arity); + } + } } // Make sure the basic argument spreading and varargs mechanisms are working. @@ -133,7 +223,7 @@ public class BigArityTest { if (cls == Object[].class) r = smh.invokeExact(tail); else if (cls == Integer[].class) - r = smh.invokeExact((Integer[]) tail); + r = smh.invokeExact((Integer[]) tail); //warning OK, see 8019340 else r = smh.invoke(tail); assertEquals(r0, r); @@ -235,21 +325,41 @@ public class BigArityTest { MethodHandle mh_VA = mh.asSpreader(cls, arity); assert(mh_VA.type().parameterType(0) == cls); testArities(cls, arity, iterations, verbose, mh, mh_VA); + // mh_CA will collect arguments of a particular type and pass them to mh_VA + MethodHandle mh_CA = mh_VA.asCollector(cls, arity); + MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity); + assert(mh_CA.type().equals(mh.type())); + assert(mh_VA2.type().equals(mh_VA.type())); if (cls != Object[].class) { - // mh_CA will collect arguments of a particular type and pass them to mh_VA - MethodHandle mh_CA = mh_VA.asCollector(cls, arity); - MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity); try { mh_VA2.invokeWithArguments(new Object[arity]); throw new AssertionError("should not reach"); } catch (ClassCastException | WrongMethodTypeException ex) { } - assert(mh_CA.type().equals(mh.type())); - assert(mh_VA2.type().equals(mh_VA.type())); - testArities(cls, arity, iterations, false, mh_CA, mh_VA2); } + int iterations_VA = iterations / 100; + testArities(cls, arity, iterations_VA, false, mh_CA, mh_VA2); } } + + /** + * Tests calls to {@link BigArityTest#hashArguments hashArguments} as related to a single given arity N. + * Applies the given {@code mh} to a set of N integer arguments, checking the answer. + * Also applies the varargs variation {@code mh_VA} to an array of type C[] (given by {@code cls}). + * Test steps: + *
      + *
    • mh_VA.invokeExact(new C[]{ arg, ... })
    • + *
    • mh.invokeWithArguments((Object[]) new C[]{ arg, ... })
    • + *
    • exactInvoker(mh.type()).invokeWithArguments(new Object[]{ mh, arg, ... })
    • + *
    • invoker(mh.type()).invokeWithArguments(new Object[]{ mh, arg, ... })
    • + *
    + * @param cls array type for varargs call (one of Object[], Number[], Integer[], Comparable[]) + * @param arity N, the number of arguments to {@code mh} and length of its varargs array, in [0..255] + * @param iterations number of times to repeat each test step (at least 4) + * @param verbose are we printing extra output? + * @param mh a fixed-arity version of {@code hashArguments} + * @param mh_VA a variable-arity version of {@code hashArguments}, accepting the given array type {@code cls} + */ private void testArities(Class cls, int arity, int iterations, @@ -292,7 +402,7 @@ public class BigArityTest { if (cls == Object[].class) r = mh_VA.invokeExact(args); else if (cls == Integer[].class) - r = mh_VA.invokeExact((Integer[])args); + r = mh_VA.invokeExact((Integer[])args); //warning OK, see 8019340 else r = mh_VA.invoke(args); assertEquals(r0, r); @@ -392,10 +502,16 @@ public class BigArityTest { a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF], a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7], // - a[0xF8], a[0xF9], a[0xFA], a[0xFB]); + a[0xF8], a[0xF9], a[0xFA], a[0xFB]); // hashArguments_252 assertEquals(r0, r); MethodType mt = MethodType.genericMethodType(ARITY); MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt); + test252(mh, a, r0); + MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY); + test252(mh_CA, a, r0); + } + public void test252(MethodHandle mh, Object[] a, Object r0) throws Throwable { + Object r; r = mh.invokeExact( // a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F], @@ -599,10 +715,16 @@ public class BigArityTest { a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF], a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7], // - a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]); + a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]); // hashArguments_253 assertEquals(r0, r); MethodType mt = MethodType.genericMethodType(ARITY); MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt); + test253(mh, a, r0); + MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY); + test253(mh_CA, a, r0); + } + public void test253(MethodHandle mh, Object[] a, Object r0) throws Throwable { + Object r; r = mh.invokeExact( // a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F], @@ -648,7 +770,6 @@ public class BigArityTest { // a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]); assertEquals(r0, r); - // FIXME: This next one fails, because it uses an internal invoker of arity 255. r = ximh.invokeWithArguments(cat(mh,a)); assertEquals(r0, r); MethodHandle gimh = MethodHandles.invoker(mh.type()); @@ -674,7 +795,6 @@ public class BigArityTest { // a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]); assertEquals(r0, r); - // FIXME: This next one fails, because it uses an internal invoker of arity 255. r = gimh.invokeWithArguments(cat(mh,a)); assertEquals(r0, r); mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class)); @@ -808,10 +928,16 @@ public class BigArityTest { a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF], a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7], // - a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]); + a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]); // hashArguments_254 assertEquals(r0, r); MethodType mt = MethodType.genericMethodType(ARITY); MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt); + test254(mh, a, r0); + MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY); + test254(mh_CA, a, r0); + } + public void test254(MethodHandle mh, Object[] a, Object r0) throws Throwable { + Object r; r = mh.invokeExact( // a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F], @@ -833,7 +959,6 @@ public class BigArityTest { // a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]); assertEquals(r0, r); - // FIXME: This next one fails, because it uses an internal invoker of arity 255. r = mh.invokeWithArguments(a); assertEquals(r0, r); try { @@ -998,7 +1123,7 @@ public class BigArityTest { a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF], a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7], // - a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]); + a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]); // hashArguments_255 assertEquals(r0, r); MethodType mt = MethodType.genericMethodType(ARITY); MethodHandle mh; From e4df9dc1eeca2c217705f9801fe227d47d0a6b94 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:39 -0700 Subject: [PATCH 276/293] 8001109: arity mismatch on a call to spreader method handle should elicit IllegalArgumentException Document error conditions that may occur when calling a "spreader" method handle. Use IAE in all cases. Reviewed-by: twisti, vlivanov --- .../share/classes/java/lang/invoke/MethodHandle.java | 10 ++++++++++ .../classes/java/lang/invoke/MethodHandleImpl.java | 10 +--------- .../share/classes/java/lang/invoke/MethodHandles.java | 3 +++ jdk/test/java/lang/invoke/JavaDocExamplesTest.java | 6 ++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index 7bfce2d7711..79e9617094e 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -804,6 +804,10 @@ public abstract class MethodHandle { * to the target method handle. * (The array may also be null when zero elements are required.) *

    + * If, when the adapter is called, the supplied array argument does + * not have the correct number of elements, the adapter will throw + * an {@link IllegalArgumentException} instead of invoking the target. + *

    * Here are some simple examples of array-spreading method handles: *

    {@code
     MethodHandle equals = publicLookup()
    @@ -814,6 +818,12 @@ assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
     MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
     assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
     assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
    +// try to spread from anything but a 2-array:
    +for (int n = 0; n <= 10; n++) {
    +  Object[] badArityArgs = (n == 2 ? null : new Object[n]);
    +  try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
    +  catch (IllegalArgumentException ex) { } // OK
    +}
     // spread both arguments from a String array:
     MethodHandle eq2s = equals.asSpreader(String[].class, 2);
     assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
    diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
    index f5fc1b7a707..b25c0d847db 100644
    --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
    +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
    @@ -460,14 +460,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
         }
     
         static void checkSpreadArgument(Object av, int n) {
    -        // FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE
    -        // but the actual exception raised by an arity mismatch should be WMTE
    -        final boolean RAISE_RANDOM_EXCEPTIONS = true;  // FIXME: delete in JSR 292 M1
             if (av == null) {
                 if (n == 0)  return;
    -            int len;
    -            if (RAISE_RANDOM_EXCEPTIONS)
    -                len = ((Object[])av).length;  // throw NPE; but delete this after tests are fixed
             } else if (av instanceof Object[]) {
                 int len = ((Object[])av).length;
                 if (len == n)  return;
    @@ -476,9 +470,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
                 if (len == n)  return;
             }
             // fall through to error:
    -        if (RAISE_RANDOM_EXCEPTIONS)
    -            throw newIllegalArgumentException("Array is not of length "+n);
    -        throw new WrongMethodTypeException("Array is not of length "+n);
    +        throw newIllegalArgumentException("array is not of length "+n);
         }
     
         /**
    diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
    index 663dfb58c1f..60fa6de5674 100644
    --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
    +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
    @@ -1511,6 +1511,9 @@ return mh1;
          * 

    * Before invoking its target, the invoker will spread the final array, apply * reference casts as necessary, and unbox and widen primitive arguments. + * If, when the invoker is called, the supplied array argument does + * not have the correct number of elements, the invoker will throw + * an {@link IllegalArgumentException} instead of invoking the target. *

    * This method is equivalent to the following code (though it may be more efficient): *

    diff --git a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
    index 0de2015ea94..b75b8c471a0 100644
    --- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
    +++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
    @@ -264,6 +264,12 @@ assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
     MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
     assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
     assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
    +// try to spread from anything but a 2-array:
    +for (int n = 0; n <= 10; n++) {
    +  Object[] badArityArgs = (n == 2 ? null : new Object[n]);
    +  try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
    +  catch (IllegalArgumentException ex) { } // OK
    +}
     // spread both arguments from a String array:
     MethodHandle eq2s = equals.asSpreader(String[].class, 2);
     assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
    
    From 154969a2bc0435a8e891f7f22dce4aee2285437a Mon Sep 17 00:00:00 2001
    From: John R Rose 
    Date: Sat, 5 Oct 2013 05:30:39 -0700
    Subject: [PATCH 277/293] 8001108: an attempt to use "" as a method name
     should elicit NoSuchMethodException
    
    Add an explicit check for leading "<", upgrade the unit tests
    
    Reviewed-by: twisti, darcy
    ---
     .../java/lang/invoke/MethodHandles.java       | 115 +++++++++++++++++-
     .../java/lang/invoke/JavaDocExamplesTest.java |  93 +++++++++++++-
     .../java/lang/invoke/MethodHandlesTest.java   |  90 +++++++++-----
     3 files changed, 265 insertions(+), 33 deletions(-)
    
    diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
    index 60fa6de5674..627e4684907 100644
    --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
    +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
    @@ -289,6 +289,9 @@ public class MethodHandles {
          * In general, the conditions under which a method handle may be
          * looked up for a method {@code M} are exactly equivalent to the conditions
          * under which the lookup class could have compiled and resolved a call to {@code M}.
    +     * Where the JVM would raise exceptions like {@code NoSuchMethodError},
    +     * a method handle lookup will generally raise a corresponding
    +     * checked exception, such as {@code NoSuchMethodException}.
          * And the effect of invoking the method handle resulting from the lookup
          * is exactly equivalent to executing the compiled and resolved call to {@code M}.
          * The same point is true of fields and constructors.
    @@ -305,6 +308,12 @@ public class MethodHandles {
          * (which will necessarily be a superclass of the lookup class)
          * to the lookup class itself.
          * 

    + * The JVM represents constructors and static initializer blocks as internal methods + * with special names ({@code ""} and {@code ""}). + * The internal syntax of invocation instructions allows them to refer to such internal + * methods as if they were normal methods, but the JVM bytecode verifier rejects them. + * A lookup of such an internal method will produce a {@code NoSuchMethodException}. + *

    * In some cases, access between nested classes is obtained by the Java compiler by creating * an wrapper method to access a private method of another class * in the same top-level declaration. @@ -604,6 +613,15 @@ public class MethodHandles { * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + * Example: + *

    {@code
    +import static java.lang.invoke.MethodHandles.*;
    +import static java.lang.invoke.MethodType.*;
    +...
    +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
    +  "asList", methodType(List.class, Object[].class));
    +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
    +         * }
    * @param refc the class from which the method is accessed * @param name the name of the method * @param type the type of the method @@ -654,6 +672,34 @@ public class MethodHandles { * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker} * with the same {@code type} argument. * + * Example: + *

    {@code
    +import static java.lang.invoke.MethodHandles.*;
    +import static java.lang.invoke.MethodType.*;
    +...
    +MethodHandle MH_concat = publicLookup().findVirtual(String.class,
    +  "concat", methodType(String.class, String.class));
    +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
    +  "hashCode", methodType(int.class));
    +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
    +  "hashCode", methodType(int.class));
    +assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
    +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
    +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
    +// interface method:
    +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
    +  "subSequence", methodType(CharSequence.class, int.class, int.class));
    +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
    +// constructor "internal method" must be accessed differently:
    +MethodType MT_newString = methodType(void.class); //()V for new String()
    +try { assertEquals("impossible", lookup()
    +        .findVirtual(String.class, "", MT_newString));
    + } catch (NoSuchMethodException ex) { } // OK
    +MethodHandle MH_newString = publicLookup()
    +  .findConstructor(String.class, MT_newString);
    +assertEquals("", (String) MH_newString.invokeExact());
    +         * }
    + * * @param refc the class or interface from which the method is accessed * @param name the name of the method * @param type the type of the method, with the receiver argument omitted @@ -696,12 +742,30 @@ public class MethodHandles { * If the constructor's class has not yet been initialized, that is done * immediately, before the method handle is returned. *

    - * Note: The requested type must have a return type of {@code void}. - * This is consistent with the JVM's treatment of constructor type descriptors. + * (Note: The requested type must have a return type of {@code void}. + * This is consistent with the JVM's treatment of constructor type descriptors.) *

    * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the constructor's variable arity modifier bit ({@code 0x0080}) is set. + *

    Example: + *

    {@code
    +import static java.lang.invoke.MethodHandles.*;
    +import static java.lang.invoke.MethodType.*;
    +...
    +MethodHandle MH_newArrayList = publicLookup().findConstructor(
    +  ArrayList.class, methodType(void.class, Collection.class));
    +Collection orig = Arrays.asList("x", "y");
    +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
    +assert(orig != copy);
    +assertEquals(orig, copy);
    +// a variable-arity constructor:
    +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
    +  ProcessBuilder.class, methodType(void.class, String[].class));
    +ProcessBuilder pb = (ProcessBuilder)
    +  MH_newProcessBuilder.invoke("x", "y", "z");
    +assertEquals("[x, y, z]", pb.command().toString());
    +         * }
    * @param refc the class or interface from which the method is accessed * @param type the type of the method, with the receiver argument omitted, and a void return type * @return the desired method handle @@ -741,6 +805,45 @@ public class MethodHandles { * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + *

    + * (Note: JVM internal methods named {@code ""} are not visible to this API, + * even though the {@code invokespecial} instruction can refer to them + * in special circumstances. Use {@link #findConstructor findConstructor} + * to access instance initialization methods in a safe manner.) + *

    Example: + *

    {@code
    +import static java.lang.invoke.MethodHandles.*;
    +import static java.lang.invoke.MethodType.*;
    +...
    +static class Listie extends ArrayList {
    +  public String toString() { return "[wee Listie]"; }
    +  static Lookup lookup() { return MethodHandles.lookup(); }
    +}
    +...
    +// no access to constructor via invokeSpecial:
    +MethodHandle MH_newListie = Listie.lookup()
    +  .findConstructor(Listie.class, methodType(void.class));
    +Listie l = (Listie) MH_newListie.invokeExact();
    +try { assertEquals("impossible", Listie.lookup().findSpecial(
    +        Listie.class, "", methodType(void.class), Listie.class));
    + } catch (NoSuchMethodException ex) { } // OK
    +// access to super and self methods via invokeSpecial:
    +MethodHandle MH_super = Listie.lookup().findSpecial(
    +  ArrayList.class, "toString" , methodType(String.class), Listie.class);
    +MethodHandle MH_this = Listie.lookup().findSpecial(
    +  Listie.class, "toString" , methodType(String.class), Listie.class);
    +MethodHandle MH_duper = Listie.lookup().findSpecial(
    +  Object.class, "toString" , methodType(String.class), Listie.class);
    +assertEquals("[]", (String) MH_super.invokeExact(l));
    +assertEquals(""+l, (String) MH_this.invokeExact(l));
    +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
    +try { assertEquals("inaccessible", Listie.lookup().findSpecial(
    +        String.class, "toString", methodType(String.class), Listie.class));
    + } catch (IllegalAccessException ex) { } // OK
    +Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
    +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
    +         * }
    + * * @param refc the class or interface from which the method is accessed * @param name the name of the method (which must not be "<init>") * @param type the type of the method, with the receiver argument omitted @@ -1105,6 +1208,7 @@ return mh1; checkSymbolicClass(refc); // do this before attempting to resolve name.getClass(); // NPE type.getClass(); // NPE + checkMethodName(refKind, name); // NPE check on name return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchMethodException.class); } @@ -1124,6 +1228,13 @@ return mh1; throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); } + /** Check name for an illegal leading "<" character. */ + void checkMethodName(byte refKind, String name) throws NoSuchMethodException { + if (name.startsWith("<") && refKind != REF_newInvokeSpecial) + throw new NoSuchMethodException("illegal method name: "+name); + } + + /** * Find my trustable caller class if m is a caller sensitive method. * If this lookup object has private access, then the caller class is the lookupClass. diff --git a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java index b75b8c471a0..982bfe90054 100644 --- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java +++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java @@ -53,7 +53,11 @@ public class JavaDocExamplesTest { } public void run() throws Throwable { + testMisc(); + testFindStatic(); + testFindConstructor(); testFindVirtual(); + testFindSpecial(); testPermuteArguments(); testDropArguments(); testFilterArguments(); @@ -99,7 +103,8 @@ static { {} - @Test public void testFindVirtual() throws Throwable { + @Test public void testMisc() throws Throwable { +// Extra tests, not from javadoc: {} MethodHandle CONCAT_3 = LOOKUP.findVirtual(String.class, "concat", methodType(String.class, String.class)); @@ -114,6 +119,92 @@ assertEquals("xy".hashCode(), (int) HASHCODE_3.invokeExact((Object)"xy")); {} } + @Test public void testFindStatic() throws Throwable { +{} +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class, + "asList", methodType(List.class, Object[].class)); +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); +{} + } + + @Test public void testFindVirtual() throws Throwable { +{} +MethodHandle MH_concat = publicLookup().findVirtual(String.class, + "concat", methodType(String.class, String.class)); +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class, + "hashCode", methodType(int.class)); +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class, + "hashCode", methodType(int.class)); +assertEquals("xy", (String) MH_concat.invokeExact("x", "y")); +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy")); +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy")); +// interface method: +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class, + "subSequence", methodType(CharSequence.class, int.class, int.class)); +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString()); +// constructor "internal method" must be accessed differently: +MethodType MT_newString = methodType(void.class); //()V for new String() +try { assertEquals("impossible", lookup() + .findVirtual(String.class, "", MT_newString)); + } catch (NoSuchMethodException ex) { } // OK +MethodHandle MH_newString = publicLookup() + .findConstructor(String.class, MT_newString); +assertEquals("", (String) MH_newString.invokeExact()); +{} + } + + @Test public void testFindConstructor() throws Throwable { +{} +MethodHandle MH_newArrayList = publicLookup().findConstructor( + ArrayList.class, methodType(void.class, Collection.class)); +Collection orig = Arrays.asList("x", "y"); +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig); +assert(orig != copy); +assertEquals(orig, copy); +// a variable-arity constructor: +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor( + ProcessBuilder.class, methodType(void.class, String[].class)); +ProcessBuilder pb = (ProcessBuilder) + MH_newProcessBuilder.invoke("x", "y", "z"); +assertEquals("[x, y, z]", pb.command().toString()); +{} + } + +// for testFindSpecial +{} +static class Listie extends ArrayList { + public String toString() { return "[wee Listie]"; } + static Lookup lookup() { return MethodHandles.lookup(); } +} +{} + + @Test public void testFindSpecial() throws Throwable { +{} +// no access to constructor via invokeSpecial: +MethodHandle MH_newListie = Listie.lookup() + .findConstructor(Listie.class, methodType(void.class)); +Listie l = (Listie) MH_newListie.invokeExact(); +try { assertEquals("impossible", Listie.lookup().findSpecial( + Listie.class, "", methodType(void.class), Listie.class)); + } catch (NoSuchMethodException ex) { } // OK +// access to super and self methods via invokeSpecial: +MethodHandle MH_super = Listie.lookup().findSpecial( + ArrayList.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_this = Listie.lookup().findSpecial( + Listie.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_duper = Listie.lookup().findSpecial( + Object.class, "toString" , methodType(String.class), Listie.class); +assertEquals("[]", (String) MH_super.invokeExact(l)); +assertEquals(""+l, (String) MH_this.invokeExact(l)); +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method +try { assertEquals("inaccessible", Listie.lookup().findSpecial( + String.class, "toString", methodType(String.class), Listie.class)); + } catch (IllegalAccessException ex) { } // OK +Listie subl = new Listie() { public String toString() { return "[subclass]"; } }; +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method +{} + } + @Test public void testPermuteArguments() throws Throwable { {{ {} /// JAVADOC diff --git a/jdk/test/java/lang/invoke/MethodHandlesTest.java b/jdk/test/java/lang/invoke/MethodHandlesTest.java index 092eeb4eeda..b77f74e3d26 100644 --- a/jdk/test/java/lang/invoke/MethodHandlesTest.java +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java @@ -387,6 +387,7 @@ public class MethodHandlesTest { protected Example(String name) { this.name = name; } @SuppressWarnings("LeakingThisInConstructor") protected Example(int x) { this(); called("protected ", this, x); } + //Example(Void x) { does not exist; lookup elicts NoSuchMethodException } @Override public String toString() { return name; } public void v0() { called("v0", this); } @@ -487,6 +488,9 @@ public class MethodHandlesTest { return lookup.in(defc); } + /** Is findVirtual (etc.) of "" supposed to elicit a NoSuchMethodException? */ + final static boolean INIT_REF_CAUSES_NSME = true; + @Test public void testFindStatic() throws Throwable { if (CAN_SKIP_WORKING) return; @@ -507,6 +511,8 @@ public class MethodHandlesTest { testFindStatic(Example.class, Object.class, "s7", float.class, double.class); testFindStatic(false, PRIVATE, Example.class, void.class, "bogus"); + testFindStatic(false, PRIVATE, Example.class, void.class, "", int.class); + testFindStatic(false, PRIVATE, Example.class, void.class, "", Void.class); testFindStatic(false, PRIVATE, Example.class, void.class, "v0"); } @@ -529,11 +535,12 @@ public class MethodHandlesTest { target = maybeMoveIn(lookup, defc).findStatic(defc, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findStatic "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target @@ -551,6 +558,13 @@ public class MethodHandlesTest { System.out.print(':'); } + static void assertExceptionClass(Class expected, + Throwable actual) { + if (expected.isInstance(actual)) return; + actual.printStackTrace(); + assertEquals(expected, actual.getClass()); + } + static final boolean DEBUG_METHOD_HANDLE_NAMES = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES"); // rough check of name string @@ -580,6 +594,8 @@ public class MethodHandlesTest { testFindVirtual(PubExample.class, void.class, "Pub/pro_v0"); testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "bogus"); + testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "", int.class); + testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "", Void.class); testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "s0"); // test dispatch @@ -628,11 +644,12 @@ public class MethodHandlesTest { target = maybeMoveIn(lookup, defc).findVirtual(defc, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findVirtual "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target @@ -682,11 +699,11 @@ public class MethodHandlesTest { testFindSpecial(SubExample.class, Example.class, void.class, "pkg_v0"); testFindSpecial(RemoteExample.class, PubExample.class, void.class, "Pub/pro_v0"); // Do some negative testing: - testFindSpecial(false, EXAMPLE, SubExample.class, Example.class, void.class, "bogus"); - testFindSpecial(false, PRIVATE, SubExample.class, Example.class, void.class, "bogus"); for (Lookup lookup : new Lookup[]{ PRIVATE, EXAMPLE, PACKAGE, PUBLIC }) { testFindSpecial(false, lookup, Object.class, Example.class, void.class, "v0"); + testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "bogus"); testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "", int.class); + testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "", Void.class); testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "s0"); } } @@ -712,19 +729,25 @@ public class MethodHandlesTest { countTest(positive); String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo MethodType type = MethodType.methodType(ret, params); + Lookup specialLookup = maybeMoveIn(lookup, specialCaller); + boolean specialAccessOK = (specialLookup.lookupClass() == specialCaller && + (specialLookup.lookupModes() & Lookup.PRIVATE) != 0); MethodHandle target = null; Exception noAccess = null; try { if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type); - if (verbosity >= 5) System.out.println(" lookup => "+maybeMoveIn(lookup, specialCaller)); - target = maybeMoveIn(lookup, specialCaller).findSpecial(defc, methodName, type, specialCaller); + if (verbosity >= 5) System.out.println(" lookup => "+specialLookup); + target = specialLookup.findSpecial(defc, methodName, type, specialCaller); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (!specialAccessOK) // this check should happen first + ? IllegalAccessException.class + : (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target @@ -769,7 +792,7 @@ public class MethodHandlesTest { target = lookup.findConstructor(defc, type); } catch (ReflectiveOperationException ex) { noAccess = ex; - assertTrue(noAccess instanceof IllegalAccessException); + assertTrue(noAccess.getClass().getName(), noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("findConstructor "+defc.getName()+"./"+type+" => "+target @@ -800,6 +823,8 @@ public class MethodHandlesTest { testBind(Example.class, Object.class, "v2", int.class, Object.class); testBind(Example.class, Object.class, "v2", int.class, int.class); testBind(false, PRIVATE, Example.class, void.class, "bogus"); + testBind(false, PRIVATE, Example.class, void.class, "", int.class); + testBind(false, PRIVATE, Example.class, void.class, "", Void.class); testBind(SubExample.class, void.class, "Sub/v0"); testBind(SubExample.class, void.class, "Sub/pkg_v0"); testBind(IntExample.Impl.class, void.class, "Int/v0"); @@ -823,11 +848,12 @@ public class MethodHandlesTest { target = maybeMoveIn(lookup, defc).bind(receiver, methodName, type); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("")) + ? NoSuchMethodException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("bind "+receiver+"."+name+"/"+type+" => "+target @@ -890,6 +916,10 @@ public class MethodHandlesTest { countTest(positive); String methodName = name.substring(1 + name.indexOf('/')); // foo/bar => foo MethodType type = MethodType.methodType(ret, params); + Lookup specialLookup = (specialCaller != null ? maybeMoveIn(lookup, specialCaller) : null); + boolean specialAccessOK = (specialCaller != null && + specialLookup.lookupClass() == specialCaller && + (specialLookup.lookupModes() & Lookup.PRIVATE) != 0); Method rmethod = defc.getDeclaredMethod(methodName, params); MethodHandle target = null; Exception noAccess = null; @@ -898,16 +928,15 @@ public class MethodHandlesTest { try { if (verbosity >= 4) System.out.println("lookup via "+lookup+" of "+defc+" "+name+type); if (isSpecial) - target = maybeMoveIn(lookup, specialCaller).unreflectSpecial(rmethod, specialCaller); + target = specialLookup.unreflectSpecial(rmethod, specialCaller); else target = maybeMoveIn(lookup, defc).unreflect(rmethod); } catch (ReflectiveOperationException ex) { noAccess = ex; + assertExceptionClass( + IllegalAccessException.class, // NSME is impossible, since it was already reflected + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (name.contains("bogus")) - assertTrue(noAccess instanceof NoSuchMethodException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("unreflect"+(isSpecial?"Special":"")+" "+defc.getName()+"."+name+"/"+type @@ -1141,11 +1170,12 @@ public class MethodHandlesTest { } catch (ReflectiveOperationException ex) { mh = null; noAccess = ex; + assertExceptionClass( + (fname.contains("bogus")) + ? NoSuchFieldException.class + : IllegalAccessException.class, + noAccess); if (verbosity >= 5) ex.printStackTrace(System.out); - if (fname.contains("bogus")) - assertTrue(noAccess instanceof NoSuchFieldException); - else - assertTrue(noAccess instanceof IllegalAccessException); } if (verbosity >= 3) System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype From 4ea5f818b56542ba5a43a82827aab757214ca718 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:39 -0700 Subject: [PATCH 278/293] 8024599: JSR 292 direct method handles need to respect initialization rules for static members Align MH semantic with bytecode behavior of constructor and static member accesses, regarding invocation. Reviewed-by: twisti, darcy, abuckley, vlivanov --- .../java/lang/invoke/MethodHandles.java | 33 ++- .../java/lang/invoke/CallStaticInitOrder.java | 275 ++++++++++++++++++ 2 files changed, 303 insertions(+), 5 deletions(-) create mode 100644 jdk/test/java/lang/invoke/CallStaticInitOrder.java diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 627e4684907..77a65385121 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -607,13 +607,14 @@ public class MethodHandles { * additional receiver argument inserted into the method handle type, * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.) * The method and all its argument types must be accessible to the lookup class. - * If the method's class has not yet been initialized, that is done - * immediately, before the method handle is returned. *

    * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. - * Example: + *

    + * If the returned method handle is invoked, the method's class will + * be initialized, if it has not already been initialized. + *

    Example: *

    {@code
     import static java.lang.invoke.MethodHandles.*;
     import static java.lang.invoke.MethodType.*;
    @@ -739,8 +740,6 @@ assertEquals("", (String) MH_newString.invokeExact());
              * The parameter types of the method handle will be those of the constructor,
              * while the return type will be a reference to the constructor's class.
              * The constructor and all its argument types must be accessible to the lookup class.
    -         * If the constructor's class has not yet been initialized, that is done
    -         * immediately, before the method handle is returned.
              * 

    * (Note: The requested type must have a return type of {@code void}. * This is consistent with the JVM's treatment of constructor type descriptors.) @@ -748,6 +747,9 @@ assertEquals("", (String) MH_newString.invokeExact()); * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the constructor's variable arity modifier bit ({@code 0x0080}) is set. + *

    + * If the returned method handle is invoked, the constructor's class will + * be initialized, if it has not already been initialized. *

    Example: *

    {@code
     import static java.lang.invoke.MethodHandles.*;
    @@ -918,6 +920,9 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
              * value type.
              * The method handle will take no arguments.
              * Access checking is performed immediately on behalf of the lookup class.
    +         * 

    + * If the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param refc the class or interface from which the method is accessed * @param name the field's name * @param type the field's type @@ -940,6 +945,9 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method * The method handle will take a single * argument, of the field's value type, the value to be stored. * Access checking is performed immediately on behalf of the lookup class. + *

    + * If the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param refc the class or interface from which the method is accessed * @param name the field's name * @param type the field's type @@ -1024,6 +1032,10 @@ return mh1; * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + *

    + * If m is static, and + * if the returned method handle is invoked, the method's class will + * be initialized, if it has not already been initialized. * @param m the reflected method * @return a method handle which can invoke the reflected method * @throws IllegalAccessException if access checking fails @@ -1095,6 +1107,9 @@ return mh1; * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the constructor's variable arity modifier bit ({@code 0x0080}) is set. + *

    + * If the returned method handle is invoked, the constructor's class will + * be initialized, if it has not already been initialized. * @param c the reflected constructor * @return a method handle which can invoke the reflected constructor * @throws IllegalAccessException if access checking fails @@ -1119,6 +1134,10 @@ return mh1; * the field. * If the field's {@code accessible} flag is not set, * access checking is performed immediately on behalf of the lookup class. + *

    + * If the field is static, and + * if the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param f the reflected field * @return a method handle which can load values from the reflected field * @throws IllegalAccessException if access checking fails @@ -1145,6 +1164,10 @@ return mh1; * the field, and the value to be stored. * If the field's {@code accessible} flag is not set, * access checking is performed immediately on behalf of the lookup class. + *

    + * If the field is static, and + * if the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param f the reflected field * @return a method handle which can store values into the reflected field * @throws IllegalAccessException if access checking fails diff --git a/jdk/test/java/lang/invoke/CallStaticInitOrder.java b/jdk/test/java/lang/invoke/CallStaticInitOrder.java new file mode 100644 index 00000000000..83808f8fb9f --- /dev/null +++ b/jdk/test/java/lang/invoke/CallStaticInitOrder.java @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @summary static initializer invocation order + * + * @build indify.Indify + * @compile CallStaticInitOrder.java + * @run main/othervm + * indify.Indify + * --expand-properties --classpath ${test.classes} + * --java test.java.lang.invoke.CallStaticInitOrder + */ + +package test.java.lang.invoke; + +import java.io.*; + +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; + +public class CallStaticInitOrder { + private static int TICK; + private static synchronized int tick(String event) { + int n = ++TICK; + System.out.println("event #"+n+" = "+event); + return n; + } + + static int Init1Tick; + private static class Init1 { + static { Init1Tick = tick("foo -> Init1."); } + static int foo() { return Init1Tick; } + } + + static int Init2Tick; + private static class Init2 { + static { Init2Tick = tick("bar -> Init2."); } + static int bar() { return Init2Tick; } + } + + static int Init3Tick; + private static class Init3 { + static { Init3Tick = tick("baz -> Init3."); } + static int baz() { return Init3Tick; } + } + + static int Init4Tick; + private static class Init4 { + static { Init4Tick = tick("bat -> Init4."); } + static int bat() { return Init4Tick; } + } + + static int Init5Tick; + private static class Init5 { + static { Init5Tick = tick("read bang -> Init5."); } + static int bang = Init5Tick; + } + + static int Init6Tick; + private static class Init6 { + static { Init6Tick = tick("write pong -> Init6."); } + static int pong; + } + + private static final MutableCallSite CONSTANT_CS_baz; + private static MethodHandle MH_foo() throws ReflectiveOperationException { + return lookup().findStatic(Init1.class, "foo", methodType(int.class)); + } + private static final MethodHandle CONSTANT_MH_bar; + private static MethodHandle MH_baz() throws ReflectiveOperationException { + return lookup().findStatic(Init3.class, "baz", methodType(int.class)); + } + private static final MethodHandle CONSTANT_MH_bat; + private static final MethodHandle CONSTANT_MH_bangGetter; + private static final MethodHandle CONSTANT_MH_pongSetter; + static { + try { + int t1 = tick("CallStaticInitOrder."); + { + CONSTANT_CS_baz = new MutableCallSite(methodType(int.class)); + // MH_foo() := lookup().findStatic(Init1.class, "foo", methodType(int.class)); + CONSTANT_MH_bar = lookup().findStatic(Init2.class, "bar", methodType(int.class)); + // MH_baz() := lookup().findStatic(Init3.class, "baz", methodType(int.class)); + CONSTANT_MH_bat = lookup().unreflect(Init4.class.getDeclaredMethod("bat")); + CONSTANT_MH_bangGetter = lookup().findStaticGetter(Init5.class, "bang", int.class); + MethodHandle pongSetter = lookup().findStaticSetter(Init6.class, "pong", int.class); + MethodHandle tickGetter = lookup().findStaticGetter(CallStaticInitOrder.class, "Init6Tick", int.class); + CONSTANT_MH_pongSetter = filterReturnValue(insertArguments(pongSetter, 0, -99), tickGetter); + } + int t2 = tick("CallStaticInitOrder. done"); + assertEquals(t1+1, t2); // no ticks in between + } catch (Exception ex) { + throw new InternalError(ex.toString()); + } + } + + public static void main(String... av) throws Throwable { + testInit(); + if (LAST_LOSER != null) throw LAST_LOSER; + } + + private static Throwable LAST_LOSER; + + private static void assertEquals(int expected, int actual) { + if (expected != actual) { + Throwable loser = new AssertionError("expected: " + expected + ", actual: " + actual); + if (LAST_LOSER != null) + LAST_LOSER.printStackTrace(System.out); + LAST_LOSER = loser; + } + } + + private static void testInit() throws Throwable { + System.out.println("runFoo = "+runFoo()); + System.out.println("runBar = "+runBar()); + try { + runBaz(); + } catch (IllegalStateException ex) { + tick("runBaz throw/catch"); + } + CONSTANT_CS_baz.setTarget(MH_baz()); + System.out.println("runBaz = "+runBaz()); + System.out.println("runBat = "+runBat()); + System.out.println("runBang = "+runBang()); + System.out.println("runPong = "+runPong()); + } + + private static int runFoo() throws Throwable { + assertEquals(Init1Tick, 0); // Init1 not initialized yet + int t1 = tick("runFoo"); + int t2 = (int) INDY_foo().invokeExact(); + int t3 = tick("runFoo done"); + assertEquals(Init1Tick, t2); // when Init1 was initialized + assertEquals(t1+2, t3); // exactly two ticks in between + assertEquals(t1+1, t2); // init happened inside + return t2; + } + private static MethodHandle INDY_foo() throws Throwable { + shouldNotCallThis(); + return ((CallSite) MH_bsm().invoke(lookup(), "foo", methodType(int.class))).dynamicInvoker(); + } + + private static int runBar() throws Throwable { + assertEquals(Init2Tick, 0); // Init2 not initialized yet + int t1 = tick("runBar"); + int t2 = (int) INDY_bar().invokeExact(); + int t3 = tick("runBar done"); + assertEquals(Init2Tick, t2); // when Init2 was initialized + assertEquals(t1+2, t3); // exactly two ticks in between + assertEquals(t1+1, t2); // init happened inside + return t2; + } + private static MethodHandle INDY_bar() throws Throwable { + shouldNotCallThis(); + return ((CallSite) MH_bsm().invoke(lookup(), "bar", methodType(int.class))).dynamicInvoker(); + } + + private static int runBaz() throws Throwable { + assertEquals(Init3Tick, 0); // Init3 not initialized yet + int t1 = tick("runBaz"); + int t2 = (int) INDY_baz().invokeExact(); + int t3 = tick("runBaz done"); + assertEquals(Init3Tick, t2); // when Init3 was initialized + assertEquals(t1+2, t3); // exactly two ticks in between + assertEquals(t1+1, t2); // init happened inside + return t2; + } + private static MethodHandle INDY_baz() throws Throwable { + shouldNotCallThis(); + return ((CallSite) MH_bsm().invoke(lookup(), "baz", methodType(int.class))).dynamicInvoker(); + } + + private static int runBat() throws Throwable { + assertEquals(Init4Tick, 0); // Init4 not initialized yet + int t1 = tick("runBat"); + int t2 = (int) INDY_bat().invokeExact(); + int t3 = tick("runBat done"); + assertEquals(Init4Tick, t2); // when Init4 was initialized + assertEquals(t1+2, t3); // exactly two ticks in between + assertEquals(t1+1, t2); // init happened inside + return t2; + } + private static MethodHandle INDY_bat() throws Throwable { + shouldNotCallThis(); + return ((CallSite) MH_bsm().invoke(lookup(), "bat", methodType(int.class))).dynamicInvoker(); + } + + private static int runBang() throws Throwable { + assertEquals(Init5Tick, 0); // Init5 not initialized yet + int t1 = tick("runBang"); + int t2 = (int) INDY_bang().invokeExact(); + int t3 = tick("runBang done"); + assertEquals(Init5Tick, t2); // when Init5 was initialized + assertEquals(t1+2, t3); // exactly two ticks in between + assertEquals(t1+1, t2); // init happened inside + return t2; + } + private static MethodHandle INDY_bang() throws Throwable { + shouldNotCallThis(); + return ((CallSite) MH_bsm().invoke(lookup(), "bang", methodType(int.class))).dynamicInvoker(); + } + + private static int runPong() throws Throwable { + assertEquals(Init6Tick, 0); // Init6 not initialized yet + int t1 = tick("runPong"); + int t2 = (int) INDY_pong().invokeExact(); + int t3 = tick("runPong done"); + assertEquals(Init6Tick, t2); // when Init6 was initialized + assertEquals(t1+2, t3); // exactly two ticks in between + assertEquals(t1+1, t2); // init happened inside + return t2; + } + private static MethodHandle INDY_pong() throws Throwable { + shouldNotCallThis(); + return ((CallSite) MH_bsm().invoke(lookup(), "pong", methodType(int.class))).dynamicInvoker(); + } + + private static CallSite bsm(Lookup caller, String name, MethodType type) throws ReflectiveOperationException { + System.out.println("bsm "+name+type); + CallSite res; + switch (name) { + case "foo": + res = new ConstantCallSite(MH_foo()); break; + case "bar": + res = new ConstantCallSite(CONSTANT_MH_bar); break; + case "baz": + res = CONSTANT_CS_baz; break; + case "bat": + res = new ConstantCallSite(CONSTANT_MH_bat); break; + case "bang": + res = new ConstantCallSite(CONSTANT_MH_bangGetter); break; + case "pong": + res = new ConstantCallSite(CONSTANT_MH_pongSetter); break; + default: + res = null; + } + if (res == null || !res.type().equals(type)) { + throw new AssertionError(String.valueOf(res)); + } + return res; + } + private static MethodHandle MH_bsm() throws ReflectiveOperationException { + shouldNotCallThis(); + return lookup().findStatic(lookup().lookupClass(), "bsm", + methodType(CallSite.class, Lookup.class, String.class, MethodType.class)); + } + private static void shouldNotCallThis() { + // if this gets called, the transformation has not taken place + throw new AssertionError("this code should be statically transformed away by Indify"); + } +} From 32e77eaae1cb49b531cab8ed835d599313d90d70 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:39 -0700 Subject: [PATCH 279/293] 8001110: method handles should have a collectArguments transform, generalizing asCollector Promote an existing private method; make unit tests on all argument positions to arity 10 with mixed types Reviewed-by: twisti, vlivanov --- .../java/lang/invoke/MethodHandles.java | 115 ++++++++++++++++- .../sun/invoke/util/ValueConversions.java | 51 +------- .../java/lang/invoke/JavaDocExamplesTest.java | 22 ++++ .../java/lang/invoke/MethodHandlesTest.java | 119 +++++++++++++++--- 4 files changed, 234 insertions(+), 73 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 77a65385121..0b55bfb4830 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -2216,15 +2216,120 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY return MethodHandleImpl.makeCollectArguments(target, filter, pos, false); } - // FIXME: Make this public in M1. - /*non-public*/ static - MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle collector) { + /** + * Adapts a target method handle by pre-processing + * a sub-sequence of its arguments with a filter (another method handle). + * The pre-processed arguments are replaced by the result (if any) of the + * filter function. + * The target is then called on the modified (usually shortened) argument list. + *

    + * If the filter returns a value, the target must accept that value as + * its argument in position {@code pos}, preceded and/or followed by + * any arguments not passed to the filter. + * If the filter returns void, the target must accept all arguments + * not passed to the filter. + * No arguments are reordered, and a result returned from the filter + * replaces (in order) the whole subsequence of arguments originally + * passed to the adapter. + *

    + * The argument types (if any) of the filter + * replace zero or one argument types of the target, at position {@code pos}, + * in the resulting adapted method handle. + * The return type of the filter (if any) must be identical to the + * argument type of the target at position {@code pos}, and that target argument + * is supplied by the return value of the filter. + *

    + * In all cases, {@code pos} must be greater than or equal to zero, and + * {@code pos} must also be less than or equal to the target's arity. + *

    Example: + *

    +import static java.lang.invoke.MethodHandles.*;
    +import static java.lang.invoke.MethodType.*;
    +...
    +MethodHandle deepToString = publicLookup()
    +  .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
    +
    +MethodHandle ts1 = deepToString.asCollector(String[].class, 1);
    +assertEquals("[strange]", (String) ts1.invokeExact("strange"));
    +
    +MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
    +assertEquals("[up, down]", (String) ts2.invokeExact("up", "down"));
    +
    +MethodHandle ts3 = deepToString.asCollector(String[].class, 3);
    +MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2);
    +assertEquals("[top, [up, down], strange]",
    +             (String) ts3_ts2.invokeExact("top", "up", "down", "strange"));
    +
    +MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1);
    +assertEquals("[top, [up, down], [strange]]",
    +             (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange"));
    +
    +MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
    +assertEquals("[top, [[up, down, strange], charm], bottom]",
    +             (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
    +     * 
    + *

    Here is pseudocode for the resulting adapter: + *

    +     * T target(A...,V,C...);
    +     * V filter(B...);
    +     * T adapter(A... a,B... b,C... c) {
    +     *   V v = filter(b...);
    +     *   return target(a...,v,c...);
    +     * }
    +     * // and if the filter has no arguments:
    +     * T target2(A...,V,C...);
    +     * V filter2();
    +     * T adapter2(A... a,C... c) {
    +     *   V v = filter2();
    +     *   return target2(a...,v,c...);
    +     * }
    +     * // and if the filter has a void return:
    +     * T target3(A...,C...);
    +     * void filter3(B...);
    +     * void adapter3(A... a,B... b,C... c) {
    +     *   filter3(b...);
    +     *   return target3(a...,c...);
    +     * }
    +     * 
    + *

    + * A collection adapter {@code collectArguments(mh, 0, coll)} is equivalent to + * one which first "folds" the affected arguments, and then drops them, in separate + * steps as follows: + *

    {@code
    +     * mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2
    +     * mh = MethodHandles.foldArguments(mh, coll); //step 1
    +     * }
    + * If the target method handle consumes no arguments besides than the result + * (if any) of the filter {@code coll}, then {@code collectArguments(mh, 0, coll)} + * is equivalent to {@code filterReturnValue(coll, mh)}. + * If the filter method handle {@code coll} consumes one argument and produces + * a non-void result, then {@code collectArguments(mh, N, coll)} + * is equivalent to {@code filterArguments(mh, N, coll)}. + * Other equivalences are possible but would require argument permutation. + * + * @param target the method handle to invoke after filtering the subsequence of arguments + * @param pos the position of the first adapter argument to pass to the filter, + * and/or the target argument which receives the result of the filter + * @param filter method handle to call on the subsequence of arguments + * @return method handle which incorporates the specified argument subsequence filtering logic + * @throws NullPointerException if either argument is null + * @throws IllegalArgumentException if the return type of {@code filter} + * is non-void and is not the same as the {@code pos} argument of the target, + * or if {@code pos} is not between 0 and the target's arity, inclusive, + * or if the resulting method handle's type would have + * too many parameters + * @see MethodHandles#foldArguments + * @see MethodHandles#filterArguments + * @see MethodHandles#filterReturnValue + */ + public static + MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter) { MethodType targetType = target.type(); - MethodType filterType = collector.type(); + MethodType filterType = filter.type(); if (filterType.returnType() != void.class && filterType.returnType() != targetType.parameterType(pos)) throw newIllegalArgumentException("target and filter types do not match", targetType, filterType); - return MethodHandleImpl.makeCollectArguments(target, collector, pos, false); + return MethodHandleImpl.makeCollectArguments(target, filter, pos, false); } /** diff --git a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java index 912fab4d99e..1158ccb890a 100644 --- a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java +++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java @@ -502,51 +502,6 @@ public class ValueConversions { } } - static MethodHandle collectArguments(MethodHandle mh, int pos, MethodHandle collector) { - // FIXME: API needs public MHs.collectArguments. - // Should be: - // return MethodHandles.collectArguments(mh, 0, collector); - // The rest of this code is a workaround for not having that API. - if (COLLECT_ARGUMENTS != null) { - try { - return (MethodHandle) - COLLECT_ARGUMENTS.invokeExact(mh, pos, collector); - } catch (Throwable ex) { - if (ex instanceof RuntimeException) - throw (RuntimeException) ex; - if (ex instanceof Error) - throw (Error) ex; - throw new Error(ex.getMessage(), ex); - } - } - // Emulate MHs.collectArguments using fold + drop. - // This is slightly inefficient. - // More seriously, it can put a MH over the 255-argument limit. - mh = MethodHandles.dropArguments(mh, 1, collector.type().parameterList()); - mh = MethodHandles.foldArguments(mh, collector); - return mh; - } - private static final MethodHandle COLLECT_ARGUMENTS; - static { - MethodHandle mh = null; - try { - final java.lang.reflect.Method m = MethodHandles.class - .getDeclaredMethod("collectArguments", - MethodHandle.class, int.class, MethodHandle.class); - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - m.setAccessible(true); - return null; - } - }); - mh = IMPL_LOOKUP.unreflect(m); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); - } - COLLECT_ARGUMENTS = mh; - } - private static final EnumMap[] WRAPPER_CASTS = newWrapperCaches(1); @@ -1050,12 +1005,12 @@ public class ValueConversions { if (mh == ARRAY_IDENTITY) mh = rightFiller; else - mh = collectArguments(mh, 0, rightFiller); + mh = MethodHandles.collectArguments(mh, 0, rightFiller); } if (mh == ARRAY_IDENTITY) mh = leftCollector; else - mh = collectArguments(mh, 0, leftCollector); + mh = MethodHandles.collectArguments(mh, 0, leftCollector); return mh; } @@ -1101,7 +1056,7 @@ public class ValueConversions { if (midLen == LEFT_ARGS) return rightFill; else - return collectArguments(rightFill, 0, midFill); + return MethodHandles.collectArguments(rightFill, 0, midFill); } // Type-polymorphic version of varargs maker. diff --git a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java index 982bfe90054..194564f2f91 100644 --- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java +++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java @@ -281,6 +281,28 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY }} } + @Test public void testCollectArguments() throws Throwable { + {{ +{} /// JAVADOC +MethodHandle deepToString = publicLookup() + .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class)); +MethodHandle ts1 = deepToString.asCollector(String[].class, 1); +assertEquals("[strange]", (String) ts1.invokeExact("strange")); +MethodHandle ts2 = deepToString.asCollector(String[].class, 2); +assertEquals("[up, down]", (String) ts2.invokeExact("up", "down")); +MethodHandle ts3 = deepToString.asCollector(String[].class, 3); +MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2); +assertEquals("[top, [up, down], strange]", + (String) ts3_ts2.invokeExact("top", "up", "down", "strange")); +MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1); +assertEquals("[top, [up, down], [strange]]", + (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange")); +MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3); +assertEquals("[top, [[up, down, strange], charm], bottom]", + (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom")); + }} + } + @Test public void testFoldArguments() throws Throwable { {{ {} /// JAVADOC diff --git a/jdk/test/java/lang/invoke/MethodHandlesTest.java b/jdk/test/java/lang/invoke/MethodHandlesTest.java index b77f74e3d26..53eb09cbfcd 100644 --- a/jdk/test/java/lang/invoke/MethodHandlesTest.java +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java @@ -277,6 +277,9 @@ public class MethodHandlesTest { args[i] = randomArg(param); return args; } + static Object[] randomArgs(List> params) { + return randomArgs(params.toArray(new Class[params.size()])); + } @SafeVarargs @SuppressWarnings("varargs") static T[] array(Class atype, E... a) { @@ -347,6 +350,11 @@ public class MethodHandlesTest { } return list.asType(listType); } + /** Variation of varargsList, but with the given ptypes and rtype. */ + static MethodHandle varargsList(List> ptypes, Class rtype) { + MethodHandle list = varargsList(ptypes.size(), rtype); + return list.asType(MethodType.methodType(rtype, ptypes)); + } private static MethodHandle LIST_TO_STRING, LIST_TO_INT; private static String listToString(List x) { return x.toString(); } private static int listToInt(List x) { return x.toString().hashCode(); } @@ -1833,24 +1841,24 @@ public class MethodHandlesTest { } @Test // SLOW - public void testCollectArguments() throws Throwable { + public void testAsCollector() throws Throwable { if (CAN_SKIP_WORKING) return; - startTest("collectArguments"); + startTest("asCollector"); for (Class argType : new Class[]{Object.class, Integer.class, int.class}) { if (verbosity >= 3) - System.out.println("collectArguments "+argType); + System.out.println("asCollector "+argType); for (int nargs = 0; nargs < 50; nargs++) { if (CAN_TEST_LIGHTLY && nargs > 11) break; for (int pos = 0; pos <= nargs; pos++) { if (CAN_TEST_LIGHTLY && pos > 2 && pos < nargs-2) continue; if (nargs > 10 && pos > 4 && pos < nargs-4 && pos % 10 != 3) continue; - testCollectArguments(argType, pos, nargs); + testAsCollector(argType, pos, nargs); } } } } - public void testCollectArguments(Class argType, int pos, int nargs) throws Throwable { + public void testAsCollector(Class argType, int pos, int nargs) throws Throwable { countTest(); // fake up a MH with the same type as the desired adapter: MethodHandle fake = varargsArray(nargs); @@ -1996,38 +2004,109 @@ public class MethodHandlesTest { assertEquals(expected, result); } + @Test + public void testCollectArguments() throws Throwable { + if (CAN_SKIP_WORKING) return; + startTest("collectArguments"); + testFoldOrCollectArguments(true); + } + @Test public void testFoldArguments() throws Throwable { if (CAN_SKIP_WORKING) return; startTest("foldArguments"); - for (int nargs = 0; nargs <= 4; nargs++) { - for (int fold = 0; fold <= nargs; fold++) { - for (int pos = 0; pos <= nargs; pos++) { - testFoldArguments(nargs, pos, fold); + testFoldOrCollectArguments(false); + } + + void testFoldOrCollectArguments(boolean isCollect) throws Throwable { + for (Class lastType : new Class[]{ Object.class, String.class, int.class }) { + for (Class collectType : new Class[]{ Object.class, String.class, int.class, void.class }) { + int maxArity = 10; + if (collectType != String.class) maxArity = 5; + if (lastType != Object.class) maxArity = 4; + for (int nargs = 0; nargs <= maxArity; nargs++) { + ArrayList> argTypes = new ArrayList<>(Collections.nCopies(nargs, Object.class)); + int maxMix = 20; + if (collectType != Object.class) maxMix = 0; + Map argTypesSeen = new HashMap<>(); + for (int mix = 0; mix <= maxMix; mix++) { + if (!mixArgs(argTypes, mix, argTypesSeen)) continue; + for (int collect = 0; collect <= nargs; collect++) { + for (int pos = 0; pos <= nargs - collect; pos++) { + testFoldOrCollectArguments(argTypes, pos, collect, collectType, lastType, isCollect); + } + } + } } } } } - void testFoldArguments(int nargs, int pos, int fold) throws Throwable { - if (pos != 0) return; // can fold only at pos=0 for now + boolean mixArgs(List> argTypes, int mix, Map argTypesSeen) { + assert(mix >= 0); + if (mix == 0) return true; // no change + if ((mix >>> argTypes.size()) != 0) return false; + for (int i = 0; i < argTypes.size(); i++) { + if (i >= 31) break; + boolean bit = (mix & (1 << i)) != 0; + if (bit) { + Class type = argTypes.get(i); + if (type == Object.class) + type = String.class; + else if (type == String.class) + type = int.class; + else + type = Object.class; + argTypes.set(i, type); + } + } + Integer prev = argTypesSeen.put(new ArrayList<>(argTypes), mix); + if (prev != null) { + if (verbosity >= 4) System.out.println("mix "+prev+" repeated "+mix+": "+argTypes); + return false; + } + if (verbosity >= 3) System.out.println("mix "+mix+" = "+argTypes); + return true; + } + + void testFoldOrCollectArguments(List> argTypes, // argument types minus the inserted combineType + int pos, int fold, // position and length of the folded arguments + Class combineType, // type returned from the combiner + Class lastType, // type returned from the target + boolean isCollect) throws Throwable { + int nargs = argTypes.size(); + if (pos != 0 && !isCollect) return; // can fold only at pos=0 for now countTest(); - MethodHandle target = varargsList(1 + nargs); - MethodHandle combine = varargsList(fold).asType(MethodType.genericMethodType(fold)); - List argsToPass = Arrays.asList(randomArgs(nargs, Object.class)); + List> combineArgTypes = argTypes.subList(pos, pos + fold); + List> targetArgTypes = new ArrayList<>(argTypes); + if (isCollect) // does targret see arg[pos..pos+cc-1]? + targetArgTypes.subList(pos, pos + fold).clear(); + if (combineType != void.class) + targetArgTypes.add(pos, combineType); + MethodHandle target = varargsList(targetArgTypes, lastType); + MethodHandle combine = varargsList(combineArgTypes, combineType); + List argsToPass = Arrays.asList(randomArgs(argTypes)); if (verbosity >= 3) - System.out.println("fold "+target+" with "+combine); - MethodHandle target2 = MethodHandles.foldArguments(target, combine); + System.out.println((isCollect ? "collect" : "fold")+" "+target+" with "+combine); + MethodHandle target2; + if (isCollect) + target2 = MethodHandles.collectArguments(target, pos, combine); + else + target2 = MethodHandles.foldArguments(target, combine); // Simulate expected effect of combiner on arglist: - List expected = new ArrayList<>(argsToPass); - List argsToFold = expected.subList(pos, pos + fold); + List expectedList = new ArrayList<>(argsToPass); + List argsToFold = expectedList.subList(pos, pos + fold); if (verbosity >= 3) - System.out.println("fold: "+argsToFold+" into "+target2); + System.out.println((isCollect ? "collect" : "fold")+": "+argsToFold+" into "+target2); Object foldedArgs = combine.invokeWithArguments(argsToFold); - argsToFold.add(0, foldedArgs); + if (isCollect) + argsToFold.clear(); + if (combineType != void.class) + argsToFold.add(0, foldedArgs); Object result = target2.invokeWithArguments(argsToPass); if (verbosity >= 3) System.out.println("result: "+result); + Object expected = target.invokeWithArguments(expectedList); if (!expected.equals(result)) System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result+" != "+expected); assertEquals(expected, result); From c5b5f0d6c7ce29b55d18caba387b07aa00313ca6 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:39 -0700 Subject: [PATCH 280/293] 8025112: JSR 292 spec updates for security manager and caller sensitivity Align CONSTANT_MethodHandle and Lookup.find* API calls, clarify security manager & @CallerSensitive interactions Reviewed-by: mchung, twisti --- .../java/lang/invoke/MethodHandle.java | 5 + .../java/lang/invoke/MethodHandleImpl.java | 24 ++- .../java/lang/invoke/MethodHandleInfo.java | 12 ++ .../java/lang/invoke/MethodHandleProxies.java | 5 + .../java/lang/invoke/MethodHandles.java | 162 +++++++++++++----- .../java/lang/invoke/TestPrivateMember.java | 9 +- 6 files changed, 169 insertions(+), 48 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index 79e9617094e..2487f0fd510 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -1330,6 +1330,11 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); return null; // DMH returns DMH.member } + /*non-public*/ + Class internalCallerClass() { + return null; // caller-bound MH for @CallerSensitive method returns caller + } + /*non-public*/ MethodHandle withInternalMemberName(MemberName member) { if (member != null) { diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index b25c0d847db..0d6ed2da06a 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -381,6 +381,10 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; MemberName internalMemberName() { return asFixedArity().internalMemberName(); } + @Override + Class internalCallerClass() { + return asFixedArity().internalCallerClass(); + } /*non-public*/ @Override @@ -831,7 +835,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; MethodHandle vamh = prepareForInvoker(mh); // Cache the result of makeInjectedInvoker once per argument class. MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass); - return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName()); + return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName(), hostClass); } private static MethodHandle makeInjectedInvoker(Class hostClass) { @@ -886,10 +890,12 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } // Undo the adapter effect of prepareForInvoker: - private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) { + private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, + MemberName member, + Class hostClass) { MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount()); mh = mh.asType(type); - mh = mh.withInternalMemberName(member); + mh = new WrappedMember(mh, type, member, hostClass); return mh; } @@ -958,11 +964,13 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; static class WrappedMember extends MethodHandle { private final MethodHandle target; private final MemberName member; + private final Class callerClass; - private WrappedMember(MethodHandle target, MethodType type, MemberName member) { + private WrappedMember(MethodHandle target, MethodType type, MemberName member, Class callerClass) { super(type, reinvokerForm(target)); this.target = target; this.member = member; + this.callerClass = callerClass; } @Override @@ -980,19 +988,23 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; return member; } @Override + Class internalCallerClass() { + return callerClass; + } + @Override boolean isInvokeSpecial() { return target.isInvokeSpecial(); } @Override MethodHandle viewAsType(MethodType newType) { - return new WrappedMember(target, newType, member); + return new WrappedMember(target, newType, member, callerClass); } } static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) { if (member.equals(target.internalMemberName())) return target; - return new WrappedMember(target, target.type(), member); + return new WrappedMember(target, target.type(), member, null); } } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java index 72fd8e91035..3bab3d28f4b 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java @@ -61,6 +61,18 @@ import static java.lang.invoke.MethodHandleStatics.*; * Cracking must be done via a {@code Lookup} object equivalent to that which created * the target method handle, or which has enough access permissions to recreate * an equivalent method handle. + *

    + * If the underlying method is caller sensitive, + * the direct method handle will have been "bound" to a particular caller class, the + * {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class} + * of the lookup object used to create it. + * Cracking this method handle with a different lookup class will fail + * even if the underlying method is public (like {@code Class.forName}). + *

    + * The requirement of lookup object matching provides a "fast fail" behavior + * for programs which may otherwise trust erroneous revelation of a method + * handle with symbolic information (or caller binding) from an unexpected scope. + * Use {@link java.lang.invoke.MethodHandles#reflectAs} to override this limitation. * *

    Reference kinds

    * The Lookup Factory Methods diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java index 246160cabaf..13b1d21acd4 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java @@ -107,6 +107,11 @@ public class MethodHandleProxies { * such as abstract classes with single abstract methods. * Future versions of this API may also equip wrapper instances * with one or more additional public "marker" interfaces. + *

    + * If a security manager is installed, this method is caller sensitive. + * During any invocation of the target method handle via the returned wrapper, + * the original creator of the wrapper (the caller) will be visible + * to context checks requested by the security manager. * * @param the desired type of the wrapper, a single-method interface * @param intfc a class object representing {@code T} diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 0b55bfb4830..d98bead89a4 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -90,6 +90,10 @@ public class MethodHandles { * {@linkplain Lookup#in publicLookup().in(C.class)}. * Since all classes have equal access to public names, * such a change would confer no new access rights. + * A public lookup object is always subject to + * security manager checks. + * Also, it cannot access + * caller sensitive methods. * @return a lookup object which is trusted minimally */ public static Lookup publicLookup() { @@ -242,9 +246,9 @@ public class MethodHandles { * For example, lookups for {@code MethodHandle.invokeExact} and * {@code MethodHandle.invoke} will always succeed, regardless of requested type. *

  • If there is a security manager installed, it can forbid the lookup - * on various grounds (see below). - * By contrast, the {@code ldc} instruction is not subject to - * security manager checks. + * on various grounds (see below). + * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle} + * constant is not subject to security manager checks. *
  • If the looked-up method has a * very large arity, * the method handle creation may fail, due to the method handle @@ -374,13 +378,42 @@ public class MethodHandles { * {@link SecurityManager#checkPermission smgr.checkPermission} * with {@code RuntimePermission("accessDeclaredMembers")} is called. *
  • If the retrieved member is not public, + * and if {@code lookc} is not present, * and if {@code defc} and {@code refc} are different, * then {@link SecurityManager#checkPackageAccess * smgr.checkPackageAccess(defcPkg)} is called, * where {@code defcPkg} is the package of {@code defc}. * + * Security checks are performed after other access checks have passed. + * Therefore, the above rules presuppose a member that is public, + * or else that is being accessed from a lookup class that has + * rights to access the member. + * + *

    Caller sensitive methods

    + * A small number of Java methods have a special property called caller sensitivity. + * A caller-sensitive method can behave differently depending on the + * identity of its immediate caller. + *

    + * If a method handle for a caller-sensitive method is requested, + * the general rules for bytecode behaviors apply, + * but they take account of the lookup class in a special way. + * The resulting method handle behaves as if it were called + * from an instruction contained in the lookup class, + * so that the caller-sensitive method detects the lookup class. + * (By contrast, the invoker of the method handle is disregarded.) + * Thus, in the case of caller-sensitive methods, + * different lookup classes may give rise to + * differently behaving method handles. + *

    + * In cases where the lookup object is + * {@link MethodHandles#publicLookup() publicLookup()}, + * or some other lookup object without + * {@linkplain java.lang.invoke.MethodHandles.Lookup#PRIVATE private access}, + * the lookup class is disregarded. + * In such cases, no caller-sensitive method handle can be created, + * access is forbidden, and the lookup fails with an + * {@code IllegalAccessException}. */ - // FIXME in MR1: clarify that the bytecode behavior of a caller-ID method (like Class.forName) is relative to the lookupClass used to create the method handle, not the dynamic caller of the method handle public static final class Lookup { /** The class on behalf of whom the lookup is being performed. */ @@ -639,7 +672,6 @@ assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); public MethodHandle findStatic(Class refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type); - checkSecurityManager(refc, method); return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method)); } @@ -721,7 +753,6 @@ assertEquals("", (String) MH_newString.invokeExact()); } byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual); MemberName method = resolveOrFail(refKind, refc, name, type); - checkSecurityManager(refc, method); return getDirectMethod(refKind, refc, method, findBoundCallerClass(method)); } private MethodHandle findVirtualForMH(String name, MethodType type) { @@ -782,7 +813,6 @@ assertEquals("[x, y, z]", pb.command().toString()); public MethodHandle findConstructor(Class refc, MethodType type) throws NoSuchMethodException, IllegalAccessException { String name = ""; MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type); - checkSecurityManager(refc, ctor); return getDirectConstructor(refc, ctor); } @@ -864,7 +894,6 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method checkSpecialCaller(specialCaller); Lookup specialLookup = this.in(specialCaller); MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type); - checkSecurityManager(refc, method); return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method)); } @@ -887,7 +916,6 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method */ public MethodHandle findGetter(Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_getField, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_getField, refc, field); } @@ -910,7 +938,6 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method */ public MethodHandle findSetter(Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_putField, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_putField, refc, field); } @@ -935,7 +962,6 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method */ public MethodHandle findStaticGetter(Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_getStatic, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_getStatic, refc, field); } @@ -960,7 +986,6 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method */ public MethodHandle findStaticSetter(Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_putStatic, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_putStatic, refc, field); } @@ -1013,7 +1038,6 @@ return mh1; public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { Class refc = receiver.getClass(); // may get NPE MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type); - checkSecurityManager(refc, method); MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method)); return mh.bindReceiver(receiver).setVarargs(method); } @@ -1054,7 +1078,7 @@ return mh1; refKind = REF_invokeVirtual; assert(method.isMethod()); Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; - return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method)); + return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method)); } private MethodHandle unreflectForMH(Method m) { // these names require special lookups because they throw UnsupportedOperationException @@ -1090,7 +1114,7 @@ return mh1; MemberName method = new MemberName(m, true); assert(method.isMethod()); // ignore m.isAccessible: this is a new kind of access - return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method)); + return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method)); } /** @@ -1122,7 +1146,7 @@ return mh1; MemberName ctor = new MemberName(c); assert(ctor.isConstructor()); Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this; - return lookup.getDirectConstructor(ctor.getDeclaringClass(), ctor); + return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor); } /** @@ -1152,7 +1176,7 @@ return mh1; ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind()) : MethodHandleNatives.refKindIsGetter(field.getReferenceKind())); Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this; - return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field); + return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field); } /** @@ -1183,6 +1207,8 @@ return mh1; * is capable of reproducing the target method handle. * This means that the cracking may fail if target is a direct method handle * but was created by an unrelated lookup object. + * This can happen if the method handle is caller sensitive + * and was created by a lookup object for a different class. * @param target a direct method handle to crack into symbolic reference components * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object * @exception SecurityException if a security manager is present and it @@ -1208,11 +1234,16 @@ return mh1; refKind = REF_invokeInterface; // Check SM permissions and member access before cracking. try { - checkSecurityManager(defc, member); checkAccess(refKind, defc, member); + checkSecurityManager(defc, member); } catch (IllegalAccessException ex) { throw new IllegalArgumentException(ex); } + if (allowedModes != TRUSTED && member.isCallerSensitive()) { + Class callerClass = target.internalCallerClass(); + if (!hasPrivateAccess() || callerClass != lookupClass()) + throw new IllegalArgumentException("method handle is caller sensitive: "+callerClass); + } // Produce the handle to the results. return new InfoFromMemberName(this, member, refKind); } @@ -1266,8 +1297,8 @@ return mh1; Class findBoundCallerClass(MemberName m) throws IllegalAccessException { Class callerClass = null; if (MethodHandleNatives.isCallerSensitive(m)) { - // Only full-power lookup is allowed to resolve caller-sensitive methods - if (isFullPowerLookup()) { + // Only lookups with private access are allowed to resolve caller-sensitive methods + if (hasPrivateAccess()) { callerClass = lookupClass; } else { throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object"); @@ -1276,7 +1307,7 @@ return mh1; return callerClass; } - private boolean isFullPowerLookup() { + private boolean hasPrivateAccess() { return (allowedModes & PRIVATE) != 0; } @@ -1291,22 +1322,21 @@ return mh1; if (allowedModes == TRUSTED) return; // Step 1: - if (!isFullPowerLookup() || + boolean fullPowerLookup = hasPrivateAccess(); + if (!fullPowerLookup || !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) { ReflectUtil.checkPackageAccess(refc); } // Step 2: if (m.isPublic()) return; - Class defc = m.getDeclaringClass(); - { - if (!isFullPowerLookup()) { - smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); - } + if (!fullPowerLookup) { + smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); } // Step 3: - if (defc != refc) { + Class defc = m.getDeclaringClass(); + if (!fullPowerLookup && defc != refc) { ReflectUtil.checkPackageAccess(defc); } } @@ -1335,6 +1365,7 @@ return mh1; throw m.makeAccessException(message, this); } + /** Check public/protected/private bits on the symbolic reference class and its member. */ void checkAccess(byte refKind, Class refc, MemberName m) throws IllegalAccessException { assert(m.referenceKindIsConsistentWith(refKind) && MethodHandleNatives.refKindIsValid(refKind) && @@ -1409,7 +1440,7 @@ return mh1; private void checkSpecialCaller(Class specialCaller) throws IllegalAccessException { int allowedModes = this.allowedModes; if (allowedModes == TRUSTED) return; - if ((allowedModes & PRIVATE) == 0 + if (!hasPrivateAccess() || (specialCaller != lookupClass() && !(ALLOW_NESTMATE_ACCESS && VerifyAccess.isSamePackageMember(specialCaller, lookupClass())))) @@ -1441,18 +1472,32 @@ return mh1; return mh.viewAsType(narrowType); } + /** Check access and get the requested method. */ private MethodHandle getDirectMethod(byte refKind, Class refc, MemberName method, Class callerClass) throws IllegalAccessException { - return getDirectMethodCommon(refKind, refc, method, - (refKind == REF_invokeSpecial || - (MethodHandleNatives.refKindHasReceiver(refKind) && - restrictProtectedReceiver(method))), callerClass); + final boolean doRestrict = true; + final boolean checkSecurity = true; + return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass); } + /** Check access and get the requested method, eliding receiver narrowing rules. */ private MethodHandle getDirectMethodNoRestrict(byte refKind, Class refc, MemberName method, Class callerClass) throws IllegalAccessException { - return getDirectMethodCommon(refKind, refc, method, false, callerClass); + final boolean doRestrict = false; + final boolean checkSecurity = true; + return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass); } + /** Check access and get the requested method, eliding security manager checks. */ + private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class refc, MemberName method, Class callerClass) throws IllegalAccessException { + final boolean doRestrict = true; + final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants + return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass); + } + /** Common code for all methods; do not call directly except from immediately above. */ private MethodHandle getDirectMethodCommon(byte refKind, Class refc, MemberName method, + boolean checkSecurity, boolean doRestrict, Class callerClass) throws IllegalAccessException { checkMethod(refKind, refc, method); + // Optionally check with the security manager; this isn't needed for unreflect* calls. + if (checkSecurity) + checkSecurityManager(refc, method); assert(!method.isMethodHandleInvoke()); Class refcAsSuper; @@ -1482,7 +1527,11 @@ return mh1; MethodHandle mh = DirectMethodHandle.make(refKind, refc, method); mh = maybeBindCaller(method, mh, callerClass); mh = mh.setVarargs(method); - if (doRestrict) + // Optionally narrow the receiver argument to refc using restrictReceiver. + if (doRestrict && + (refKind == REF_invokeSpecial || + (MethodHandleNatives.refKindHasReceiver(refKind) && + restrictProtectedReceiver(method)))) mh = restrictReceiver(method, mh, lookupClass()); return mh; } @@ -1492,14 +1541,29 @@ return mh1; if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method)) return mh; Class hostClass = lookupClass; - if ((allowedModes & PRIVATE) == 0) // caller must use full-power lookup + if (!hasPrivateAccess()) // caller must have private access hostClass = callerClass; // callerClass came from a security manager style stack walk MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass); // Note: caller will apply varargs after this step happens. return cbmh; } + /** Check access and get the requested field. */ private MethodHandle getDirectField(byte refKind, Class refc, MemberName field) throws IllegalAccessException { + final boolean checkSecurity = true; + return getDirectFieldCommon(refKind, refc, field, checkSecurity); + } + /** Check access and get the requested field, eliding security manager checks. */ + private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class refc, MemberName field) throws IllegalAccessException { + final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants + return getDirectFieldCommon(refKind, refc, field, checkSecurity); + } + /** Common code for all fields; do not call directly except from immediately above. */ + private MethodHandle getDirectFieldCommon(byte refKind, Class refc, MemberName field, + boolean checkSecurity) throws IllegalAccessException { checkField(refKind, refc, field); + // Optionally check with the security manager; this isn't needed for unreflect* calls. + if (checkSecurity) + checkSecurityManager(refc, field); MethodHandle mh = DirectMethodHandle.make(refc, field); boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) && restrictProtectedReceiver(field)); @@ -1507,9 +1571,24 @@ return mh1; mh = restrictReceiver(field, mh, lookupClass()); return mh; } + /** Check access and get the requested constructor. */ private MethodHandle getDirectConstructor(Class refc, MemberName ctor) throws IllegalAccessException { + final boolean checkSecurity = true; + return getDirectConstructorCommon(refc, ctor, checkSecurity); + } + /** Check access and get the requested constructor, eliding security manager checks. */ + private MethodHandle getDirectConstructorNoSecurityManager(Class refc, MemberName ctor) throws IllegalAccessException { + final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants + return getDirectConstructorCommon(refc, ctor, checkSecurity); + } + /** Common code for all constructors; do not call directly except from immediately above. */ + private MethodHandle getDirectConstructorCommon(Class refc, MemberName ctor, + boolean checkSecurity) throws IllegalAccessException { assert(ctor.isConstructor()); checkAccess(REF_newInvokeSpecial, refc, ctor); + // Optionally check with the security manager; this isn't needed for unreflect* calls. + if (checkSecurity) + checkSecurityManager(refc, ctor); assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here return DirectMethodHandle.make(ctor).setVarargs(ctor); } @@ -1527,7 +1606,7 @@ return mh1; return mh; } MemberName resolved = resolveOrFail(refKind, member); - mh = getDirectMethodHandle(refKind, defc, resolved); + mh = getDirectMethodForConstant(refKind, defc, resolved); if (mh instanceof DirectMethodHandle && canBeCached(refKind, defc, resolved)) { MemberName key = mh.internalMemberName(); @@ -1573,13 +1652,14 @@ return mh1; return true; } private - MethodHandle getDirectMethodHandle(byte refKind, Class defc, MemberName member) throws ReflectiveOperationException { + MethodHandle getDirectMethodForConstant(byte refKind, Class defc, MemberName member) + throws ReflectiveOperationException { if (MethodHandleNatives.refKindIsField(refKind)) { - return getDirectField(refKind, defc, member); + return getDirectFieldNoSecurityManager(refKind, defc, member); } else if (MethodHandleNatives.refKindIsMethod(refKind)) { - return getDirectMethod(refKind, defc, member, lookupClass); + return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass); } else if (refKind == REF_newInvokeSpecial) { - return getDirectConstructor(defc, member); + return getDirectConstructorNoSecurityManager(defc, member); } // oops throw newIllegalArgumentException("bad MethodHandle constant #"+member); diff --git a/jdk/test/java/lang/invoke/TestPrivateMember.java b/jdk/test/java/lang/invoke/TestPrivateMember.java index f2c0bc160d7..cf710c0a4f6 100644 --- a/jdk/test/java/lang/invoke/TestPrivateMember.java +++ b/jdk/test/java/lang/invoke/TestPrivateMember.java @@ -47,7 +47,10 @@ public class TestPrivateMember { MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(void.class); try { - MethodHandle mh = lookup.findStatic(Class.class, "checkInitted", mt); + Class checkInittedHolder = TestPrivateMemberPackageSibling.class; + // Original model: checkInittedHolder = Class.class; + // Not using Class.checkInitted because it could change without notice. + MethodHandle mh = lookup.findStatic(checkInittedHolder, "checkInitted", mt); throw new RuntimeException("IllegalAccessException not thrown"); } catch (IllegalAccessException e) { // okay @@ -55,3 +58,7 @@ public class TestPrivateMember { } } } + +class TestPrivateMemberPackageSibling { + private static void checkInitted() { } +} From be5df968ee76c75796ca92a24a76909c912b58a9 Mon Sep 17 00:00:00 2001 From: John R Rose Date: Sat, 5 Oct 2013 05:30:40 -0700 Subject: [PATCH 281/293] 8024438: JSR 292 API specification maintenance for JDK 8 Add wildcard to unreflectConstructor, various clarifications and minor edits Reviewed-by: mchung, darcy, twisti --- .../java/lang/invoke/BoundMethodHandle.java | 14 +- .../classes/java/lang/invoke/CallSite.java | 8 +- .../lang/invoke/InvokerBytecodeGenerator.java | 44 +-- .../classes/java/lang/invoke/LambdaForm.java | 12 +- .../java/lang/invoke/MethodHandle.java | 17 +- .../java/lang/invoke/MethodHandleInfo.java | 11 +- .../java/lang/invoke/MethodHandles.java | 311 ++++++++++++------ .../classes/java/lang/invoke/MethodType.java | 7 +- .../java/lang/invoke/MutableCallSite.java | 8 +- .../classes/java/lang/invoke/SwitchPoint.java | 8 +- .../classes/sun/invoke/WrapperInstance.java | 2 +- .../classes/sun/invoke/util/VerifyAccess.java | 16 +- .../classes/sun/invoke/util/VerifyType.java | 9 +- .../java/lang/invoke/AccessControlTest.java | 4 +- .../java/lang/invoke/MethodHandlesTest.java | 2 +- .../java/lang/invoke/RevealDirectTest.java | 10 +- 16 files changed, 276 insertions(+), 207 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java index 9aaafd7c7f1..abc31479f98 100644 --- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java @@ -529,18 +529,18 @@ import jdk.internal.org.objectweb.asm.Type; * A concrete BMH species adheres to the following schema: * *

    -         * class Species_<> extends BoundMethodHandle {
    -         *     <>
    -         *     final SpeciesData speciesData() { return SpeciesData.get("<>"); }
    +         * class Species_[[types]] extends BoundMethodHandle {
    +         *     [[fields]]
    +         *     final SpeciesData speciesData() { return SpeciesData.get("[[types]]"); }
              * }
              * 
    * - * The {@code <>} signature is precisely the string that is passed to this + * The {@code [[types]]} signature is precisely the string that is passed to this * method. * - * The {@code <>} section consists of one field definition per character in + * The {@code [[fields]]} section consists of one field definition per character in * the type signature, adhering to the naming schema described in the definition of - * {@link #makeFieldName()}. + * {@link #makeFieldName}. * * For example, a concrete BMH species for two reference and one integral bound values * would have the following shape: @@ -822,7 +822,7 @@ import jdk.internal.org.objectweb.asm.Type; * {@code }. To avoid this, we add an indirection by invoking {@code } through * {@link MethodHandle#linkToSpecial}. * - * The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void} + * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void} * result of the {@code } invocation. This entry is replaced. */ private static MethodHandle linkConstructor(MethodHandle cmh) { diff --git a/jdk/src/share/classes/java/lang/invoke/CallSite.java b/jdk/src/share/classes/java/lang/invoke/CallSite.java index e08f1db4733..1d584d53fdb 100644 --- a/jdk/src/share/classes/java/lang/invoke/CallSite.java +++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java @@ -60,7 +60,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; *

    * Here is a sample use of call sites and bootstrap methods which links every * dynamic call site to print its arguments: -

    
    +
    {@code
     static void test() throws Throwable {
         // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
         InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
    @@ -79,7 +79,7 @@ private static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String nam
       // ignore caller and name, but match the type:
       return new ConstantCallSite(printArgs.asType(type));
     }
    -
    +}
    * @author John Rose, JSR 292 EG */ abstract @@ -199,12 +199,12 @@ public class CallSite { * which has been linked to this call site. *

    * This method is equivalent to the following code: - *

    +     * 
    {@code
          * MethodHandle getTarget, invoker, result;
          * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
          * invoker = MethodHandles.exactInvoker(this.type());
          * result = MethodHandles.foldArguments(invoker, getTarget)
    -     * 
    + * }
    * * @return a method handle which always invokes this call site's current target */ diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 6228c07b7b0..7b6b4137549 100644 --- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -242,9 +242,6 @@ class InvokerBytecodeGenerator { /** * Extract the MemberName of a newly-defined method. - * - * @param classFile - * @return */ private MemberName loadMethod(byte[] classFile) { Class invokerClass = loadAndInitializeInvokerClass(classFile, cpPatches(classFile)); @@ -253,10 +250,6 @@ class InvokerBytecodeGenerator { /** * Define a given class as anonymous class in the runtime system. - * - * @param classBytes - * @param patches - * @return */ private static Class loadAndInitializeInvokerClass(byte[] classBytes, Object[] patches) { Class invokerClass = UNSAFE.defineAnonymousClass(HOST_CLASS, classBytes, patches); @@ -264,14 +257,6 @@ class InvokerBytecodeGenerator { return invokerClass; } - /** - * TODO - * - * @param invokerClass - * @param name - * @param type - * @return - */ private static MemberName resolveInvokerMember(Class invokerClass, String name, MethodType type) { MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic); //System.out.println("resolveInvokerMember => "+member); @@ -499,10 +484,6 @@ class InvokerBytecodeGenerator { /** * Generate customized bytecode for a given LambdaForm. - * - * @param form - * @param invokerType - * @return */ static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); @@ -565,8 +546,6 @@ class InvokerBytecodeGenerator { /** * Emit an invoke for the given name. - * - * @param name */ void emitInvoke(Name name) { if (true) { @@ -645,8 +624,6 @@ class InvokerBytecodeGenerator { /** * Emit an invoke for the given name, using the MemberName directly. - * - * @param name */ void emitStaticInvoke(MemberName member, Name name) { assert(member.equals(name.function.member())); @@ -690,9 +667,6 @@ class InvokerBytecodeGenerator { /** * Check if MemberName is a call to MethodHandleImpl.selectAlternative. - * - * @param member - * @return true if member is a call to MethodHandleImpl.selectAlternative */ private boolean isSelectAlternative(MemberName member) { return member != null && @@ -704,14 +678,12 @@ class InvokerBytecodeGenerator { * Emit bytecode for the selectAlternative idiom. * * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest): - * + *
    {@code
          *   Lambda(a0:L,a1:I)=>{
          *     t2:I=foo.test(a1:I);
          *     t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
          *     t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
    -     *
    -     * @param selectAlternativeName
    -     * @param invokeBasicName
    +     * }
    */ private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) { MethodType type = selectAlternativeName.function.methodType(); @@ -750,11 +722,6 @@ class InvokerBytecodeGenerator { mv.visitLabel(L_done); } - /** - * - * @param name - * @param paramIndex - */ private void emitPushArgument(Name name, int paramIndex) { Object arg = name.arguments[paramIndex]; char ptype = name.function.parameterType(paramIndex); @@ -923,9 +890,6 @@ class InvokerBytecodeGenerator { /** * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments. - * - * @param sig - * @return */ static MemberName generateLambdaFormInterpreterEntryPoint(String sig) { assert(LambdaForm.isValidSignature(sig)); @@ -993,10 +957,6 @@ class InvokerBytecodeGenerator { /** * Generate bytecode for a NamedFunction invoker. - * - * @param srcType - * @param dstType - * @return */ static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) { MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE; diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java index d83fc4780a1..857cf265fcb 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java @@ -50,7 +50,7 @@ import java.util.Objects; * The result of the lambda is defined as one of the names, often the last one. *

    * Here is an approximate grammar: - *

    + * 
    {@code
      * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
      * ArgName = "a" N ":" T
      * TempName = "t" N ":" T "=" Function "(" Argument* ");"
    @@ -60,7 +60,7 @@ import java.util.Objects;
      * NameRef = "a" N | "t" N
      * N = (any whole number)
      * T = "L" | "I" | "J" | "F" | "D" | "V"
    - * 
    + * }
    * Names are numbered consecutively from left to right starting at zero. * (The letters are merely a taste of syntax sugar.) * Thus, the first temporary (if any) is always numbered N (where N=arity). @@ -69,7 +69,7 @@ import java.util.Objects; * A lambda has a void result if and only if its result index is -1. * If a temporary has the type "V", it cannot be the subject of a NameRef, * even though possesses a number. - * Note that all reference types are erased to "L", which stands for {@code Object). + * Note that all reference types are erased to "L", which stands for {@code Object}. * All subword types (boolean, byte, short, char) are erased to "I" which is {@code int}. * The other types stand for the usual primitive types. *

    @@ -89,7 +89,7 @@ import java.util.Objects; * encoded by using temporary expressions which call type-transformed identity functions. *

    * Examples: - *

    + * 
    {@code
      * (a0:J)=>{ a0 }
      *     == identity(long)
      * (a0:I)=>{ t1:V = System.out#println(a0); void }
    @@ -113,7 +113,7 @@ import java.util.Objects;
      * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
      *                 t3:L = Class#cast(t2,a1); t3 }
      *     == invoker for identity method handle which performs cast
    - * 
    + * }
    *

    * @author John Rose, JSR 292 EG */ @@ -1441,8 +1441,6 @@ class LambdaForm { * Does this Name precede the given binding node in some canonical order? * This predicate is used to order data bindings (via insertion sort) * with some stability. - * @param binding - * @return */ boolean isSiblingBindingBefore(Name binding) { assert(!binding.isParam()); diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index 2487f0fd510..14bc2b44d58 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -292,7 +292,7 @@ mh.invokeExact(System.out, "Hello, world."); * generates a single invokevirtual instruction with * the symbolic type descriptor indicated in the following comment. * In these examples, the helper method {@code assertEquals} is assumed to - * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals } + * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals} * on its arguments, and asserts that the result is true. * *

    Exceptions

    @@ -575,10 +575,10 @@ public abstract class MethodHandle { /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable; /** - * Performs a variable arity invocation, passing the arguments in the given array + * Performs a variable arity invocation, passing the arguments in the given list * to the method handle, as if via an inexact {@link #invoke invoke} from a call site * which mentions only the type {@code Object}, and whose arity is the length - * of the argument array. + * of the argument list. *

    * Specifically, execution proceeds as if by the following steps, * although the methods are not guaranteed to be called if the JVM @@ -608,10 +608,10 @@ public abstract class MethodHandle { * or forced to null if the return type is void. *

    * This call is equivalent to the following code: - *

    +     * 

    {@code
          * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
          * Object result = invoker.invokeExact(this, arguments);
    -     * 
    + * }
    *

    * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke}, * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI. @@ -644,7 +644,7 @@ public abstract class MethodHandle { *

    * This method is also equivalent to the following code: *

    -     * {@link #invokeWithArguments(Object...) invokeWithArguments}(arguments.toArray())
    +     * {@link #invokeWithArguments(Object...) invokeWithArguments}{@code(arguments.toArray())}
          * 
    * * @param arguments the arguments to pass to the target @@ -1272,9 +1272,9 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); * starting with the string {@code "MethodHandle"} and * ending with the string representation of the method handle's type. * In other words, this method returns a string equal to the value of: - *
    +     * 
    {@code
          * "MethodHandle" + type().toString()
    -     * 
    + * }
    *

    * (Note: Future releases of this API may add further information * to the string representation. @@ -1485,7 +1485,6 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); * Threads may continue running the old form indefinitely, * but it is likely that the new one will be preferred for new executions. * Use with discretion. - * @param newForm */ /*non-public*/ void updateForm(LambdaForm newForm) { diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java index 3bab3d28f4b..d63db84b421 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java @@ -32,9 +32,10 @@ import java.lang.invoke.MethodHandles.Lookup; import static java.lang.invoke.MethodHandleStatics.*; /** - * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts. + * A symbolic reference obtained by cracking a direct method handle + * into its consitutent symbolic parts. * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}. - *

    + *

    Direct Method Handles

    * A direct method handle represents a method, constructor, or field without * any intervening argument bindings or other transformations. * The method, constructor, or field referred to by a direct method handle is called @@ -56,7 +57,9 @@ import static java.lang.invoke.MethodHandleStatics.*; * or {@link Lookup#unreflectSetter Lookup.unreflectSetter} * to convert a {@link Field} into a method handle. * - * In all of these cases, it is possible to crack the resulting direct method handle + * + *

    Restrictions on Cracking

    + * Given a suitable {@code Lookup} object, it is possible to crack any direct method handle * to recover a symbolic reference for the underlying method, constructor, or field. * Cracking must be done via a {@code Lookup} object equivalent to that which created * the target method handle, or which has enough access permissions to recreate @@ -202,7 +205,7 @@ interface MethodHandleInfo { * @return the Java language modifiers for underlying member, * or -1 if the member cannot be accessed * @see Modifier - * @see reflectAs + * @see #reflectAs */ public int getModifiers(); diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index d98bead89a4..369d14b21f4 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -49,7 +49,6 @@ import sun.security.util.SecurityConstants; *
  • Lookup methods which help create method handles for methods and fields. *
  • Combinator methods, which combine or transform pre-existing method handles into new ones. *
  • Other factory methods to create method handles that emulate other common JVM operations or control flow patterns. - *
  • Wrapper methods which can convert between method handles and interface types. * *

    * @author John Rose, JSR 292 EG @@ -66,12 +65,25 @@ public class MethodHandles { //// Method handle creation from ordinary methods. /** - * Returns a {@link Lookup lookup object} on the caller, - * which has the capability to access any method handle that the caller has access to, - * including direct method handles to private fields and methods. + * Returns a {@link Lookup lookup object} with + * full capabilities to emulate all supported bytecode behaviors of the caller. + * These capabilities include private access to the caller. + * Factory methods on the lookup object can create + * direct method handles + * for any member that the caller has access to via bytecodes, + * including protected and private fields and methods. * This lookup object is a capability which may be delegated to trusted agents. * Do not store it in place where untrusted code can access it. - * @return a lookup object for the caller of this method + *

    + * This method is caller sensitive, which means that it may return different + * values to different callers. + *

    + * For any given caller class {@code C}, the lookup object returned by this call + * has equivalent capabilities to any lookup object + * supplied by the JVM to the bootstrap method of an + * invokedynamic instruction + * executing in the same caller class {@code C}. + * @return a lookup object for the caller of this method, with private access */ @CallerSensitive public static Lookup lookup() { @@ -85,9 +97,11 @@ public class MethodHandles { *

    * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class} * of this lookup object will be {@link java.lang.Object}. - *

    + * + *

    + * Discussion: * The lookup class can be changed to any other class {@code C} using an expression of the form - * {@linkplain Lookup#in publicLookup().in(C.class)}. + * {@link Lookup#in publicLookup().in(C.class)}. * Since all classes have equal access to public names, * such a change would confer no new access rights. * A public lookup object is always subject to @@ -101,7 +115,8 @@ public class MethodHandles { } /** - * Performs an unchecked "crack" of a direct method handle. + * Performs an unchecked "crack" of a + * direct method handle. * The result is as if the user had obtained a lookup object capable enough * to crack the target method handle, called * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect} @@ -154,10 +169,17 @@ public class MethodHandles { *

    Lookup Factory Methods

    * The factory methods on a {@code Lookup} object correspond to all major * use cases for methods, constructors, and fields. + * Each method handle created by a factory method is the functional + * equivalent of a particular bytecode behavior. + * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.) * Here is a summary of the correspondence between these factory methods and * the behavior the resulting method handles: * - * + * + * + * + * + * * * * @@ -233,10 +255,12 @@ public class MethodHandles { * In cases where the given member is of variable arity (i.e., a method or constructor) * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}. * In all other cases, the returned method handle will be of fixed arity. - *

    + *

    + * Discussion: * The equivalence between looked-up method handles and underlying - * class members can break down in a few ways: - *

      + * class members and bytecode behaviors + * can break down in a few ways: + *
        *
      • If {@code C} is not symbolically accessible from the lookup class's loader, * the lookup can still succeed, even when there is no equivalent * Java expression or bytecoded constant. @@ -280,7 +304,8 @@ public class MethodHandles { * A lookup can fail, because * the containing class is not accessible to the lookup class, or * because the desired class member is missing, or because the - * desired class member is not accessible to the lookup class. + * desired class member is not accessible to the lookup class, or + * because the lookup object is not trusted enough to access the member. * In any of these cases, a {@code ReflectiveOperationException} will be * thrown from the attempted lookup. The exact class will be one of * the following: @@ -291,14 +316,23 @@ public class MethodHandles { *
      *

      * In general, the conditions under which a method handle may be - * looked up for a method {@code M} are exactly equivalent to the conditions - * under which the lookup class could have compiled and resolved a call to {@code M}. + * looked up for a method {@code M} are no more restrictive than the conditions + * under which the lookup class could have compiled, verified, and resolved a call to {@code M}. * Where the JVM would raise exceptions like {@code NoSuchMethodError}, * a method handle lookup will generally raise a corresponding * checked exception, such as {@code NoSuchMethodException}. * And the effect of invoking the method handle resulting from the lookup - * is exactly equivalent to executing the compiled and resolved call to {@code M}. + * is exactly equivalent + * to executing the compiled, verified, and resolved call to {@code M}. * The same point is true of fields and constructors. + *

      + * Discussion: + * Access checks only apply to named and reflected methods, + * constructors, and fields. + * Other method handle creation methods, such as + * {@link MethodHandle#asType MethodHandle.asType}, + * do not require any access checks, and are used + * independently of any {@code Lookup} object. *

      * If the desired member is {@code protected}, the usual JVM rules apply, * including the requirement that the lookup class must be either be in the @@ -312,6 +346,12 @@ public class MethodHandles { * (which will necessarily be a superclass of the lookup class) * to the lookup class itself. *

      + * The JVM imposes a similar requirement on {@code invokespecial} instruction, + * that the receiver argument must match both the resolved method and + * the current class. Again, this requirement is enforced by narrowing the + * type of the leading parameter to the resulting method handle. + * (See the Java Virtual Machine Specification, section 4.10.1.9.) + *

      * The JVM represents constructors and static initializer blocks as internal methods * with special names ({@code ""} and {@code ""}). * The internal syntax of invocation instructions allows them to refer to such internal @@ -331,6 +371,43 @@ public class MethodHandles { * which can transform a lookup on {@code C.E} into one on any of those other * classes, without special elevation of privilege. *

      + * The accesses permitted to a given lookup object may be limited, + * according to its set of {@link #lookupModes lookupModes}, + * to a subset of members normally accessible to the lookup class. + * For example, the {@link MethodHandles#publicLookup publicLookup} + * method produces a lookup object which is only allowed to access + * public members in public classes. + * The caller sensitive method {@link MethodHandles#lookup lookup} + * produces a lookup object with full capabilities relative to + * its caller class, to emulate all supported bytecode behaviors. + * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object + * with fewer access modes than the original lookup object. + * + *

      + * + * Discussion of private access: + * We say that a lookup has private access + * if its {@linkplain #lookupModes lookup modes} + * include the possibility of accessing {@code private} members. + * As documented in the relevant methods elsewhere, + * only lookups with private access possess the following capabilities: + *

        + *
      • access private fields, methods, and constructors of the lookup class + *
      • create method handles which invoke caller sensitive methods, + * such as {@code Class.forName} + *
      • create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions + *
      • avoid package access checks + * for classes accessible to the lookup class + *
      • create {@link Lookup#in delegated lookup objects} which have private access to other classes + * within the same package member + *
      + *

      + * Each of these permissions is a consequence of the fact that a lookup object + * with private access can be securely traced back to an originating class, + * whose bytecode behaviors and Java language access permissions + * can be reliably determined and emulated by method handles. + * + *

      Security manager interactions

      * Although bytecode instructions can only refer to classes in * a related class loader, this API can search for methods in any * class, as long as a reference to its {@code Class} object is @@ -343,16 +420,6 @@ public class MethodHandles { * and the Core Reflection API * (as found on {@link java.lang.Class Class}). *

      - * Access checks only apply to named and reflected methods, - * constructors, and fields. - * Other method handle creation methods, such as - * {@link MethodHandle#asType MethodHandle.asType}, - * do not require any access checks, and are done - * with static methods of {@link MethodHandles}, - * independently of any {@code Lookup} object. - * - *

      Security manager interactions

      - * * If a security manager is present, member lookups are subject to * additional checks. * From one to three calls are made to the security manager. @@ -365,19 +432,22 @@ public class MethodHandles { * member is actually defined. * The value {@code lookc} is defined as not present * if the current lookup object does not have - * {@linkplain java.lang.invoke.MethodHandles.Lookup#PRIVATE private access}. + * private access. * The calls are made according to the following rules: *
        - *
      • If {@code lookc} is not present, or if its class loader is not + *
      • Step 1: + * If {@code lookc} is not present, or if its class loader is not * the same as or an ancestor of the class loader of {@code refc}, * then {@link SecurityManager#checkPackageAccess * smgr.checkPackageAccess(refcPkg)} is called, * where {@code refcPkg} is the package of {@code refc}. - *
      • If the retrieved member is not public and + *
      • Step 2: + * If the retrieved member is not public and * {@code lookc} is not present, then * {@link SecurityManager#checkPermission smgr.checkPermission} * with {@code RuntimePermission("accessDeclaredMembers")} is called. - *
      • If the retrieved member is not public, + *
      • Step 3: + * If the retrieved member is not public, * and if {@code lookc} is not present, * and if {@code defc} and {@code refc} are different, * then {@link SecurityManager#checkPackageAccess @@ -408,11 +478,32 @@ public class MethodHandles { * In cases where the lookup object is * {@link MethodHandles#publicLookup() publicLookup()}, * or some other lookup object without - * {@linkplain java.lang.invoke.MethodHandles.Lookup#PRIVATE private access}, + * private access, * the lookup class is disregarded. * In such cases, no caller-sensitive method handle can be created, * access is forbidden, and the lookup fails with an * {@code IllegalAccessException}. + *

        + * Discussion: + * For example, the caller-sensitive method + * {@link java.lang.Class#forName(String) Class.forName(x)} + * can return varying classes or throw varying exceptions, + * depending on the class loader of the class that calls it. + * A public lookup of {@code Class.forName} will fail, because + * there is no reasonable way to determine its bytecode behavior. + *

        + * If an application caches method handles for broad sharing, + * it should use {@code publicLookup()} to create them. + * If there is a lookup of {@code Class.forName}, it will fail, + * and the application must take appropriate action in that case. + * It may be that a later lookup, perhaps during the invocation of a + * bootstrap method, can incorporate the specific identity + * of the caller, making the method accessible. + *

        + * The function {@code MethodHandles.lookup} is caller sensitive + * so that there can be a secure foundation for lookups. + * Nearly all other methods in the JSR 292 API rely on lookup + * objects to check access requests. */ public static final class Lookup { @@ -639,7 +730,7 @@ public class MethodHandles { * (Since static methods do not take receivers, there is no * additional receiver argument inserted into the method handle type, * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.) - * The method and all its argument types must be accessible to the lookup class. + * The method and all its argument types must be accessible to the lookup object. *

        * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if @@ -679,7 +770,7 @@ assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); * Produces a method handle for a virtual method. * The type of the method handle will be that of the method, * with the receiver type (usually {@code refc}) prepended. - * The method and all its argument types must be accessible to the lookup class. + * The method and all its argument types must be accessible to the lookup object. *

        * When called, the handle will treat the first argument as a receiver * and dispatch on the receiver's type to determine which method @@ -696,7 +787,7 @@ assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. *

        - * Because of the general equivalence between {@code invokevirtual} + * Because of the general equivalence between {@code invokevirtual} * instructions and method handles produced by {@code findVirtual}, * if the class is {@code MethodHandle} and the name string is * {@code invokeExact} or {@code invoke}, the resulting @@ -770,10 +861,10 @@ assertEquals("", (String) MH_newString.invokeExact()); * the constructor of the specified type. * The parameter types of the method handle will be those of the constructor, * while the return type will be a reference to the constructor's class. - * The constructor and all its argument types must be accessible to the lookup class. + * The constructor and all its argument types must be accessible to the lookup object. *

        - * (Note: The requested type must have a return type of {@code void}. - * This is consistent with the JVM's treatment of constructor type descriptors.) + * The requested type must have a return type of {@code void}. + * (This is consistent with the JVM's treatment of constructor type descriptors.) *

        * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if @@ -817,27 +908,26 @@ assertEquals("[x, y, z]", pb.command().toString()); } /** - * Produces an early-bound method handle for a virtual method, - * as if called from an {@code invokespecial} - * instruction from {@code caller}. + * Produces an early-bound method handle for a virtual method. + * It will bypass checks for overriding methods on the receiver, + * as if called from an {@code invokespecial} + * instruction from within the explicitly specified {@code specialCaller}. * The type of the method handle will be that of the method, - * with a suitably restricted receiver type (such as {@code caller}) prepended. + * with a suitably restricted receiver type prepended. + * (The receiver type will be {@code specialCaller} or a subtype.) * The method and all its argument types must be accessible - * to the caller. + * to the lookup object. *

        - * When called, the handle will treat the first argument as a receiver, - * but will not dispatch on the receiver's type. - * (This direct invocation action is identical with that performed by an - * {@code invokespecial} instruction.) - *

        - * If the explicitly specified caller class is not identical with the - * lookup class, or if this lookup object does not have private access + * Before method resolution, + * if the explicitly specified caller class is not identical with the + * lookup class, or if this lookup object does not have + * private access * privileges, the access fails. *

        * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. - *

        + *

        * (Note: JVM internal methods named {@code ""} are not visible to this API, * even though the {@code invokespecial} instruction can refer to them * in special circumstances. Use {@link #findConstructor findConstructor} @@ -993,7 +1083,7 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method * Produces an early-bound method handle for a non-static method. * The receiver must have a supertype {@code defc} in which a method * of the given name and type is accessible to the lookup class. - * The method and all its argument types must be accessible to the lookup class. + * The method and all its argument types must be accessible to the lookup object. * The type of the method handle will be that of the method, * without any insertion of an additional receiver parameter. * The given receiver will be bound into the method handle, @@ -1008,17 +1098,17 @@ assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method * the given receiver value will be bound to it.) *

        * This is equivalent to the following code: - *

        +         * 
        {@code
         import static java.lang.invoke.MethodHandles.*;
         import static java.lang.invoke.MethodType.*;
         ...
        -MethodHandle mh0 = lookup().{@link #findVirtual findVirtual}(defc, name, type);
        -MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
        +MethodHandle mh0 = lookup().findVirtual(defc, name, type);
        +MethodHandle mh1 = mh0.bindTo(receiver);
         MethodType mt1 = mh1.type();
         if (mh0.isVarargsCollector())
           mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
         return mh1;
        -         * 
        + * }
        * where {@code defc} is either {@code receiver.getClass()} or a super * type of that class, in which the requested method is accessible * to the lookup class. @@ -1034,6 +1124,8 @@ return mh1; * @exception SecurityException if a security manager is present and it * refuses access * @throws NullPointerException if any argument is null + * @see MethodHandle#bindTo + * @see #findVirtual */ public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { Class refc = receiver.getClass(); // may get NPE @@ -1043,7 +1135,8 @@ return mh1; } /** - * Makes a direct method handle to m, if the lookup class has permission. + * Makes a direct method handle + * to m, if the lookup class has permission. * If m is non-static, the receiver argument is treated as an initial argument. * If m is virtual, overriding is respected on every call. * Unlike the Core Reflection API, exceptions are not wrapped. @@ -1090,13 +1183,21 @@ return mh1; /** * Produces a method handle for a reflected method. * It will bypass checks for overriding methods on the receiver, - * as if by a {@code invokespecial} instruction from within the {@code specialCaller}. + * as if called from an {@code invokespecial} + * instruction from within the explicitly specified {@code specialCaller}. * The type of the method handle will be that of the method, - * with the special caller type prepended (and not the receiver of the method). + * with a suitably restricted receiver type prepended. + * (The receiver type will be {@code specialCaller} or a subtype.) * If the method's {@code accessible} flag is not set, * access checking is performed immediately on behalf of the lookup class, * as if {@code invokespecial} instruction were being linked. *

        + * Before method resolution, + * if the explicitly specified caller class is not identical with the + * lookup class, or if this lookup object does not have + * private access + * privileges, the access fails. + *

        * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. @@ -1141,8 +1242,7 @@ return mh1; * is set and {@code asVarargsCollector} fails * @throws NullPointerException if the argument is null */ - @SuppressWarnings("rawtypes") // Will be Constructor after JSR 292 MR - public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException { + public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException { MemberName ctor = new MemberName(c); assert(ctor.isConstructor()); Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this; @@ -1202,7 +1302,8 @@ return mh1; } /** - * Cracks a direct method handle created by this lookup object or a similar one. + * Cracks a direct method handle + * created by this lookup object or a similar one. * Security and access checks are performed to ensure that this lookup object * is capable of reproducing the target method handle. * This means that the cracking may fail if target is a direct method handle @@ -1215,6 +1316,7 @@ return mh1; * refuses access * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails * @exception NullPointerException if the target is {@code null} + * @see MethodHandleInfo * @since 1.8 */ public MethodHandleInfo revealDirect(MethodHandle target) { @@ -1282,7 +1384,7 @@ return mh1; throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); } - /** Check name for an illegal leading "<" character. */ + /** Check name for an illegal leading "<" character. */ void checkMethodName(byte refKind, String name) throws NoSuchMethodException { if (name.startsWith("<") && refKind != REF_newInvokeSpecial) throw new NoSuchMethodException("illegal method name: "+name); @@ -1730,13 +1832,12 @@ return mh1; * an {@link IllegalArgumentException} instead of invoking the target. *

        * This method is equivalent to the following code (though it may be more efficient): - *

        +     * 
        {@code
         MethodHandle invoker = MethodHandles.invoker(type);
         int spreadArgCount = type.parameterCount() - leadingArgCount;
         invoker = invoker.asSpreader(Object[].class, spreadArgCount);
         return invoker;
        -     * 
        - *

        + * }

        * This method throws no reflective or security exceptions. * @param type the desired target type * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target @@ -1762,9 +1863,7 @@ return invoker; * an additional leading argument of type {@code MethodHandle}. *

        * This method is equivalent to the following code (though it may be more efficient): - *

        -publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
        -     * 
        + * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)} * *

        * Discussion: @@ -1779,7 +1878,7 @@ publicLookup().findVirtual(MethodHandle.class, "invokeExact", type) * If spreading, collecting, or other argument transformations are required, * they can be applied once to the invoker {@code X} and reused on many {@code M} * method handle values, as long as they are compatible with the type of {@code X}. - *

        + *

        * (Note: The invoker method is not available via the Core Reflection API. * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke} * on the declared {@code invokeExact} or {@code invoke} method will raise an @@ -1810,15 +1909,19 @@ publicLookup().findVirtual(MethodHandle.class, "invokeExact", type) * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle}, * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}. *

        - * A {@linkplain MethodType#genericMethodType general method type}, + * This method is equivalent to the following code (though it may be more efficient): + * {@code publicLookup().findVirtual(MethodHandle.class, "invoke", type)} + *

        + * Discussion: + * A {@linkplain MethodType#genericMethodType general method type} is one which * mentions only {@code Object} arguments and return values. * An invoker for such a type is capable of calling any method handle * of the same arity as the general type. - *

        - * This method is equivalent to the following code (though it may be more efficient): - *

        -publicLookup().findVirtual(MethodHandle.class, "invoke", type)
        -     * 
        + *

        + * (Note: The invoker method is not available via the Core Reflection API. + * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke} + * on the declared {@code invokeExact} or {@code invoke} method will raise an + * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.) *

        * This method throws no reflective or security exceptions. * @param type the desired target type @@ -2105,7 +2208,7 @@ assert((int)twice.invokeExact(21) == 42); * they will come after. *

        * Example: - *

        +     * 

        {@code
         import static java.lang.invoke.MethodHandles.*;
         import static java.lang.invoke.MethodType.*;
         ...
        @@ -2116,11 +2219,11 @@ MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class)
         MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
         assertEquals(bigType, d0.type());
         assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
        -     * 
        + * }
        *

        * This method is also equivalent to the following code: *

        -     * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}(target, pos, valueTypes.toArray(new Class[0]))
        +     * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}{@code (target, pos, valueTypes.toArray(new Class[0]))}
              * 
        * @param target the method handle to invoke after the arguments are dropped * @param valueTypes the type(s) of the argument(s) to drop @@ -2163,7 +2266,7 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z")); * they will come after. *

        * Example: - *

        +     * 

        {@code
         import static java.lang.invoke.MethodHandles.*;
         import static java.lang.invoke.MethodType.*;
         ...
        @@ -2178,11 +2281,11 @@ MethodHandle d2 = dropArguments(cat, 2, String.class);
         assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
         MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
         assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
        -     * 
        + * }
        *

        * This method is also equivalent to the following code: *

        -     * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
        +     * {@link #dropArguments(MethodHandle,int,List) dropArguments}{@code (target, pos, Arrays.asList(valueTypes))}
              * 
        * @param target the method handle to invoke after the arguments are dropped * @param valueTypes the type(s) of the argument(s) to drop @@ -2228,8 +2331,8 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z")); * It is an error if there are elements of {@code filters} * (null or not) * which do not correspond to argument positions in the target. - * Example: - *

        +     * 

        Example: + *

        {@code
         import static java.lang.invoke.MethodHandles.*;
         import static java.lang.invoke.MethodType.*;
         ...
        @@ -2244,15 +2347,15 @@ MethodHandle f1 = filterArguments(cat, 1, upcase);
         assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
         MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
         assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
        -     * 
        + * }
        *

        Here is pseudocode for the resulting adapter: - *

        +     * 
        {@code
              * V target(P... p, A[i]... a[i], B... b);
              * A[i] filter[i](V[i]);
              * T adapter(P... p, V[i]... v[i], B... b) {
              *   return target(p..., f[i](v[i])..., b...);
              * }
        -     * 
        + * }
        * * @param target the method handle to invoke after arguments are filtered * @param pos the position of the first argument to filter @@ -2322,7 +2425,7 @@ assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY * In all cases, {@code pos} must be greater than or equal to zero, and * {@code pos} must also be less than or equal to the target's arity. *

        Example: - *

        +     * 

        {@code
         import static java.lang.invoke.MethodHandles.*;
         import static java.lang.invoke.MethodType.*;
         ...
        @@ -2347,9 +2450,9 @@ assertEquals("[top, [up, down], [strange]]",
         MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
         assertEquals("[top, [[up, down, strange], charm], bottom]",
                      (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
        -     * 
        + * }
        *

        Here is pseudocode for the resulting adapter: - *

        +     * 
        {@code
              * T target(A...,V,C...);
              * V filter(B...);
              * T adapter(A... a,B... b,C... c) {
        @@ -2370,7 +2473,7 @@ assertEquals("[top, [[up, down, strange], charm], bottom]",
              *   filter3(b...);
              *   return target3(a...,c...);
              * }
        -     * 
        + * }
        *

        * A collection adapter {@code collectArguments(mh, 0, coll)} is equivalent to * one which first "folds" the affected arguments, and then drops them, in separate @@ -2426,8 +2529,8 @@ assertEquals("[top, [[up, down, strange], charm], bottom]", * in the resulting adapted method handle. * The argument type of the filter (if any) must be identical to the * return type of the target. - * Example: - *

        +     * 

        Example: + *

        {@code
         import static java.lang.invoke.MethodHandles.*;
         import static java.lang.invoke.MethodType.*;
         ...
        @@ -2438,9 +2541,9 @@ MethodHandle length = lookup().findVirtual(String.class,
         System.out.println((String) cat.invokeExact("x", "y")); // xy
         MethodHandle f0 = filterReturnValue(cat, length);
         System.out.println((int) f0.invokeExact("x", "y")); // 2
        -     * 
        + * }
        *

        Here is pseudocode for the resulting adapter: - *

        +     * 
        {@code
              * V target(A...);
              * T filter(V);
              * T adapter(A... a) {
        @@ -2461,7 +2564,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
              *   V v = target3(a...);
              *   filter3(v);
              * }
        -     * 
        + * }
        * @param target the method handle to invoke before filtering the return value * @param filter method handle to call on the return value * @return method handle which incorporates the specified return value filtering logic @@ -2517,8 +2620,8 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2 * consider using {@link MethodHandle#asCollector asCollector} instead, since those * arguments will not need to be live on the stack on entry to the * target.) - * Example: - *

        +     * 

        Example: + *

        {@code
         import static java.lang.invoke.MethodHandles.*;
         import static java.lang.invoke.MethodType.*;
         ...
        @@ -2531,9 +2634,9 @@ assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
         MethodHandle catTrace = foldArguments(cat, trace);
         // also prints "boo":
         assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
        -     * 
        + * }
        *

        Here is pseudocode for the resulting adapter: - *

        +     * 
        {@code
              * // there are N arguments in A...
              * T target(V, A[N]..., B...);
              * V combiner(A...);
        @@ -2548,7 +2651,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
              *   combiner2(a...);
              *   return target2(a..., b...);
              * }
        -     * 
        + * }
        * @param target the method handle to invoke after arguments are combined * @param combiner method handle to call initially on the incoming arguments * @return method handle which incorporates the specified argument folding logic @@ -2591,7 +2694,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); * of the test must be boolean, and the test is allowed * to have fewer arguments than the other two method handles. *

        Here is pseudocode for the resulting adapter: - *

        +     * 
        {@code
              * boolean test(A...);
              * T target(A...,B...);
              * T fallback(A...,B...);
        @@ -2601,7 +2704,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
              *   else
              *     return fallback(a..., b...);
              * }
        -     * 
        + * }
        * Note that the test arguments ({@code a...} in the pseudocode) cannot * be modified by execution of the test, and so are passed unchanged * from the caller to the target or fallback as appropriate. @@ -2653,7 +2756,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum")); * (similarly to the predicate in {@link #guardWithTest guardWithTest}). * Also, the handler must have an extra leading parameter of {@code exType} or a supertype. *

        Here is pseudocode for the resulting adapter: - *

        +     * 
        {@code
              * T target(A..., B...);
              * T handler(ExType, A...);
              * T adapter(A... a, B... b) {
        @@ -2663,7 +2766,7 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
              *     return handler(ex, a...);
              *   }
              * }
        -     * 
        + * }
        * Note that the saved arguments ({@code a...} in the pseudocode) cannot * be modified by execution of the target, and so are passed unchanged * from the caller to the handler, if the handler is invoked. diff --git a/jdk/src/share/classes/java/lang/invoke/MethodType.java b/jdk/src/share/classes/java/lang/invoke/MethodType.java index 5fc1f377b90..5a73037afdb 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodType.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java @@ -77,7 +77,8 @@ import sun.invoke.util.VerifyType; * A method type may be loaded by an {@code ldc} instruction which refers * to a suitable {@code CONSTANT_MethodType} constant pool entry. * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string. - * For more details, see the package summary. + * (For full details on method type constants, + * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.) *

        * When the JVM materializes a {@code MethodType} from a descriptor string, * all classes named in the descriptor must be accessible, and will be loaded. @@ -940,10 +941,10 @@ class MethodType implements java.io.Serializable { * Instead, the return type and parameter type arrays are written directly * from the {@code writeObject} method, using two calls to {@code s.writeObject} * as follows: - *

        +     * 
        {@code
         s.writeObject(this.returnType());
         s.writeObject(this.parameterArray());
        -     * 
        + * }
        *

        * The deserialized field values are checked as if they were * provided to the factory method {@link #methodType(Class,Class[]) methodType}. diff --git a/jdk/src/share/classes/java/lang/invoke/MutableCallSite.java b/jdk/src/share/classes/java/lang/invoke/MutableCallSite.java index 37bd4641484..746c8d64e5c 100644 --- a/jdk/src/share/classes/java/lang/invoke/MutableCallSite.java +++ b/jdk/src/share/classes/java/lang/invoke/MutableCallSite.java @@ -38,7 +38,7 @@ import java.util.concurrent.atomic.AtomicInteger; * Here is an example of a mutable call site which introduces a * state variable into a method handle chain. * - *

        + * 
        {@code
         MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
         MethodHandle MH_name = name.dynamicInvoker();
         MethodType MT_str1 = MethodType.methodType(String.class);
        @@ -50,10 +50,10 @@ assertEquals("ROCKY", (String) worker1.invokeExact());
         name.setTarget(MethodHandles.constant(String.class, "Fred"));
         assertEquals("FRED", (String) worker1.invokeExact());
         // (mutation can be continued indefinitely)
        - * 
        + * }
        *

        * The same call site may be used in several places at once. - *

        + * 
        {@code
         MethodType MT_str2 = MethodType.methodType(String.class, String.class);
         MethodHandle MH_cat = lookup().findVirtual(String.class,
           "concat", methodType(String.class, String.class));
        @@ -63,7 +63,7 @@ assertEquals("Fred, dear?", (String) worker2.invokeExact());
         name.setTarget(MethodHandles.constant(String.class, "Wilma"));
         assertEquals("WILMA", (String) worker1.invokeExact());
         assertEquals("Wilma, dear?", (String) worker2.invokeExact());
        - * 
        + * }
        *

        * Non-synchronization of target values: * A write to a mutable call site's target does not force other threads diff --git a/jdk/src/share/classes/java/lang/invoke/SwitchPoint.java b/jdk/src/share/classes/java/lang/invoke/SwitchPoint.java index 65fd1dabfc6..290f9f01779 100644 --- a/jdk/src/share/classes/java/lang/invoke/SwitchPoint.java +++ b/jdk/src/share/classes/java/lang/invoke/SwitchPoint.java @@ -55,7 +55,7 @@ package java.lang.invoke; * At that point {@code guardWithTest} may ignore {@code T} and return {@code F}. *

        * Here is an example of a switch point in action: - *

        + * 
        {@code
         MethodHandle MH_strcat = MethodHandles.lookup()
             .findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class));
         SwitchPoint spt = new SwitchPoint();
        @@ -68,7 +68,7 @@ assertEquals("method", (String) worker.invokeExact("met", "hod"));
         SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
         assert(spt.hasBeenInvalidated());
         assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
        - * 
        + * }
        *

        * Discussion: * Switch points are useful without subclassing. They may also be subclassed. @@ -82,7 +82,7 @@ assertEquals("hodmet", (String) worker.invokeExact("met", "hod")); * Implementation Note: * A switch point behaves as if implemented on top of {@link MutableCallSite}, * approximately as follows: - *

        + * 
        {@code
         public class SwitchPoint {
           private static final MethodHandle
             K_true  = MethodHandles.constant(boolean.class, true),
        @@ -106,7 +106,7 @@ public class SwitchPoint {
             MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
           }
         }
        - * 
        + * }
        * @author Remi Forax, JSR 292 EG */ public class SwitchPoint { diff --git a/jdk/src/share/classes/sun/invoke/WrapperInstance.java b/jdk/src/share/classes/sun/invoke/WrapperInstance.java index ba918b4d9d2..6c545cf2528 100644 --- a/jdk/src/share/classes/sun/invoke/WrapperInstance.java +++ b/jdk/src/share/classes/sun/invoke/WrapperInstance.java @@ -30,7 +30,7 @@ import java.lang.invoke.MethodHandle; /** * Private API used inside of java.lang.invoke.MethodHandles. * Interface implemented by every object which is produced by - * {@link java.lang.invoke.MethodHandles#asInstance MethodHandles.asInstance}. + * {@link java.lang.invoke.MethodHandleProxies#asInterfaceInstance MethodHandleProxies.asInterfaceInstance}. * The methods of this interface allow a caller to recover the parameters * to {@code asInstance}. * This allows applications to repeatedly convert between method handles diff --git a/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java index 5070e973c27..3b65b586757 100644 --- a/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java +++ b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java @@ -172,7 +172,7 @@ public class VerifyAccess { * Decide if the given method type, attributed to a member or symbolic * reference of a given reference class, is really visible to that class. * @param type the supposed type of a member or symbolic reference of refc - * @param refc + * @param refc the class attempting to make the reference */ public static boolean isTypeVisible(Class type, Class refc) { if (type == refc) return true; // easy check @@ -197,7 +197,7 @@ public class VerifyAccess { * Decide if the given method type, attributed to a member or symbolic * reference of a given reference class, is really visible to that class. * @param type the supposed type of a member or symbolic reference of refc - * @param refc + * @param refc the class attempting to make the reference */ public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class refc) { for (int n = -1, max = type.parameterCount(); n < max; n++) { @@ -210,8 +210,8 @@ public class VerifyAccess { /** * Test if two classes have the same class loader and package qualifier. - * @param class1 - * @param class2 + * @param class1 a class + * @param class2 another class * @return whether they are in the same package */ public static boolean isSamePackage(Class class1, Class class2) { @@ -244,8 +244,8 @@ public class VerifyAccess { /** * Test if two classes are defined as part of the same package member (top-level class). * If this is true, they can share private access with each other. - * @param class1 - * @param class2 + * @param class1 a class + * @param class2 another class * @return whether they are identical or nested together */ public static boolean isSamePackageMember(Class class1, Class class2) { @@ -287,8 +287,8 @@ public class VerifyAccess { /** * Is the class loader of parentClass identical to, or an ancestor of, * the class loader of childClass? - * @param parentClass - * @param childClass + * @param parentClass a class + * @param childClass another class, which may be a descendent of the first class * @return whether parentClass precedes or equals childClass in class loader order */ public static boolean classLoaderIsAncestor(Class parentClass, Class childClass) { diff --git a/jdk/src/share/classes/sun/invoke/util/VerifyType.java b/jdk/src/share/classes/sun/invoke/util/VerifyType.java index e755a9eacf7..b0c76aec460 100644 --- a/jdk/src/share/classes/sun/invoke/util/VerifyType.java +++ b/jdk/src/share/classes/sun/invoke/util/VerifyType.java @@ -41,8 +41,8 @@ public class VerifyType { * True if a value can be stacked as the source type and unstacked as the * destination type, without violating the JVM's type consistency. * - * @param call the type of a stacked value - * @param recv the type by which we'd like to treat it + * @param src the type of a stacked value + * @param dst the type by which we'd like to treat it * @return whether the retyping can be done without motion or reformatting */ public static boolean isNullConversion(Class src, Class dst) { @@ -67,9 +67,8 @@ public class VerifyType { /** * Specialization of isNullConversion to reference types. - - * @param call the type of a stacked value - * @param recv the reference type by which we'd like to treat it + * @param src the type of a stacked value + * @param dst the reference type by which we'd like to treat it * @return whether the retyping can be done without a cast */ public static boolean isNullReferenceConversion(Class src, Class dst) { diff --git a/jdk/test/java/lang/invoke/AccessControlTest.java b/jdk/test/java/lang/invoke/AccessControlTest.java index 0ee0678b2c4..0d37ec6c1a3 100644 --- a/jdk/test/java/lang/invoke/AccessControlTest.java +++ b/jdk/test/java/lang/invoke/AccessControlTest.java @@ -133,7 +133,7 @@ public class AccessControlTest { } /** Simulate all assertions from the spec. for Lookup.in: - *
        + *
        * Creates a lookup on the specified new lookup class. * [A1] The resulting object will report the specified * class as its own {@link #lookupClass lookupClass}. @@ -155,7 +155,7 @@ public class AccessControlTest { *
      * Other than the above cases, the new lookup will have the same * access capabilities as the original. [A8] - *
      + *
      */ public LookupCase in(Class c2) { Class c1 = lookupClass(); diff --git a/jdk/test/java/lang/invoke/MethodHandlesTest.java b/jdk/test/java/lang/invoke/MethodHandlesTest.java index 53eb09cbfcd..37da9b0c8a0 100644 --- a/jdk/test/java/lang/invoke/MethodHandlesTest.java +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java @@ -496,7 +496,7 @@ public class MethodHandlesTest { return lookup.in(defc); } - /** Is findVirtual (etc.) of "" supposed to elicit a NoSuchMethodException? */ + /** Is findVirtual (etc.) of "<init<" supposed to elicit a NoSuchMethodException? */ final static boolean INIT_REF_CAUSES_NSME = true; @Test diff --git a/jdk/test/java/lang/invoke/RevealDirectTest.java b/jdk/test/java/lang/invoke/RevealDirectTest.java index f05b19077c1..1aa15da8af2 100644 --- a/jdk/test/java/lang/invoke/RevealDirectTest.java +++ b/jdk/test/java/lang/invoke/RevealDirectTest.java @@ -104,6 +104,9 @@ public class RevealDirectTest { private static Lookup localLookup() { return lookup(); } private static List members() { return getMembers(lookup().lookupClass()); }; } + static class Nestmate { + private static Lookup localLookup() { return lookup(); } + } static boolean VERBOSE = false; @@ -152,7 +155,10 @@ public class RevealDirectTest { getMembers(Method.class, "invoke")); mems = callerSensitive(true, publicOnly(mems)); // CS methods cannot be looked up with publicLookup - testOnMembersNoLookup("testCallerSensitiveNegative", mems, publicLookup()); + testOnMembersNoLookup("testCallerSensitiveNegative/1", mems, publicLookup()); + // CS methods have to be revealed with a matching lookupClass + testOnMembersNoReveal("testCallerSensitiveNegative/2", mems, Simple.localLookup(), publicLookup()); + testOnMembersNoReveal("testCallerSensitiveNegative/3", mems, Simple.localLookup(), Nestmate.localLookup()); } @Test public void testMethodHandleNatives() throws Throwable { if (VERBOSE) System.out.println("@Test testMethodHandleNatives"); @@ -703,7 +709,7 @@ public class RevealDirectTest { try { info = revLookup.revealDirect(mh); if (expectEx2) throw new AssertionError("unexpected revelation for negative test"); - } catch (Throwable ex2) { + } catch (IllegalArgumentException|SecurityException ex2) { if (VERBOSE) System.out.println(" "+variation+": "+res+" => "+mh.getClass().getName()+" => (EX2)"+ex2); if (expectEx2) continue; // this is OK; we expected the reflect to fail From 68ef7f0bc3075f990e40aafdd5f2ea10b29cd44f Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Mon, 7 Oct 2013 11:48:55 +0100 Subject: [PATCH 282/293] 8025983: Typo in Javadoc of Files.isRegularFile() Reviewed-by: mchung, chegar --- jdk/src/share/classes/java/nio/file/Files.java | 6 +++--- jdk/src/share/classes/java/nio/file/Path.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index f084040c179..174e390a665 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -2128,7 +2128,7 @@ public final class Files { /** * Tests whether a file is a symbolic link. * - *

      Where is it required to distinguish an I/O exception from the case + *

      Where it is required to distinguish an I/O exception from the case * that the file is not a symbolic link then the file attributes can be * read with the {@link #readAttributes(Path,Class,LinkOption[]) * readAttributes} method and the file type tested with the {@link @@ -2164,7 +2164,7 @@ public final class Files { * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS * NOFOLLOW_LINKS} is present then symbolic links are not followed. * - *

      Where is it required to distinguish an I/O exception from the case + *

      Where it is required to distinguish an I/O exception from the case * that the file is not a directory then the file attributes can be * read with the {@link #readAttributes(Path,Class,LinkOption[]) * readAttributes} method and the file type tested with the {@link @@ -2201,7 +2201,7 @@ public final class Files { * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS * NOFOLLOW_LINKS} is present then symbolic links are not followed. * - *

      Where is it required to distinguish an I/O exception from the case + *

      Where it is required to distinguish an I/O exception from the case * that the file is not a regular file then the file attributes can be * read with the {@link #readAttributes(Path,Class,LinkOption[]) * readAttributes} method and the file type tested with the {@link diff --git a/jdk/src/share/classes/java/nio/file/Path.java b/jdk/src/share/classes/java/nio/file/Path.java index 39afd4d4255..2bcc9aa3512 100644 --- a/jdk/src/share/classes/java/nio/file/Path.java +++ b/jdk/src/share/classes/java/nio/file/Path.java @@ -315,7 +315,7 @@ public interface Path * and parent directory. In such file systems all occurrences of "{@code .}" * are considered redundant. If a "{@code ..}" is preceded by a * non-"{@code ..}" name then both names are considered redundant (the - * process to identify such names is repeated until is it no longer + * process to identify such names is repeated until it is no longer * applicable). * *

      This method does not access the file system; the path may not locate From af5d94ec7154ca40aaef9186a66dbcafed9bc3a1 Mon Sep 17 00:00:00 2001 From: Tomas Hurka Date: Mon, 7 Oct 2013 13:11:40 +0200 Subject: [PATCH 283/293] 8025920: webrev.ksh does not provide any details about changes in zip files Add support for diffs for zip files Reviewed-by: ksrini, chegar --- make/scripts/webrev.ksh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/make/scripts/webrev.ksh b/make/scripts/webrev.ksh index 3839b7490f5..d36e62b27a1 100644 --- a/make/scripts/webrev.ksh +++ b/make/scripts/webrev.ksh @@ -2704,11 +2704,11 @@ do rm -f $WDIR/$DIR/$F.html its_a_jar= - if expr $F : '.*\.jar' >/dev/null; then + if expr $F : '.*\.jar' \| $F : '.*\.zip' >/dev/null; then its_a_jar=1 - # It's a JAR file, let's do it differntly + # It's a JAR or ZIP file, let's do it differently if [[ -z $JAR ]]; then - print "No access to jar, so can't produce diffs for jar files" + print "No access to jar, so can't produce diffs for jar or zip files" else if [ -f $ofile ]; then $JAR -tvf $ofile >"$ofile".lst From e749e35771569bf71362bfbcd1b1347175b43dfd Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Mon, 7 Oct 2013 18:19:15 +0200 Subject: [PATCH 284/293] 8005924: Make it possible to set both --with-user-release-suffix and --with-build-number Reviewed-by: ihse, tbell --- common/autoconf/generated-configure.sh | 44 ++++++++++++++------------ common/autoconf/jdk-options.m4 | 30 ++++++++++-------- common/autoconf/spec.gmk.in | 5 +-- 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index adf6e10e4ba..d09935154a7 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1016,8 +1016,8 @@ with_cacerts_file enable_unlimited_crypto with_milestone with_update_version -with_build_number with_user_release_suffix +with_build_number with_boot_jdk with_boot_jdk_jvmargs with_add_source_root @@ -1755,10 +1755,10 @@ Optional Packages: --with-cacerts-file specify alternative cacerts file --with-milestone Set milestone value for build [internal] --with-update-version Set update version value for build [b00] - --with-build-number Set build number value for build [b00] --with-user-release-suffix Add a custom string to the version string if build number isn't set.[username_builddateb00] + --with-build-number Set build number value for build [b00] --with-boot-jdk path to Boot JDK (used to bootstrap build) [probed] --with-boot-jdk-jvmargs specify JVM arguments to be passed to all invocations of the Boot JDK, overriding the default @@ -3818,7 +3818,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1380792206 +DATE_WHEN_GENERATED=1381162713 ############################################################################### # @@ -11048,6 +11048,18 @@ elif test "x$with_update_version" != x; then fi +# Check whether --with-user-release-suffix was given. +if test "${with_user_release_suffix+set}" = set; then : + withval=$with_user_release_suffix; +fi + +if test "x$with_user_release_suffix" = xyes; then + as_fn_error $? "Release suffix must have a value" "$LINENO" 5 +elif test "x$with_user_release_suffix" != x; then + USER_RELEASE_SUFFIX="$with_user_release_suffix" +fi + + # Check whether --with-build-number was given. if test "${with_build_number+set}" = set; then : withval=$with_build_number; @@ -11058,28 +11070,17 @@ if test "x$with_build_number" = xyes; then elif test "x$with_build_number" != x; then JDK_BUILD_NUMBER="$with_build_number" fi +# Define default USER_RELEASE_SUFFIX if BUILD_NUMBER and USER_RELEASE_SUFFIX are not set if test "x$JDK_BUILD_NUMBER" = x; then JDK_BUILD_NUMBER=b00 + if test "x$USER_RELEASE_SUFFIX" = x; then + BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` + # Avoid [:alnum:] since it depends on the locale. + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` + USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi fi - -# Check whether --with-user-release-suffix was given. -if test "${with_user_release_suffix+set}" = set; then : - withval=$with_user_release_suffix; -fi - -if test "x$with_user_release_suffix" = xyes; then - as_fn_error $? "Release suffix must have a value" "$LINENO" 5 -elif test "x$with_user_release_suffix" != x; then - USER_RELEASE_SUFFIX="$with_user_release_suffix" -else - BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` - # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` - USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -fi - - # Now set the JDK version, milestone, build number etc. @@ -11095,6 +11096,7 @@ fi + COPYRIGHT_YEAR=`date +'%Y'` diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index f52f74d0574..188060740d7 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -426,6 +426,14 @@ elif test "x$with_update_version" != x; then JDK_UPDATE_VERSION="$with_update_version" fi +AC_ARG_WITH(user-release-suffix, [AS_HELP_STRING([--with-user-release-suffix], + [Add a custom string to the version string if build number isn't set.@<:@username_builddateb00@:>@])]) +if test "x$with_user_release_suffix" = xyes; then + AC_MSG_ERROR([Release suffix must have a value]) +elif test "x$with_user_release_suffix" != x; then + USER_RELEASE_SUFFIX="$with_user_release_suffix" +fi + AC_ARG_WITH(build-number, [AS_HELP_STRING([--with-build-number], [Set build number value for build @<:@b00@:>@])]) if test "x$with_build_number" = xyes; then @@ -433,25 +441,19 @@ if test "x$with_build_number" = xyes; then elif test "x$with_build_number" != x; then JDK_BUILD_NUMBER="$with_build_number" fi +# Define default USER_RELEASE_SUFFIX if BUILD_NUMBER and USER_RELEASE_SUFFIX are not set if test "x$JDK_BUILD_NUMBER" = x; then JDK_BUILD_NUMBER=b00 + if test "x$USER_RELEASE_SUFFIX" = x; then + BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` + # Avoid [:alnum:] since it depends on the locale. + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` + USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + fi fi -AC_ARG_WITH(user-release-suffix, [AS_HELP_STRING([--with-user-release-suffix], - [Add a custom string to the version string if build number isn't set.@<:@username_builddateb00@:>@])]) -if test "x$with_user_release_suffix" = xyes; then - AC_MSG_ERROR([Release suffix must have a value]) -elif test "x$with_user_release_suffix" != x; then - USER_RELEASE_SUFFIX="$with_user_release_suffix" -else - BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` - # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` - USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` -fi -AC_SUBST(USER_RELEASE_SUFFIX) - # Now set the JDK version, milestone, build number etc. +AC_SUBST(USER_RELEASE_SUFFIX) AC_SUBST(JDK_MAJOR_VERSION) AC_SUBST(JDK_MINOR_VERSION) AC_SUBST(JDK_MICRO_VERSION) diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index 7e186693700..163fbc9a90d 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -161,6 +161,7 @@ JDK_RC_PLATFORM_NAME:=@JDK_RC_PLATFORM_NAME@ COMPANY_NAME:=@COMPANY_NAME@ MACOSX_BUNDLE_NAME_BASE=@MACOSX_BUNDLE_NAME_BASE@ MACOSX_BUNDLE_ID_BASE=@MACOSX_BUNDLE_ID_BASE@ +USER_RELEASE_SUFFIX=@USER_RELEASE_SUFFIX@ # Different version strings generated from the above information. JDK_VERSION:=@JDK_VERSION@ @@ -173,8 +174,8 @@ ifeq ($(MILESTONE),) else RELEASE=$(JDK_VERSION)-$(MILESTONE)$(BUILD_VARIANT_RELEASE) endif -ifeq ($(JDK_BUILD_NUMBER),b00) - USER_RELEASE_SUFFIX=@USER_RELEASE_SUFFIX@ + +ifneq ($(USER_RELEASE_SUFFIX),) FULL_VERSION=$(RELEASE)-$(USER_RELEASE_SUFFIX)-$(JDK_BUILD_NUMBER) else FULL_VERSION=$(RELEASE)-$(JDK_BUILD_NUMBER) From 1542ab6eefbbcbcec38d274b495d5b87a2927b57 Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Mon, 7 Oct 2013 11:25:56 -0700 Subject: [PATCH 285/293] 8025968: Integrate test improvements made in lambda repo Reviewed-by: psandoz --- .../bootlib/java/util/stream/OpTestCase.java | 171 +++++++++--------- .../tests/java/util/stream/ExplodeOpTest.java | 3 + .../java/util/stream/TabulatorsTest.java | 2 +- 3 files changed, 87 insertions(+), 89 deletions(-) diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java b/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java index 115a37dc6c5..09fbff83986 100644 --- a/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java +++ b/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java @@ -30,7 +30,6 @@ import java.util.Collection; import java.util.Collections; import java.util.EnumMap; import java.util.EnumSet; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -41,7 +40,6 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; -import org.testng.Assert; import org.testng.annotations.Test; /** @@ -397,14 +395,68 @@ public abstract class OpTestCase extends LoggingTestCase { // Exercise terminal operations - static enum TerminalTestScenario { - SINGLE_SEQUENTIAL, - SINGLE_SEQUENTIAL_SHORT_CIRCUIT, - SINGLE_PARALLEL, - ALL_SEQUENTIAL, - ALL_SEQUENTIAL_SHORT_CIRCUIT, - ALL_PARALLEL, - ALL_PARALLEL_SEQUENTIAL, + interface BaseTerminalTestScenario> { + boolean requiresSingleStageSource(); + + boolean requiresParallelSource(); + + default R run(Function terminalF, S_OUT source, StreamShape shape) { + return terminalF.apply(source); + } + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + static enum TerminalTestScenario implements BaseTerminalTestScenario { + SINGLE_SEQUENTIAL(true, false), + + SINGLE_SEQUENTIAL_SHORT_CIRCUIT(true, false) { + @Override + public Object run(Function terminalF, BaseStream source, StreamShape shape) { + source = (BaseStream) chain(source, new ShortCircuitOp(shape)); + return terminalF.apply(source); + } + }, + + SINGLE_PARALLEL(true, true), + + ALL_SEQUENTIAL(false, false), + + ALL_SEQUENTIAL_SHORT_CIRCUIT(false, false) { + @Override + public Object run(Function terminalF, BaseStream source, StreamShape shape) { + source = (BaseStream) chain(source, new ShortCircuitOp(shape)); + return terminalF.apply(source); + } + }, + + ALL_PARALLEL(false, true), + + ALL_PARALLEL_SEQUENTIAL(false, false) { + @Override + public Object run(Function terminalF, BaseStream source, StreamShape shape) { + return terminalF.apply(source.sequential()); + } + }, + ; + + private final boolean requiresSingleStageSource; + private final boolean isParallel; + + TerminalTestScenario(boolean requiresSingleStageSource, boolean isParallel) { + this.requiresSingleStageSource = requiresSingleStageSource; + this.isParallel = isParallel; + } + + @Override + public boolean requiresSingleStageSource() { + return requiresSingleStageSource; + } + + @Override + public boolean requiresParallelSource() { + return isParallel; + } + } @SuppressWarnings({"rawtypes", "unchecked"}) @@ -415,8 +467,6 @@ public abstract class OpTestCase extends LoggingTestCase { R refResult; - Set testSet = EnumSet.allOf(TerminalTestScenario.class); - ResultAsserter resultAsserter = (act, exp, ord, par) -> LambdaTestHelpers.assertContentsEqual(act, exp); private ExerciseDataTerminalBuilder(TestData data, Function streamF, Function terminalF) { @@ -442,27 +492,6 @@ public abstract class OpTestCase extends LoggingTestCase { return this; } - public ExerciseDataTerminalBuilder without(TerminalTestScenario... tests) { - return without(Arrays.asList(tests)); - } - - public ExerciseDataTerminalBuilder without(Collection tests) { - testSet.removeAll(tests); - if (testSet.isEmpty()) { - throw new IllegalStateException("Terminal test scenario set is empty"); - } - return this; - } - - public ExerciseDataTerminalBuilder with(TerminalTestScenario... tests) { - return with(Arrays.asList(tests)); - } - - public ExerciseDataTerminalBuilder with(Collection tests) { - testSet.addAll(tests); - return this; - } - // Build method public R exercise() { @@ -471,70 +500,36 @@ public abstract class OpTestCase extends LoggingTestCase { boolean isOrdered = StreamOpFlag.ORDERED.isKnown(ap.getStreamFlags()); StreamShape shape = ap.getOutputShape(); + EnumSet tests = EnumSet.allOf(TerminalTestScenario.class); + // Sequentially collect the output that will be input to the terminal op Node node = ap.evaluateToArrayNode(size -> (U[]) new Object[size]); if (refResult == null) { - // Sequentially collect the output that will be input to the terminal op - refResult = terminalF.apply((S_OUT) createPipeline(shape, node.spliterator(), - StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED, - false)); - } else if (testSet.contains(TerminalTestScenario.SINGLE_SEQUENTIAL)) { + // Induce the reference result S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(), StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED, false); - R result = terminalF.apply(source); - LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false), - () -> String.format("Single sequential: %s != %s", refResult, result)); + + refResult = (R) TerminalTestScenario.SINGLE_SEQUENTIAL.run(terminalF, source, shape); + tests.remove(TerminalTestScenario.SINGLE_SEQUENTIAL); } - if (testSet.contains(TerminalTestScenario.SINGLE_SEQUENTIAL_SHORT_CIRCUIT)) { - S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(), - StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED, - false); - // Force short-circuit - source = (S_OUT) chain(source, new ShortCircuitOp(shape)); - R result = terminalF.apply(source); - LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false), - () -> String.format("Single sequential pull: %s != %s", refResult, result)); - } + for (BaseTerminalTestScenario test : tests) { + S_OUT source; + if (test.requiresSingleStageSource()) { + source = (S_OUT) createPipeline(shape, node.spliterator(), + StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED, + test.requiresParallelSource()); + } + else { + source = streamF.apply(test.requiresParallelSource() + ? data.parallelStream() : data.stream()); + } - if (testSet.contains(TerminalTestScenario.SINGLE_PARALLEL)) { - S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(), - StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED, - true); - R result = terminalF.apply(source); - LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, true), - () -> String.format("Single parallel: %s != %s", refResult, result)); - } + R result = (R) test.run(terminalF, source, shape); - if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL)) { - // This may forEach or tryAdvance depending on the terminal op implementation - S_OUT source = streamF.apply(data.stream()); - R result = terminalF.apply(source); - LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false), - () -> String.format("All sequential: %s != %s", refResult, result)); - } - - if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL_SHORT_CIRCUIT)) { - S_OUT source = streamF.apply(data.stream()); - // Force short-circuit - source = (S_OUT) chain(source, new ShortCircuitOp(shape)); - R result = terminalF.apply(source); - LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false), - () -> String.format("All sequential pull: %s != %s", refResult, result)); - } - - if (testSet.contains(TerminalTestScenario.ALL_PARALLEL)) { - S_OUT source = streamF.apply(data.parallelStream()); - R result = terminalF.apply(source); - LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, true), - () -> String.format("All parallel: %s != %s", refResult, result)); - } - - if (testSet.contains(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL)) { - S_OUT source = streamF.apply(data.parallelStream()); - R result = terminalF.apply(source.sequential()); - LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false), - () -> String.format("All parallel then sequential: %s != %s", refResult, result)); + LambdaTestHelpers.launderAssertion( + () -> resultAsserter.assertResult(result, refResult, isOrdered, test.requiresParallelSource()), + () -> String.format("%s: %s != %s", test, refResult, result)); } return refResult; diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java index 4332a0cc786..cbd9534aa6f 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java @@ -64,6 +64,9 @@ public class ExplodeOpTest extends OpTestCase { result = exerciseOps(data, s -> s.flatMap(mfNull)); assertEquals(0, result.size()); + result = exerciseOps(data, s-> s.flatMap(e -> Stream.empty())); + assertEquals(0, result.size()); + exerciseOps(data, s -> s.flatMap(mfLt)); exerciseOps(data, s -> s.flatMap(integerRangeMapper)); exerciseOps(data, s -> s.flatMap((Integer e) -> IntStream.range(0, e).boxed().limit(10))); diff --git a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java index 52f3c21d574..f539df5d825 100644 --- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java +++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java @@ -609,7 +609,7 @@ public class TabulatorsTest extends OpTestCase { @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) public void testComposeFinisher(String name, TestData.OfRef data) throws ReflectiveOperationException { List asList = exerciseTerminalOps(data, s -> s.collect(toList())); - List asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList))); + List asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList))); assertEquals(asList, asImmutableList); try { asImmutableList.add(0); From 6a322383a899cccdf1710b975cf379a5179ab5ea Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Mon, 7 Oct 2013 15:18:37 -0700 Subject: [PATCH 286/293] 8026009: Changes for 8025968 break all stream tests Reviewed-by: mduigou --- .../java/util/stream/bootlib/java/util/stream/OpTestCase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java b/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java index 09fbff83986..9be4be72c72 100644 --- a/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java +++ b/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java @@ -591,10 +591,10 @@ public abstract class OpTestCase extends LoggingTestCase { // Test data - private class ShortCircuitOp implements StatelessTestOp { + static class ShortCircuitOp implements StatelessTestOp { private final StreamShape shape; - private ShortCircuitOp(StreamShape shape) { + ShortCircuitOp(StreamShape shape) { this.shape = shape; } From 1d8fbe7d053d049c206329df0d61b853d1b48854 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Mon, 7 Oct 2013 18:46:28 -0700 Subject: [PATCH 287/293] 6956398: make ephemeral DH key match the length of the certificate key Reviewed-by: weijun --- .../sun/security/ssl/ServerHandshaker.java | 122 ++++- .../ssl/DHKeyExchange/DHEKeySizing.java | 477 ++++++++++++++++++ 2 files changed, 589 insertions(+), 10 deletions(-) create mode 100644 jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java diff --git a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java index 23b806f33e2..85c1b4d56f3 100644 --- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java +++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java @@ -40,6 +40,8 @@ import javax.net.ssl.*; import javax.security.auth.Subject; +import sun.security.util.KeyUtil; +import sun.security.action.GetPropertyAction; import sun.security.ssl.HandshakeMessage.*; import sun.security.ssl.CipherSuite.*; import sun.security.ssl.SignatureAndHashAlgorithm.*; @@ -93,6 +95,50 @@ final class ServerHandshaker extends Handshaker { // the preferable signature algorithm used by ServerKeyExchange message SignatureAndHashAlgorithm preferableSignatureAlgorithm; + // Flag to use smart ephemeral DH key which size matches the corresponding + // authentication key + private static final boolean useSmartEphemeralDHKeys; + + // Flag to use legacy ephemeral DH key which size is 512 bits for + // exportable cipher suites, and 768 bits for others + private static final boolean useLegacyEphemeralDHKeys; + + // The customized ephemeral DH key size for non-exportable cipher suites. + private static final int customizedDHKeySize; + + static { + String property = AccessController.doPrivileged( + new GetPropertyAction("jdk.tls.ephemeralDHKeySize")); + if (property == null || property.length() == 0) { + useLegacyEphemeralDHKeys = false; + useSmartEphemeralDHKeys = false; + customizedDHKeySize = -1; + } else if ("matched".equals(property)) { + useLegacyEphemeralDHKeys = false; + useSmartEphemeralDHKeys = true; + customizedDHKeySize = -1; + } else if ("legacy".equals(property)) { + useLegacyEphemeralDHKeys = true; + useSmartEphemeralDHKeys = false; + customizedDHKeySize = -1; + } else { + useLegacyEphemeralDHKeys = false; + useSmartEphemeralDHKeys = false; + + try { + customizedDHKeySize = Integer.parseUnsignedInt(property); + if (customizedDHKeySize < 1024 || customizedDHKeySize > 2048) { + throw new IllegalArgumentException( + "Customized DH key size should be positive integer " + + "between 1024 and 2048 bits, inclusive"); + } + } catch (NumberFormatException nfe) { + throw new IllegalArgumentException( + "Invalid system property jdk.tls.ephemeralDHKeySize"); + } + } + } + /* * Constructor ... use the keys found in the auth context. */ @@ -1107,7 +1153,7 @@ final class ServerHandshaker extends Handshaker { } } - setupEphemeralDHKeys(suite.exportable); + setupEphemeralDHKeys(suite.exportable, privateKey); break; case K_ECDHE_RSA: // need RSA certs for authentication @@ -1144,7 +1190,8 @@ final class ServerHandshaker extends Handshaker { if (setupPrivateKeyAndChain("DSA") == false) { return false; } - setupEphemeralDHKeys(suite.exportable); + + setupEphemeralDHKeys(suite.exportable, privateKey); break; case K_ECDHE_ECDSA: // get preferable peer signature algorithm for server key exchange @@ -1188,7 +1235,7 @@ final class ServerHandshaker extends Handshaker { break; case K_DH_ANON: // no certs needed for anonymous - setupEphemeralDHKeys(suite.exportable); + setupEphemeralDHKeys(suite.exportable, null); break; case K_ECDH_ANON: // no certs needed for anonymous @@ -1237,15 +1284,70 @@ final class ServerHandshaker extends Handshaker { * Acquire some "ephemeral" Diffie-Hellman keys for this handshake. * We don't reuse these, for improved forward secrecy. */ - private void setupEphemeralDHKeys(boolean export) { + private void setupEphemeralDHKeys(boolean export, Key key) { /* - * Diffie-Hellman keys ... we use 768 bit private keys due - * to the "use twice as many key bits as bits you want secret" - * rule of thumb, assuming we want the same size premaster - * secret with Diffie-Hellman and RSA key exchanges. Except - * that exportable ciphers max out at 512 bits modulus values. + * 768 bits ephemeral DH private keys were used to be used in + * ServerKeyExchange except that exportable ciphers max out at 512 + * bits modulus values. We still adhere to this behavior in legacy + * mode (system property "jdk.tls.ephemeralDHKeySize" is defined + * as "legacy"). + * + * Old JDK (JDK 7 and previous) releases don't support DH keys bigger + * than 1024 bits. We have to consider the compatibility requirement. + * 1024 bits DH key is always used for non-exportable cipher suites + * in default mode (system property "jdk.tls.ephemeralDHKeySize" + * is not defined). + * + * However, if applications want more stronger strength, setting + * system property "jdk.tls.ephemeralDHKeySize" to "matched" + * is a workaround to use ephemeral DH key which size matches the + * corresponding authentication key. For example, if the public key + * size of an authentication certificate is 2048 bits, then the + * ephemeral DH key size should be 2048 bits accordingly unless + * the cipher suite is exportable. This key sizing scheme keeps + * the cryptographic strength consistent between authentication + * keys and key-exchange keys. + * + * Applications may also want to customize the ephemeral DH key size + * to a fixed length for non-exportable cipher suites. This can be + * approached by setting system property "jdk.tls.ephemeralDHKeySize" + * to a valid positive integer between 1024 and 2048 bits, inclusive. + * + * Note that the minimum acceptable key size is 1024 bits except + * exportable cipher suites or legacy mode. + * + * Note that the maximum acceptable key size is 2048 bits because + * DH keys bigger than 2048 are not always supported by underlying + * JCE providers. + * + * Note that per RFC 2246, the key size limit of DH is 512 bits for + * exportable cipher suites. Because of the weakness, exportable + * cipher suites are deprecated since TLS v1.1 and they are not + * enabled by default in Oracle provider. The legacy behavior is + * reserved and 512 bits DH key is always used for exportable + * cipher suites. */ - dh = new DHCrypt((export ? 512 : 768), sslContext.getSecureRandom()); + int keySize = export ? 512 : 1024; // default mode + if (!export) { + if (useLegacyEphemeralDHKeys) { // legacy mode + keySize = 768; + } else if (useSmartEphemeralDHKeys) { // matched mode + if (key != null) { + int ks = KeyUtil.getKeySize(key); + // Note that SunJCE provider only supports 2048 bits DH + // keys bigger than 1024. Please DON'T use value other + // than 1024 and 2048 at present. We may improve the + // underlying providers and key size here in the future. + // + // keySize = ks <= 1024 ? 1024 : (ks >= 2048 ? 2048 : ks); + keySize = ks <= 1024 ? 1024 : 2048; + } // Otherwise, anonymous cipher suites, 1024-bit is used. + } else if (customizedDHKeySize > 0) { // customized mode + keySize = customizedDHKeySize; + } + } + + dh = new DHCrypt(keySize, sslContext.getSecureRandom()); } // Setup the ephemeral ECDH parameters. diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java new file mode 100644 index 00000000000..3c61f76371f --- /dev/null +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java @@ -0,0 +1,477 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 6956398 + * @summary make ephemeral DH key match the length of the certificate key + * @run main/othervm + * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched + * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy + * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024 + * DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75 + * + * @run main/othervm + * DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 292 75 + * + * @run main/othervm + * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1510 139 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy + * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1414 107 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched + * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1894 267 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024 + * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1510 139 + * + * @run main/othervm + * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 484 139 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy + * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 388 107 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched + * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 484 139 + * @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024 + * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 484 139 + */ + +/* + * This is a simple hack to test key sizes of Diffie-Hellman key exchanging + * during SSL/TLS handshaking. + * + * The record length of DH ServerKeyExchange and ClientKeyExchange. + * ServerKeyExchange message are wrapped in ServerHello series messages, which + * contains ServerHello, Certificate and ServerKeyExchange message. + * + * struct { + * opaque dh_p<1..2^16-1>; + * opaque dh_g<1..2^16-1>; + * opaque dh_Ys<1..2^16-1>; + * } ServerDHParams; // Ephemeral DH parameters + * + * struct { + * select (PublicValueEncoding) { + * case implicit: struct { }; + * case explicit: opaque dh_Yc<1..2^16-1>; + * } dh_public; + * } ClientDiffieHellmanPublic; + * + * Fomr above structures, it is clear that if the DH key size increasing 128 + * bits (16 bytes), the ServerHello series messages increases 48 bytes + * (becuase dh_p, dh_g and dh_Ys each increase 16 bytes) and ClientKeyExchange + * increases 16 bytes (because of the size increasing of dh_Yc). + * + * Here is a summary of the record length in the test case. + * + * | ServerHello Series | ClientKeyExchange | ServerHello Anon + * 512-bit | 1318 bytes | 75 bytes | 292 bytes + * 768-bit | 1414 bytes | 107 bytes | 388 bytes + * 1024-bit | 1510 bytes | 139 bytes | 484 bytes + * 2048-bit | 1894 bytes | 267 bytes | 484 bytes + */ + +import javax.net.ssl.*; +import javax.net.ssl.SSLEngineResult.*; +import java.io.*; +import java.nio.*; +import java.security.KeyStore; +import java.security.KeyFactory; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.*; +import java.security.interfaces.*; +import java.util.Base64; + +public class DHEKeySizing { + + private static boolean debug = true; + + private SSLContext sslc; + private SSLEngine ssle1; // client + private SSLEngine ssle2; // server + + private ByteBuffer appOut1; // write side of ssle1 + private ByteBuffer appIn1; // read side of ssle1 + private ByteBuffer appOut2; // write side of ssle2 + private ByteBuffer appIn2; // read side of ssle2 + + private ByteBuffer oneToTwo; // "reliable" transport ssle1->ssle2 + private ByteBuffer twoToOne; // "reliable" transport ssle2->ssle1 + + /* + * Where do we find the keystores? + */ + // Certificates and key used in the test. + static String trustedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIIC8jCCAdqgAwIBAgIEUjkuRzANBgkqhkiG9w0BAQUFADA7MR0wGwYDVQQLExRT\n" + + "dW5KU1NFIFRlc3QgU2VyaXZjZTENMAsGA1UEChMESmF2YTELMAkGA1UEBhMCVVMw\n" + + "HhcNMTMwOTE4MDQzODMxWhcNMTMxMjE3MDQzODMxWjA7MR0wGwYDVQQLExRTdW5K\n" + + "U1NFIFRlc3QgU2VyaXZjZTENMAsGA1UEChMESmF2YTELMAkGA1UEBhMCVVMwggEi\n" + + "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCO+IGeaskJAvEcYc7pCl9neK3E\n" + + "a28fwWLtChufYNaC9hQfZlUdETWYjV7fZJVJKT/oLzdDNMWuVA0LKXArpI3thLNK\n" + + "QLXisdF9hKPlZRDazACL9kWUUtJ0FzpEySK4e8wW/z9FuU6e6iO19FbjxAfInJqk\n" + + "3EDiEhB5g73S2vtvPCxgq2DvWw9TDl/LIqdKG2JCS93koXCCaHmQ7MrIOqHPd+8r\n" + + "RbGpatXT9qyHKppUv9ATxVygO4rA794mgCFxpT+fkhz+NEB0twTkM65T1hnnOv5n\n" + + "ZIxkcjBggt85UlZtnP3b9P7SYxsWIa46Oc38Od2f3YejfVg6B+PqPgWNl3+/AgMB\n" + + "AAEwDQYJKoZIhvcNAQEFBQADggEBAAlrP6DFLRPSy0IgQhcI2i56tR/na8pezSte\n" + + "ZHcCdaCZPDy4UP8mpLJ9QCjEB5VJv8hPm4xdK7ULnKGOGHgYqDpV2ZHvQlhV1woQ\n" + + "TZGb/LM3c6kAs0j4j9KM2fq3iYUYexjIkS1KzsziflxMM6igS9BRMBR2LQyU+cYq\n" + + "YEsFzkF7Aj2ET4v/+tgot9mRr2NioJcaJkdsPDpMU3IKB1cczfu+OuLQ/GCG0Fqu\n" + + "6ijCeCqfnaAbemHbJeVZZ6Qgka3uC2YMntLBmLkhqEo1d9zGYLoh7oWL77y5ibQZ\n" + + "LK5/H/zikcu579TWjlDHcqL3arCwBcrtsjSaPrRSWMrWV/6c0qw=\n" + + "-----END CERTIFICATE-----"; + + // Private key in the format of PKCS#8 + static String targetPrivateKey = + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCO+IGeaskJAvEc\n" + + "Yc7pCl9neK3Ea28fwWLtChufYNaC9hQfZlUdETWYjV7fZJVJKT/oLzdDNMWuVA0L\n" + + "KXArpI3thLNKQLXisdF9hKPlZRDazACL9kWUUtJ0FzpEySK4e8wW/z9FuU6e6iO1\n" + + "9FbjxAfInJqk3EDiEhB5g73S2vtvPCxgq2DvWw9TDl/LIqdKG2JCS93koXCCaHmQ\n" + + "7MrIOqHPd+8rRbGpatXT9qyHKppUv9ATxVygO4rA794mgCFxpT+fkhz+NEB0twTk\n" + + "M65T1hnnOv5nZIxkcjBggt85UlZtnP3b9P7SYxsWIa46Oc38Od2f3YejfVg6B+Pq\n" + + "PgWNl3+/AgMBAAECggEAPdb5Ycc4m4A9QBSCRcRpzbyiFLKPh0HDg1n65q4hOtYr\n" + + "kAVYTVFTSF/lqGS+Ob3w2YIKujQKSUQrvCc5UHdFuHXMgxKIWbymK0+DAMb9SlYw\n" + + "6lkkcWp9gx9E4dnJ/df2SAAxovvrKMuHlL1SFASHhVtPfH2URvSfUaANLDXxyYOs\n" + + "8BX0Nr6wazhWjLjXo9yIGnKSvFfB8XisYcA78kEgas43zhmIGCDPqaYyyffOfRbx\n" + + "pM1KNwGmlN86iWR1CbwA/wwhcMySWQueS+s7cHbpRqZIYJF9jEeELiwi0vxjealS\n" + + "EMuHYedIRFMWaDIq9XyjrvXamHb0Z25jlXBNZHaM0QKBgQDE9adl+zAezR/n79vw\n" + + "0XiX2Fx1UEo3ApZHuoA2Q/PcBk+rlKqqQ3IwTcy6Wo648wK7v6Nq7w5nEWcsf0dU\n" + + "QA2Ng/AJEev/IfF34x7sKGYxtk1gcE0EuSBA3R+ocEZxnNw1Ryd5nUU24s8d4jCP\n" + + "Mkothnyaim+zE2raDlEtVc0CaQKBgQC509av+02Uq5oMjzbQp5PBJfQFjATOQT15\n" + + "eefYnVYurkQ1kcVfixkrO2ORhg4SjmI2Z5hJDgGtXdwgidpzkad+R2epS5qLMyno\n" + + "lQVpY6bMpEZ7Mos0yQygxnm8uNohEcTExOe+nP5fNJVpzBsGmfeyYOhnPQlf6oqf\n" + + "0cHizedb5wKBgQC/l5LyMil6HOGHlhzmIm3jj7VI7QR0hJC5T6N+phVml8ESUDjA\n" + + "DYHbmSKouISTRtkG14FY+RiSjCxH7bvuKazFV2289PETquogTA/9e8MFYqfcQwG4\n" + + "sXi9gBxWlnj/9a2EKiYtOB5nKLR/BlNkSHA93tAA6N+FXEMZwMmYhxk42QKBgAuY\n" + + "HQgD3PZOsqDf+qKQIhbmAFCsSMx5o5VFtuJ8BpmJA/Z3ruHkMuDQpsi4nX4o5hXQ\n" + + "5t6AAjjH52kcUMXvK40kdWJJtk3DFnVNfvXxYsHX6hHbuHXFqYUKfSP6QJnZmvZP\n" + + "9smcz/4usLfWJUWHK740b6upUkFqx9Vq5/b3s9y3AoGAdM5TW7LkkOFsdMGVAUzR\n" + + "9iXmCWElHTK2Pcp/3yqDBHSfiQx6Yp5ANyPnE9NBM0yauCfOyBB2oxLO4Rdv3Rqk\n" + + "9V9kyR/YAGr7dJaPcQ7pZX0OpkzgueAOJYPrx5VUzPYUtklYV1ycFZTfKlpFCxT+\n" + + "Ei6KUo0NXSdUIcB4yib1J10="; + + static char passphrase[] = "passphrase".toCharArray(); + + /* + * Majority of the test case is here, setup is done below. + */ + + private void createSSLEngines() throws Exception { + ssle1 = sslc.createSSLEngine("client", 1); + ssle1.setUseClientMode(true); + + ssle2 = sslc.createSSLEngine("server", 2); + ssle2.setUseClientMode(false); + } + + private boolean isHandshaking(SSLEngine e) { + return (e.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING); + } + + private void checkResult(ByteBuffer bbIn, ByteBuffer bbOut, + SSLEngineResult result, + Status status, HandshakeStatus hsStatus, + int consumed, int produced) + throws Exception { + + if ((status != null) && (result.getStatus() != status)) { + throw new Exception("Unexpected Status: need = " + status + + " got = " + result.getStatus()); + } + + if ((hsStatus != null) && (result.getHandshakeStatus() != hsStatus)) { + throw new Exception("Unexpected hsStatus: need = " + hsStatus + + " got = " + result.getHandshakeStatus()); + } + + if ((consumed != -1) && (consumed != result.bytesConsumed())) { + throw new Exception("Unexpected consumed: need = " + consumed + + " got = " + result.bytesConsumed()); + } + + if ((produced != -1) && (produced != result.bytesProduced())) { + throw new Exception("Unexpected produced: need = " + produced + + " got = " + result.bytesProduced()); + } + + if ((consumed != -1) && (bbIn.position() != result.bytesConsumed())) { + throw new Exception("Consumed " + bbIn.position() + + " != " + consumed); + } + + if ((produced != -1) && (bbOut.position() != result.bytesProduced())) { + throw new Exception("produced " + bbOut.position() + + " != " + produced); + } + } + + private void test(String cipherSuite, boolean exportable, + int lenServerKeyEx, int lenClientKeyEx) throws Exception { + + createSSLEngines(); + createBuffers(); + + SSLEngineResult result1; // ssle1's results from last operation + SSLEngineResult result2; // ssle2's results from last operation + + String[] suites = new String [] {cipherSuite}; + + ssle1.setEnabledCipherSuites(suites); + ssle2.setEnabledCipherSuites(suites); + + log("======================================"); + log("==================="); + log("client hello"); + result1 = ssle1.wrap(appOut1, oneToTwo); + checkResult(appOut1, oneToTwo, result1, + Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1); + oneToTwo.flip(); + + result2 = ssle2.unwrap(oneToTwo, appIn2); + checkResult(oneToTwo, appIn2, result2, + Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0); + runDelegatedTasks(ssle2); + oneToTwo.compact(); + + log("==================="); + log("ServerHello"); + result2 = ssle2.wrap(appOut2, twoToOne); + checkResult(appOut2, twoToOne, result2, + Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1); + twoToOne.flip(); + + log("Message length of ServerHello series: " + twoToOne.remaining()); + if (lenServerKeyEx != twoToOne.remaining()) { + throw new Exception( + "Expected to generate ServerHello series messages of " + + lenServerKeyEx + " bytes, but not " + twoToOne.remaining()); + } + + result1 = ssle1.unwrap(twoToOne, appIn1); + checkResult(twoToOne, appIn1, result1, + Status.OK, HandshakeStatus.NEED_TASK, result2.bytesProduced(), 0); + runDelegatedTasks(ssle1); + twoToOne.compact(); + + log("==================="); + log("Key Exchange"); + result1 = ssle1.wrap(appOut1, oneToTwo); + checkResult(appOut1, oneToTwo, result1, + Status.OK, HandshakeStatus.NEED_WRAP, 0, -1); + oneToTwo.flip(); + + log("Message length of ClientKeyExchange: " + oneToTwo.remaining()); + if (lenClientKeyEx != oneToTwo.remaining()) { + throw new Exception( + "Expected to generate ClientKeyExchange message of " + + lenClientKeyEx + " bytes, but not " + oneToTwo.remaining()); + } + result2 = ssle2.unwrap(oneToTwo, appIn2); + checkResult(oneToTwo, appIn2, result2, + Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0); + runDelegatedTasks(ssle2); + oneToTwo.compact(); + + log("==================="); + log("Client CCS"); + result1 = ssle1.wrap(appOut1, oneToTwo); + checkResult(appOut1, oneToTwo, result1, + Status.OK, HandshakeStatus.NEED_WRAP, 0, -1); + oneToTwo.flip(); + + result2 = ssle2.unwrap(oneToTwo, appIn2); + checkResult(oneToTwo, appIn2, result2, + Status.OK, HandshakeStatus.NEED_UNWRAP, + result1.bytesProduced(), 0); + oneToTwo.compact(); + + log("==================="); + log("Client Finished"); + result1 = ssle1.wrap(appOut1, oneToTwo); + checkResult(appOut1, oneToTwo, result1, + Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1); + oneToTwo.flip(); + + result2 = ssle2.unwrap(oneToTwo, appIn2); + checkResult(oneToTwo, appIn2, result2, + Status.OK, HandshakeStatus.NEED_WRAP, + result1.bytesProduced(), 0); + oneToTwo.compact(); + + log("==================="); + log("Server CCS"); + result2 = ssle2.wrap(appOut2, twoToOne); + checkResult(appOut2, twoToOne, result2, + Status.OK, HandshakeStatus.NEED_WRAP, 0, -1); + twoToOne.flip(); + + result1 = ssle1.unwrap(twoToOne, appIn1); + checkResult(twoToOne, appIn1, result1, + Status.OK, HandshakeStatus.NEED_UNWRAP, result2.bytesProduced(), 0); + twoToOne.compact(); + + log("==================="); + log("Server Finished"); + result2 = ssle2.wrap(appOut2, twoToOne); + checkResult(appOut2, twoToOne, result2, + Status.OK, HandshakeStatus.FINISHED, 0, -1); + twoToOne.flip(); + + result1 = ssle1.unwrap(twoToOne, appIn1); + checkResult(twoToOne, appIn1, result1, + Status.OK, HandshakeStatus.FINISHED, result2.bytesProduced(), 0); + twoToOne.compact(); + + log("==================="); + log("Check Session/Ciphers"); + String cs = ssle1.getSession().getCipherSuite(); + if (!cs.equals(suites[0])) { + throw new Exception("suites not equal: " + cs + "/" + suites[0]); + } + + cs = ssle2.getSession().getCipherSuite(); + if (!cs.equals(suites[0])) { + throw new Exception("suites not equal: " + cs + "/" + suites[0]); + } + + log("==================="); + log("Done with SSL/TLS handshaking"); + } + + public static void main(String args[]) throws Exception { + if (args.length != 4) { + System.out.println( + "Usage: java DHEKeySizing cipher-suite " + + "exportable(true|false)\n" + + " size-of-server-hello-record size-of-client-key-exchange"); + throw new Exception("Incorrect usage!"); + } + + (new DHEKeySizing()).test(args[0], + Boolean.parseBoolean(args[1]), + Integer.parseInt(args[2]), + Integer.parseInt(args[3])); + System.out.println("Test Passed."); + } + + /* + * ********************************************************** + * Majority of the test case is above, below is just setup stuff + * ********************************************************** + */ + + public DHEKeySizing() throws Exception { + sslc = getSSLContext(); + } + + /* + * Create an initialized SSLContext to use for this test. + */ + private SSLContext getSSLContext() throws Exception { + + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // create a key store + KeyStore ts = KeyStore.getInstance("JKS"); + KeyStore ks = KeyStore.getInstance("JKS"); + ts.load(null, null); + ks.load(null, null); + + // import the trused cert + ByteArrayInputStream is = + new ByteArrayInputStream(trustedCertStr.getBytes()); + Certificate trusedCert = cf.generateCertificate(is); + is.close(); + ts.setCertificateEntry("rsa-trusted-2048", trusedCert); + + // generate the private key. + String keySpecStr = targetPrivateKey; + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder().decode(keySpecStr)); + KeyFactory kf = KeyFactory.getInstance("RSA"); + RSAPrivateKey priKey = (RSAPrivateKey)kf.generatePrivate(priKeySpec); + + Certificate[] chain = new Certificate[1]; + chain[0] = trusedCert; + + // import the key entry. + ks.setKeyEntry("rsa-key-2048", priKey, passphrase, chain); + + // create SSL context + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance("TLS"); + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + return sslCtx; + } + + private void createBuffers() { + // Size the buffers as appropriate. + + SSLSession session = ssle1.getSession(); + int appBufferMax = session.getApplicationBufferSize(); + int netBufferMax = session.getPacketBufferSize(); + + appIn1 = ByteBuffer.allocateDirect(appBufferMax + 50); + appIn2 = ByteBuffer.allocateDirect(appBufferMax + 50); + + oneToTwo = ByteBuffer.allocateDirect(netBufferMax); + twoToOne = ByteBuffer.allocateDirect(netBufferMax); + + appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes()); + appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes()); + + log("AppOut1 = " + appOut1); + log("AppOut2 = " + appOut2); + log(""); + } + + private static void runDelegatedTasks(SSLEngine engine) throws Exception { + + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + log("running delegated task..."); + runnable.run(); + } + } + + private static void log(String str) { + if (debug) { + System.out.println(str); + } + } +} From 5bc35911d01635a0e6b8cf76731b4f29bccc4ea8 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Tue, 8 Oct 2013 11:17:15 +0200 Subject: [PATCH 288/293] 8025136: SplittableRandom enchancements Co-authored-by: Guy Steele Reviewed-by: psandoz, martin --- jdk/src/share/classes/java/util/Random.java | 2 +- .../classes/java/util/SplittableRandom.java | 99 +++++++++---------- .../util/concurrent/ThreadLocalRandom.java | 4 +- 3 files changed, 51 insertions(+), 54 deletions(-) diff --git a/jdk/src/share/classes/java/util/Random.java b/jdk/src/share/classes/java/util/Random.java index 2c0e0135c72..2095c437168 100644 --- a/jdk/src/share/classes/java/util/Random.java +++ b/jdk/src/share/classes/java/util/Random.java @@ -89,7 +89,7 @@ class Random implements java.io.Serializable { private static final long addend = 0xBL; private static final long mask = (1L << 48) - 1; - private static final double DOUBLE_UNIT = 1.0 / (1L << 53); + private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) // IllegalArgumentException messages static final String BadBound = "bound must be positive"; diff --git a/jdk/src/share/classes/java/util/SplittableRandom.java b/jdk/src/share/classes/java/util/SplittableRandom.java index c3f5c0b4234..00de113a6f8 100644 --- a/jdk/src/share/classes/java/util/SplittableRandom.java +++ b/jdk/src/share/classes/java/util/SplittableRandom.java @@ -107,29 +107,25 @@ public final class SplittableRandom { * Methods nextLong, nextInt, and derivatives do not return the * sequence (seed) values, but instead a hash-like bit-mix of * their bits, producing more independently distributed sequences. - * For nextLong, the mix64 bit-mixing function computes the same - * value as the "64-bit finalizer" function in Austin Appleby's - * MurmurHash3 algorithm. See - * http://code.google.com/p/smhasher/wiki/MurmurHash3 , which - * comments: "The constants for the finalizers were generated by a - * simple simulated-annealing algorithm, and both avalanche all - * bits of 'h' to within 0.25% bias." The mix32 function is - * equivalent to (int)(mix64(seed) >>> 32), but faster because it - * omits a step that doesn't contribute to result. + * For nextLong, the mix64 function is based on David Stafford's + * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html) + * "Mix13" variant of the "64-bit finalizer" function in Austin + * Appleby's MurmurHash3 algorithm (see + * http://code.google.com/p/smhasher/wiki/MurmurHash3). The mix32 + * function is based on Stafford's Mix04 mix function, but returns + * the upper 32 bits cast as int. * * The split operation uses the current generator to form the seed * and gamma for another SplittableRandom. To conservatively * avoid potential correlations between seed and value generation, - * gamma selection (method nextGamma) uses the "Mix13" constants - * for MurmurHash3 described by David Stafford - * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html) - * To avoid potential weaknesses in bit-mixing transformations, we - * restrict gammas to odd values with at least 12 and no more than - * 52 bits set. Rather than rejecting candidates with too few or - * too many bits set, method nextGamma flips some bits (which has - * the effect of mapping at most 4 to any given gamma value). - * This reduces the effective set of 64bit odd gamma values by - * about 214, a very tiny percentage, and serves as an + * gamma selection (method mixGamma) uses different + * (Murmurhash3's) mix constants. To avoid potential weaknesses + * in bit-mixing transformations, we restrict gammas to odd values + * with at least 24 0-1 or 1-0 bit transitions. Rather than + * rejecting candidates with too few or too many bits set, method + * mixGamma flips some bits (which has the effect of mapping at + * most 4 to any given gamma value). This reduces the effective + * set of 64bit odd gamma values by about 2%, and serves as an * automated screening for sequence constant selection that is * left as an empirical decision in some other hashing and crypto * algorithms. @@ -140,14 +136,15 @@ public final class SplittableRandom { * avalanching. * * The default (no-argument) constructor, in essence, invokes - * split() for a common "seeder" SplittableRandom. Unlike other - * cases, this split must be performed in a thread-safe manner, so - * we use an AtomicLong to represent the seed rather than use an - * explicit SplittableRandom. To bootstrap the seeder, we start - * off using a seed based on current time and host unless the - * java.util.secureRandomSeed property is set. This serves as a - * slimmed-down (and insecure) variant of SecureRandom that also - * avoids stalls that may occur when using /dev/random. + * split() for a common "defaultGen" SplittableRandom. Unlike + * other cases, this split must be performed in a thread-safe + * manner, so we use an AtomicLong to represent the seed rather + * than use an explicit SplittableRandom. To bootstrap the + * defaultGen, we start off using a seed based on current time and + * network interface address unless the java.util.secureRandomSeed + * property is set. This serves as a slimmed-down (and insecure) + * variant of SecureRandom that also avoids stalls that may occur + * when using /dev/random. * * It is a relatively simple matter to apply the basic design here * to use 128 bit seeds. However, emulating 128bit arithmetic and @@ -160,17 +157,16 @@ public final class SplittableRandom { */ /** - * The initial gamma value for (unsplit) SplittableRandoms. Must - * be odd with at least 12 and no more than 52 bits set. Currently - * set to the golden ratio scaled to 64bits. + * The golden ratio scaled to 64bits, used as the initial gamma + * value for (unsplit) SplittableRandoms. */ - private static final long INITIAL_GAMMA = 0x9e3779b97f4a7c15L; + private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L; /** * The least non-zero value returned by nextDouble(). This value * is scaled by a random value of 53 bits to produce a result. */ - private static final double DOUBLE_UNIT = 1.0 / (1L << 53); + private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53); /** * The seed. Updated only via method nextSeed. @@ -191,31 +187,31 @@ public final class SplittableRandom { } /** - * Computes MurmurHash3 64bit mix function. + * Computes Stafford variant 13 of 64bit mix function. */ private static long mix64(long z) { - z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; - z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L; - return z ^ (z >>> 33); + z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; + z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL; + return z ^ (z >>> 31); } /** - * Returns the 32 high bits of mix64(z) as int. + * Returns the 32 high bits of Stafford variant 4 mix64 function as int. */ private static int mix32(long z) { - z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; - return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32); + z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L; + return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32); } /** * Returns the gamma value to use for a new split instance. */ - private static long nextGamma(long z) { - z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; // Stafford "Mix13" - z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL; - z = (z ^ (z >>> 31)) | 1L; // force to be odd - int n = Long.bitCount(z); // ensure enough 0 and 1 bits - return (n < 12 || n > 52) ? z ^ 0xaaaaaaaaaaaaaaaaL : z; + private static long mixGamma(long z) { + z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix constants + z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L; + z = (z ^ (z >>> 33)) | 1L; // force to be odd + int n = Long.bitCount(z ^ (z >>> 1)); // ensure enough transitions + return (n < 24) ? z ^ 0xaaaaaaaaaaaaaaaaL : z; } /** @@ -228,7 +224,7 @@ public final class SplittableRandom { /** * The seed generator for default constructors. */ - private static final AtomicLong seeder = new AtomicLong(initialSeed()); + private static final AtomicLong defaultGen = new AtomicLong(initialSeed()); private static long initialSeed() { String pp = java.security.AccessController.doPrivileged( @@ -396,7 +392,7 @@ public final class SplittableRandom { * @param seed the initial seed */ public SplittableRandom(long seed) { - this(seed, INITIAL_GAMMA); + this(seed, GOLDEN_GAMMA); } /** @@ -405,8 +401,10 @@ public final class SplittableRandom { * of those of any other instances in the current program; and * may, and typically does, vary across program invocations. */ - public SplittableRandom() { // emulate seeder.split() - this.gamma = nextGamma(this.seed = seeder.addAndGet(INITIAL_GAMMA)); + public SplittableRandom() { // emulate defaultGen.split() + long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA); + this.seed = mix64(s); + this.gamma = mixGamma(s + GOLDEN_GAMMA); } /** @@ -424,8 +422,7 @@ public final class SplittableRandom { * @return the new SplittableRandom instance */ public SplittableRandom split() { - long s = nextSeed(); - return new SplittableRandom(s, nextGamma(s)); + return new SplittableRandom(nextLong(), mixGamma(nextSeed())); } /** diff --git a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java index 2cd2b0094bf..2606bed44be 100644 --- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -194,8 +194,8 @@ public class ThreadLocalRandom extends Random { private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL; // Constants from SplittableRandom - private static final double DOUBLE_UNIT = 1.0 / (1L << 53); - private static final float FLOAT_UNIT = 1.0f / (1 << 24); + private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) + private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24) /** Rarely-used holder for the second of a pair of Gaussians */ private static final ThreadLocal nextLocalGaussian = From 31fdd1b27caffd81e5d58f7d9f37e37508ca4243 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Tue, 8 Oct 2013 10:49:09 +0100 Subject: [PATCH 289/293] 8024788: (fs) Files.readAllBytes uses FileChannel which may not be supported by all providers Reviewed-by: chegar --- jdk/src/share/classes/java/nio/file/Files.java | 8 ++++---- jdk/test/java/nio/file/Files/BytesAndLines.java | 14 +++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index 174e390a665..01629442af4 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -3082,13 +3082,13 @@ public final class Files { * method is invoked to check read access to the file. */ public static byte[] readAllBytes(Path path) throws IOException { - try (FileChannel fc = FileChannel.open(path); - InputStream is = Channels.newInputStream(fc)) { - long size = fc.size(); + try (SeekableByteChannel sbc = Files.newByteChannel(path); + InputStream in = Channels.newInputStream(sbc)) { + long size = sbc.size(); if (size > (long)MAX_BUFFER_SIZE) throw new OutOfMemoryError("Required array size too large"); - return read(is, (int)size); + return read(in, (int)size); } } diff --git a/jdk/test/java/nio/file/Files/BytesAndLines.java b/jdk/test/java/nio/file/Files/BytesAndLines.java index 15fb6a4251b..6c36c121afe 100644 --- a/jdk/test/java/nio/file/Files/BytesAndLines.java +++ b/jdk/test/java/nio/file/Files/BytesAndLines.java @@ -22,7 +22,9 @@ */ /* @test - * @bug 7006126 8020669 + * @bug 7006126 8020669 8024788 + * @build BytesAndLines PassThroughFileSystem + * @run main BytesAndLines * @summary Unit test for methods for Files readAllBytes, readAllLines and * and write methods. */ @@ -92,6 +94,16 @@ public class BytesAndLines { byte[] data = Files.readAllBytes(pathStat); assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read"); } + + // test readAllBytes on custom file system + Path myfile = PassThroughFileSystem.create().getPath(file.toString()); + for (int size=0; size<=1024; size+=512) { + byte[] b1 = new byte[size]; + rand.nextBytes(b1); + Files.write(myfile, b1); + byte[] b2 = Files.readAllBytes(myfile); + assertTrue(Arrays.equals(b1, b2), "bytes not equal"); + } } From 37283c9847217f6606b916faee02d733e3ea9f2b Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 19:12:21 +0200 Subject: [PATCH 290/293] Added tag jdk8-b108 for changeset 74049f7a28b4 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 2fc464b6481..a3f78b33edc 100644 --- a/.hgtags +++ b/.hgtags @@ -229,3 +229,4 @@ b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104 589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105 514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106 892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107 +74049f7a28b48c14910106a75d9f2504169c352e jdk8-b108 From a398cd02750a60fd975f31db4df3296d33a7c80a Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 19:13:10 +0200 Subject: [PATCH 291/293] Added tag jdk8-b109 for changeset af9a674e12a1 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index a3f78b33edc..f5f0bdfd1da 100644 --- a/.hgtags +++ b/.hgtags @@ -230,3 +230,4 @@ b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104 514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106 892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107 74049f7a28b48c14910106a75d9f2504169c352e jdk8-b108 +af9a674e12a16da1a4bd53e4990ddb1121a21ef1 jdk8-b109 From f84ac5de52d79ef956878b1ee10e98285b310634 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 19:14:20 +0200 Subject: [PATCH 292/293] Added tag jdk8-b110 for changeset b5d2bf482a3e --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index f5f0bdfd1da..563322098f3 100644 --- a/.hgtags +++ b/.hgtags @@ -231,3 +231,4 @@ b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104 892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107 74049f7a28b48c14910106a75d9f2504169c352e jdk8-b108 af9a674e12a16da1a4bd53e4990ddb1121a21ef1 jdk8-b109 +b5d2bf482a3ea1cca08c994512804ffbc73de0a1 jdk8-b110 From 5d6172225c0e2c31c18d653e6151fe2d9b74b130 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 10 Oct 2013 10:09:19 -0700 Subject: [PATCH 293/293] Added tag jdk8-b111 for changeset ff73e351b200 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index cdae1de11aa..3a38f345100 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -232,3 +232,4 @@ eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 006aaa5f069e7dd98fccdc696866c9f8582c087c jdk8-b108 946f3fd5f8bf0ccd180c258d25e5837fa1bf004c jdk8-b109 54e099776f08430d3a7f4feabd9f2ba886b55320 jdk8-b110 +719befd87c7b96ae103c05730ca555227bfc0116 jdk8-b111

    lookup expressionmemberbehavior
    lookup expressionmemberbytecode behavior
    {@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}{@code FT f;}{@code (T) this.f;}